Changeset 533
- Timestamp:
- 06/06/08 15:35:02 (3 months ago)
- Files:
-
- trunk/thune/boot.c (modified) (3 diffs)
- trunk/thune/console.c (modified) (3 diffs)
- trunk/thune/doc/UserManual (modified) (4 diffs)
- trunk/thune/eval.c (modified) (2 diffs)
- trunk/thune/gl/TexFont.c (modified) (18 diffs)
- trunk/thune/gl/TexFont.h (modified) (3 diffs)
- trunk/thune/gl/boot.c (modified) (1 diff)
- trunk/thune/gl/draw_list.c (modified) (8 diffs)
- trunk/thune/gl/gllist.c (modified) (2 diffs)
- trunk/thune/gl/gui.c (modified) (16 diffs)
- trunk/thune/gl/gui.h (modified) (4 diffs)
- trunk/thune/gl/gx.c (modified) (6 diffs)
- trunk/thune/gl/gx.h (modified) (2 diffs)
- trunk/thune/gl/gx.t (modified) (1 diff)
- trunk/thune/gl/gx_dt.c (modified) (1 diff)
- trunk/thune/gl/rfont.c (modified) (2 diffs)
- trunk/thune/gl/scripts/gui.t (modified) (2 diffs)
- trunk/thune/gl/widgets/buttonw.c (added)
- trunk/thune/gl/widgets/labelw.c (added)
- trunk/thune/gl/widgets/twidget.c (modified) (2 diffs)
- trunk/thune/mkboot.t (modified) (1 diff)
- trunk/thune/tests/working/control.good (modified) (1 diff)
- trunk/thune/tests/working/control.t (modified) (1 diff)
- trunk/thune/tests/working/helpers.good (modified) (1 diff)
- trunk/thune/tests/working/helpers.t (modified) (1 diff)
- trunk/thune/thune.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/thune/boot.c
r527 r533 81 81 " ser [dup first comb do 1 poke drop] iter\n" 82 82 "] 'loop func :map ;(ser comb -- )\n" 83 "[[do if-some return] each false] proc :any ; (blk -- logic)\n" 84 "[[do dup iff return drop] each true] proc :all ; (blk -- logic)\n" 83 85 "[ser old new | len] [\n" 84 86 " old length? :len\n" … … 89 91 "[reduce [first to-text console.out] iter] proc :prin.pack ;(val -- )\n" 90 92 "[reduce to-text console.out eol console.out] proc :print ;(val -- )\n" 91 "[dup .] proc :.t\n"92 93 "[error! swap make throw] proc :error\n" 93 94 "[swap context bind proc] proc :proc.env ;(env body -- proc)\n" … … 105 106 "proc :parse.some ;(data rules -- )\n" 106 107 "[\n" 107 " 0,0, 4:version\n"108 " 0,0,5 :version\n" 108 109 " none :os\n" 109 110 " [] :devices\n" trunk/thune/console.c
r518 r533 56 56 " -h Show this help and exit\n" 57 57 ); 58 } 59 60 61 int quitResult( UThread* ut ) 62 { 63 UCell* val = ur_result( ut, 0 ); 64 return ur_sel(val); 58 65 } 59 66 … … 210 217 goto prompt; 211 218 219 case UR_EVAL_QUIT: 220 ret = quitResult( ut ); 221 goto quit; 222 212 223 case UR_EVAL_ERROR: 213 224 reportError( ut ); … … 282 293 283 294 case UR_EVAL_QUIT: 295 ret = quitResult( ut ); 284 296 goto quit; 285 297 trunk/thune/doc/UserManual
r512 r533 337 337 =========== ================= ============================ 338 338 . (val -- ) Remove value on top of stack and print it. 339 .t (val -- val) Show top value of stack. 339 340 .s () Show values on stack. 340 341 dup (a -- a a) Duplicate value on top of stack. … … 347 348 rot (a b c -- b c a) Rotate third value to top. 348 349 rot.r (a b c -- c a b) Rotate top of stack to third position. 349 stack .level ( -- level) Returns depth of data stack.350 stack-level ( -- level) Returns depth of data stack. 350 351 =========== ================= ============================ 351 352 … … 393 394 verify (a type -- a) Throw error if datatype does not match. 394 395 verify/N (a1-aN t1-tN -- a1-aN) Throw error if datatypes do not match. 395 quit () Quit program396 quit/N ( -- quit/N) Quit program. Exit status is optional. 396 397 ======== ========================= ============================ 397 398 … … 409 410 func.env (env sig body -- func) Create function with private context. 410 411 q () Quit 412 any (block -- logic) True if any block values are true. 413 all (block -- logic) True if all block values are true. 411 414 ======== ========================= ============================ 412 415 trunk/thune/eval.c
r527 r533 943 943 _probe( ut, tos ); 944 944 UR_S_SAFE_DROP; 945 } 946 947 948 UR_CALL( uc_printTOS ) 949 { 950 _probe( ut, tos ); 945 951 } 946 952 … … 1812 1818 #endif 1813 1819 { uc_showTOS, "." }, 1814 { uc_stack_level, "stack.level" }, 1820 { uc_printTOS, ".t" }, 1821 { uc_stack_level, "stack-level" }, 1815 1822 { uc_lift_local, "lift-local" }, 1816 1823 //{ uc_enclose, "enclose" }, trunk/thune/gl/TexFont.c
r527 r533 19 19 #include <string.h> 20 20 #include "TexFont.h" 21 #include <ft2build.h> 22 #include FT_FREETYPE_H 21 23 22 24 … … 25 27 #define FT_PIXELS(x) (x >> 6) 26 28 27 #define GLYPHS(tf) ((Tex GlyphInfo*) (tf + 1))29 #define GLYPHS(tf) ((TexFontGlyph*) (tf + 1)) 28 30 #define TABLE(tf) (((uint16_t*) tf) + tf->table_offset) 29 31 #define KERN(tf) (((int16_t*) tf) + tf->kern_offset) … … 34 36 35 37 /** 36 Returns the Tex GlyphInfofor a glyph or zero if it is not available.38 Returns the TexFontGlyph for a glyph or zero if it is not available. 37 39 Automatically substitutes uppercase letters with lowercase if 38 40 uppercase not available (and vice versa). 39 41 */ 40 Tex GlyphInfo* txf_glyph( const TexFont* tf, int c )42 TexFontGlyph* txf_glyph( const TexFont* tf, int c ) 41 43 { 42 44 uint16_t n; … … 68 70 69 71 70 int txf_kerning( const TexFont* tf, const Tex GlyphInfo* left,71 const Tex GlyphInfo* right )72 int txf_kerning( const TexFont* tf, const TexFontGlyph* left, 73 const TexFontGlyph* right ) 72 74 { 73 75 const int16_t* table; … … 109 111 if( tf && (tf->glyph_offset == (sizeof(TexFont) << 8)) ) 110 112 { 111 Tex GlyphInfo* tgi;112 Tex GlyphInfo* end;113 TexFontGlyph* tgi; 114 TexFontGlyph* end; 113 115 uint16_t* it; 114 116 … … 160 162 161 163 162 static void blitGlyphToBitmap( FT_Bitmap* src, FT_Bitmap* dst, int x, int y )164 static void blitGlyphToBitmap( FT_Bitmap* src, TexFontImage* dst, int x, int y ) 163 165 { 164 166 unsigned char* s; … … 168 170 169 171 s = src->buffer; 170 d = dst-> buffer+ (y * dst->pitch) + x;171 dend = dst-> buffer + (dst->rows* dst->pitch);172 d = dst->pixels + (y * dst->pitch) + x; 173 dend = dst->pixels + (dst->height * dst->pitch); 172 174 173 175 r = src->rows; … … 182 184 183 185 184 static FT_Error _renderGlyph( FT_Bitmap* img, FT_GlyphSlot glyph,186 static FT_Error _renderGlyph( TexFontImage* img, FT_GlyphSlot glyph, 185 187 int x_offset, int y_offset, int antialias ) 186 188 { … … 278 280 */ 279 281 TexFont* txf_build( const char* file, const char* codes, 280 FT_Bitmap* img, int psize, int gap, int antialias )282 TexFontImage* img, int psize, int gap, int antialias ) 281 283 { 282 284 FT_Library library; … … 295 297 const char* ci; 296 298 uint16_t* table; 297 Tex GlyphInfo* tgi;299 TexFontGlyph* tgi; 298 300 TexFont* txf = 0; 299 301 int count; … … 353 355 354 356 txf = (TexFont*) malloc( sizeof(TexFont) + 355 (sizeof(Tex GlyphInfo) * count) +357 (sizeof(TexFontGlyph) * count) + 356 358 (sizeof(uint16_t) * (gmax - gmin + 1)) + 357 359 (sizeof(int16_t) * kern_space) ); … … 359 361 txf->glyph_offset = sizeof(TexFont); 360 362 txf->glyph_count = count; 361 txf->table_offset = (txf->glyph_offset + (sizeof(Tex GlyphInfo) * count))363 txf->table_offset = (txf->glyph_offset + (sizeof(TexFontGlyph) * count)) 362 364 / sizeof(uint16_t); 363 365 txf->table_size = gmax - gmin + 1; … … 371 373 txf->min_glyph = gmin; 372 374 txf->tex_width = img->pitch; 373 txf->tex_height = img-> rows;375 txf->tex_height = img->height; 374 376 375 377 table = TABLE(txf); … … 378 380 379 381 // Clear bitmap. 380 memset( img-> buffer, 0, img->rows* img->pitch );382 memset( img->pixels, 0, img->height * img->pitch ); 381 383 382 384 … … 417 419 418 420 //if( (y + step_y) >= img->rows ) 419 if( y >= img-> rows)421 if( y >= img->height ) 420 422 { 421 423 fprintf( stderr, "txf_build: Texture too small\n" ); … … 435 437 tgi->advance = FT_PIXELS(glyph->metrics.horiAdvance); 436 438 tgi->x = x /*+ tgi->xoffset*/; 437 tgi->y = img-> rows- y + tgi->yoffset;439 tgi->y = img->height - y + tgi->yoffset; 438 440 439 441 #ifdef DUMP … … 483 485 int txf_width( const TexFont* tf, const char* it, const char* end ) 484 486 { 485 Tex GlyphInfo* prev = 0;486 Tex GlyphInfo* tgi;487 TexFontGlyph* prev = 0; 488 TexFontGlyph* tgi; 487 489 int width = 0; 488 490 … … 516 518 517 519 518 int txf_line spacing( const TexFont* tf )520 int txf_lineSpacing( const TexFont* tf ) 519 521 { 520 522 return tf->max_ascent + (tf->max_ascent / 2); trunk/thune/gl/TexFont.h
r527 r533 4 4 5 5 #include <stdint.h> 6 #include <ft2build.h> 7 #include FT_FREETYPE_H 6 7 8 typedef struct 9 { 10 void* pixels; 11 uint16_t width; 12 uint16_t height; 13 uint16_t pitch; 14 } 15 TexFontImage; 8 16 9 17 … … 21 29 int8_t _pad; 22 30 } 23 Tex GlyphInfo;31 TexFontGlyph; 24 32 25 33 26 34 typedef struct 27 35 { 28 uint16_t glyph_offset; // Array of Tex GlyphInfo.36 uint16_t glyph_offset; // Array of TexFontGlyph. 29 37 uint16_t glyph_count; 30 38 uint16_t table_offset; // Lookup table; array of uint16_t. … … 47 55 48 56 extern TexFont* txf_build( const char* file, const char* codes, 49 FT_Bitmap* img, int psize, int gap, int antialias ); 50 extern TexGlyphInfo* txf_glyph( const TexFont*, int c ); 51 extern int txf_kerning( const TexFont*, const TexGlyphInfo* left, 52 const TexGlyphInfo* right ); 57 TexFontImage* img, int psize, 58 int gap, int antialias ); 59 extern TexFontGlyph* txf_glyph( const TexFont*, int c ); 60 extern int txf_kerning( const TexFont*, const TexFontGlyph* left, 61 const TexFontGlyph* right ); 53 62 extern void txf_swap( TexFont* ); 54 63 extern int txf_width( const TexFont*, const char* it, const char* end ); 55 extern int txf_line spacing( const TexFont* );64 extern int txf_lineSpacing( const TexFont* ); 56 65 57 66 #ifdef __cplusplus trunk/thune/gl/boot.c
r527 r533 35 35 " none :button-down\n" 36 36 " none :button-hover\n" 37 " none :label-dl\n" 37 38 "]\n" 38 39 "context dup :gui-style-proto :gui-style\n" trunk/thune/gl/draw_list.c
r527 r533 27 27 #include "math3d.h" 28 28 #include "shader.h" 29 #include "TexFont.h"30 29 31 30 … … 240 239 241 240 /* 242 Returns Tex GlyphInfoof rendered glyph.241 Returns TexFontGlyph of rendered glyph. 243 242 Advances x. 244 243 */ 245 static Tex GlyphInfo* renderGlyphXY( const TexFont* txf, int c,244 static TexFontGlyph* renderGlyphXY( const TexFont* txf, int c, 246 245 GLfloat* xp, GLfloat y, 247 const Tex GlyphInfo* leftGI )246 const TexFontGlyph* leftGI ) 248 247 { 249 248 GLfloat w, h; … … 252 251 GLfloat min_s, max_s; 253 252 GLfloat min_t, max_t; 254 Tex GlyphInfo* tgi;253 TexFontGlyph* tgi; 255 254 int xkern; 256 255 … … 289 288 static GLfloat advanceGlyph( TexFont* txf, int c ) 290 289 { 291 Tex GlyphInfo* tgi = txf_glyph( txf, c );290 TexFontGlyph* tgi = txf_glyph( txf, c ); 292 291 if( tgi ) 293 292 return (GLfloat) tgi->advance; … … 303 302 { 304 303 GLfloat x, y; 305 Tex GlyphInfo* prev = 0;304 TexFontGlyph* prev = 0; 306 305 307 306 if( (it != end) ) … … 342 341 343 342 344 void gr_drawTextCell( UThread* ut, UCell* cell, UAtom sel, UCell* area )345 { 346 TexFont* tf; 343 void gr_drawTextCell( UThread* ut, TexFont* tf, UCell* cell, UAtom sel, 344 UCell* area ) 345 { 347 346 char* cpA; 348 347 char* cpB; 349 348 350 if( ! grState.fontN )351 return;352 tf = (TexFont*) ur_binPtr(grState.fontN)->ptr.v;353 349 354 350 if( ! ur_stringSlice( ut, cell, &cpA, &cpB ) ) … … 1100 1096 1101 1097 #ifdef DEBUG 1098 #include <stdio.h> 1102 1099 #define PRINT_STATE(txt,f,e) \ 1103 1100 s = glIsEnabled( e ); \ … … 1668 1665 } 1669 1666 1670 gr_drawTextCell( ut, val, sel, area ); 1667 if( grState.fontN ) 1668 { 1669 gr_drawTextCell( ut, 1670 (TexFont*) ur_binPtr(grState.fontN)->ptr.v, 1671 val, sel, area ); 1672 } 1671 1673 } 1672 1674 break; trunk/thune/gl/gllist.c
r458 r533 1 1 /*============================================================================ 2 2 Thune Interpreter 3 Copyright (C) 2005-200 7Karl Robillard3 Copyright (C) 2005-2008 Karl Robillard 4 4 5 5 This library is free software; you can redistribute it and/or … … 121 121 { 122 122 // Compile empty list to reduce memory usage. 123 // Well, hopefully that is what OpenGL will do... 123 124 glNewList( listBase + i, GL_COMPILE ); 124 125 glEndList(); trunk/thune/gl/gui.c
r528 r533 42 42 #include <GL/glv_keys.h> 43 43 #include "gx.h" 44 #include "gx_atoms.h" 44 45 #include "gui.h" 45 46 #include "os.h" 46 #include "TexFont.h"47 47 #include "gllist.h" 48 48 … … 88 88 ms.x = ex; \ 89 89 ms.y = ey 90 91 92 #define SET_AREA(wp,rect) \93 wp->x = rect->x; \94 wp->y = rect->y; \95 wp->w = rect->w; \96 wp->h = rect->h97 98 #define AREA_CHANGED(wp,rect) \99 ((wp->x != rect->x) || (wp->y != rect->y) || \100 (wp->w != rect->w) || (wp->h != rect->h))101 90 102 91 … … 123 112 CI_STYLE_BUTTON_UP, // Draw list 124 113 CI_STYLE_BUTTON_DOWN, // Draw list 125 CI_STYLE_BUTTON_HOVER // Draw list 114 CI_STYLE_BUTTON_HOVER, // Draw list 115 CI_STYLE_LABEL_DL // Draw list 126 116 }; 127 117 … … 159 149 160 150 161 // styleCell() may only be used by sizeHint, layout, & render methods.162 #define styleCell(index) (ui->style + index)163 164 165 151 static UCell* setStyleCells( GUI* ui ) 166 152 { … … 176 162 } 177 163 return 0; 178 }179 180 181 #define no_mark 0182 #define no_render 0183 184 185 static void no_event( GUI* ui, GWidget* wp, const GLViewEvent* ev )186 {187 (void) ui;188 (void) wp;189 (void) ev;190 }191 192 193 static void no_layout( GUI* ui, GWidget* wp, GRect* rect )194 {195 (void) ui;196 SET_AREA( wp, rect );197 }198 199 200 static GWidget* base_parse( GUI* ui, GMakeState* ms, int classId )201 {202 GWidget* wp;203 GUI_PARSE_ALLOC( wp )204 ++ms->it;205 return wp;206 164 } 207 165 … … 224 182 Set cell to coord! holding widget area. 225 183 */ 226 void gui_initRectCoord( UCell* cell, GWidget* w, int len)184 static void gui_initRectCoord( UCell* cell, GWidget* w, UAtom what ) 227 185 { 228 186 ur_initType(cell, UT_COORD); 229 cell->coord.len = len; 230 cell->coord.elem[ 0 ] = w->x; 231 cell->coord.elem[ 1 ] = w->y; 232 if( len > 2 ) 233 { 187 if( what == UR_ATOM_SIZE ) 188 { 189 cell->coord.len = 2; 190 cell->coord.elem[0] = w->w; 191 cell->coord.elem[1] = w->h; 192 } 193 else if( what == UR_ATOM_POS ) 194 { 195 cell->coord.len = 2; 196 cell->coord.elem[0] = w->x; 197 cell->coord.elem[1] = w->y; 198 } 199 else 200 { 201 cell->coord.len = 4; 202 cell->coord.elem[ 0 ] = w->x; 203 cell->coord.elem[ 1 ] = w->y; 234 204 cell->coord.elem[ 2 ] = w->w; 235 205 cell->coord.elem[ 3 ] = w->h; 236 206 } 207 } 208 209 210 //---------------------------------------------------------------------------- 211 212 213 #define no_mark 0 214 #define no_render 0 215 216 217 static void no_event( GUI* ui, GWidget* wp, const GLViewEvent* ev ) 218 { 219 (void) ui; 220 (void) wp; 221 (void) ev; 222 } 223 224 225 static void base_layout( GUI* ui, GWidget* wp, GRect* rect ) 226 { 227 (void) ui; 228 gui_setArea( wp, rect ); 229 } 230 231 232 static int base_select( GUI* ui, GWidget* wp, UAtom atom, UCell* result ) 233 { 234 (void) ui; 235 switch( atom ) 236 { 237 case UR_ATOM_RECT: 238 case UR_ATOM_SIZE: 239 case UR_ATOM_POS: 240 gui_initRectCoord( result, wp, atom ); 241 return 1; 242 } 243 return 0; 244 } 245 246 247 static GWidget* base_parse( GUI* ui, GMakeState* ms, int classId ) 248 { 249 GWidget* wp; 250 GUI_PARSE_ALLOC( wp ) 251 ++ms->it; 252 return wp; 237 253 } 238 254 … … 542 558 } 543 559 544 SET_AREA( wp, rect );560 gui_setArea( wp, rect ); 545 561 546 562 dim = wp->x + wd->marginL; … … 665 681 } 666 682 667 SET_AREA( wp, rect );668 669 dim = wp->y + w d->marginB;683 gui_setArea( wp, rect ); 684 685 dim = wp->y + wp->h - wd->marginT; 670 686 room = wp->w - wd->marginL - wd->marginR; 671 687 hint = lo.hint; 672 688 EACH_SHOWN_CHILD( wp, it ) 673 689 cr.x = wp->x + wd->marginL; 674 cr.y = dim;675 690 cr.w = MIN( hint->maxW, room ); 676 691 cr.h = hint->minH; 677 678 dim += cr.h + wd->spacing; 692 cr.y = dim - cr.h; 693 694 dim -= cr.h + wd->spacing; 679 695 680 696 #ifdef REPORT_LAYOUT … … 755 771 UCell* rc; 756 772 BoxData* wd = BOX_DATA(wp); 757 int changed = AREA_CHANGED( wp, rect );758 759 rc = styleCell( CI_STYLE_WINDOW_MARGIN );773 int changed = gui_areaChanged( wp, rect ); 774 775 rc = gui_styleCell( CI_STYLE_WINDOW_MARGIN ); 760 776 if( ur_is(rc, UT_COORD) ) 761 777 setBoxMargins( wd, rc ); … … 769 785 { 770 786 // Set draw list variables. 771 rc = styleCell( CI_STYLE_LABEL );787 rc = gui_styleCell( CI_STYLE_LABEL ); 772 788 ur_initString( rc, wd->titleN, 0 ); 773 789 774 rc = styleCell( CI_STYLE_AREA );775 gui_initRectCoord( rc, wp, 4);790 rc = gui_styleCell( CI_STYLE_AREA ); 791 gui_initRectCoord( rc, wp, UR_ATOM_RECT ); 776 792 777 793 // Compile draw list. 778 rc = styleCell( CI_STYLE_WINDOW );794 rc = gui_styleCell( CI_STYLE_WINDOW ); 779 795 if( ur_is(rc, UT_DRAWLIST) ) 780 796 ug_compileDrawList( ui->ut, rc, wd->dl[ 0 ] ); … … 795 811 796 812 797 //#define BTN_PRESSED GW_FLAG_USER1 798 799 #define BTN_STATE_UP 0 800 #define BTN_STATE_DOWN 1 801 802 803 typedef struct 804 { 805 UIndex labelN; 806 UIndex codeN; 807 GLuint dl[4]; 808 uint8_t pool[4]; // LIMIT: 256 gllist pools. 809 uint8_t state; 810 uint8_t held; 811 812 uint8_t _pad[2]; 813 } 814 ButtonData; 815 816 #define BUTTON_DATA(wp) ((ButtonData*) (wp)->cell) 817 818 819 static GWidget* button_parse( GUI* ui, GMakeState* ms, int classId ) 820 { 821 GWidget* wp; 822 ButtonData* wd; 823 const UCell* arg0; 824 825 arg0 = gui_matchArgs( ms, 2, UT_STRING, UT_BLOCK ); 826 if( arg0 ) 827 { 828 GUI_PARSE_ALLOC( wp ) 829 830 wd = BUTTON_DATA(wp); 831 wd->labelN = arg0->series.n; 832 wd->codeN = (arg0 + 1)->series.n; 833 return wp; 834 } 835 836 GUI_PARSE_ERR( "button requires string! and block!" ); 837 } 838 839 840 static void button_init( GUI* ui, GWidget* wp ) 841 { 842 int i; 843 int pool; 844 ButtonData* wd = BUTTON_DATA(wp); 845 (void) ui; 846 847 memSet( wd, 0, sizeof(ButtonData) ); 848 849 for( i = 0; i < 2; ++i ) 850 { 851 wd->dl[ i ] = gllist_alloc( &pool ); 852 wd->pool[ i ] = pool; 853 } 854 855 wd->state = BTN_STATE_UP; 856 wd->held = 0; 857 } 858 859 860 static void button_mark( GUI* ui, UCollector* gc, GWidget* wp ) 861 { 862 UIndex n; 863 ButtonData* wd = BUTTON_DATA(wp); 864 (void) ui; 865 866 n = wd->labelN; 867 if( n ) 868 ur_gcMarkBin( gc, n ); 869 870 n = wd->codeN; 871 if( n ) 872 ur_gcMarkBlock( gc, n ); 873 874 for( n = 0; n < 2; ++n ) 875 gllist_gcMark( wd->pool[ n ], wd->dl[ n ] ); 876 } 877 878 879 static void button_event( GUI* ui, GWidget* wp, const GLViewEvent* ev ) 880 { 881 ButtonData* wd = BUTTON_DATA(wp); 882 //printf( "KR button %d\n", ev->type ); 883 884 switch( ev->type ) 885 { 886 case GLV_EVENT_BUTTON_DOWN: 887 if( ev->code == GLV_BUTTON_LEFT ) 888 { 889 GWidgetId id = WID(wp); 890 891 wd->state = BTN_STATE_DOWN; 892 wd->held = 1; 893 gui_grabMouse( ui, id ); 894 gui_setKeyFocus( ui, id ); 895 } 896 break; 897 898 case GLV_EVENT_BUTTON_UP: 899 if( ev->code == GLV_BUTTON_LEFT ) 900 { 901 int pressed = (wd->state == BTN_STATE_DOWN); 902 gui_ungrabMouse( ui, WID(wp) ); 903 wd->state = BTN_STATE_UP; 904 wd->held = 0; 905 if( pressed && gui_widgetContains( wp, ev->x, ev->y ) ) 906 goto activate; 907 } 908 break; 909 910 case GLV_EVENT_MOTION: 911 if( wd->held ) 912 { 913 if( gui_widgetContains( wp, ev->x, ev->y ) ) 914 wd->state = BTN_STATE_DOWN; 915 else 916 wd->state = BTN_STATE_UP; 917 } 918 break; 919 920 case GLV_EVENT_KEY_DOWN: 921 if( ev->code == KEY_Return ) 922 { 923 wd->state = BTN_STATE_UP; 924 goto activate; 925 } 926 break; 927 928 case GLV_EVENT_FOCUS_IN: 929 break; 930 931 case GLV_EVENT_FOCUS_OUT: 932 wd->state = BTN_STATE_UP; 933 break; 934 } 935 return; 936 937 activate: 938 939 if( wd->codeN ) 940 { 941 if( UR_EVAL_OK != ur_eval( ui->ut, wd->codeN, 0 ) ) 942 { 943 UG_GUI_THROW; 944 } 945 } 946 } 947 948 949 static void button_sizeHint( GUI* ui, GWidget* wp, GSizeHint* size ) 950 { 951 UCell* wfont; 952 UCell* rc; 953 UString* str; 954 TexFont* tf; 955 UThread* ut = ui->ut; 956 ButtonData* wd = BUTTON_DATA(wp); 957 int width; 958 959 rc = styleCell( CI_STYLE_BUTTON_SIZE ); 960 if( ur_is(rc, UT_COORD) ) 961 { 962 size->minW = rc->coord.elem[0]; 963 size->minH = rc->coord.elem[1]; 964 size->maxW = rc->coord.elem[2]; 965 } 966 else 967 { 968 size->minW = 32; 969 size->minH = 20; 970 size->maxW = 100; 971 } 972 973 size->maxH = size->minH; 974 size->weightX = 2; 975 size->weightY = 1; 976 size->policyX = GW_WEIGHTED; 977 size->policyY = GW_FIXED; 978 979 if( wd->labelN ) 980 { 981 str = ur_binPtr( wd->labelN ); 982 wfont = styleCell( CI_STYLE_CONTROL_FONT ); 983 if( ur_is(wfont, UT_FONT) ) 984 { 985 tf = (TexFont*) ur_binPtr( ur_fontTF(wfont) )->ptr.v; 986 width = txf_width( tf, str->ptr.c, str->ptr.c + str->used ); 987 if( width > size->minW ) 988 size->minW += width; 989 if( size->maxW < size->minW ) 990 size->maxW = size->minW; 991 } 992 } 993 } 994 995 996 static void button_buildLists( GUI* ui, GWidget* wp ) 997 { 998 UCell* rc; 999 ButtonData* wd = BUTTON_DATA(wp); 1000 1001 1002 // Set draw list variables. 1003 1004 rc = styleCell( CI_STYLE_LABEL ); 1005 ur_initString( rc, wd->labelN, 0 ); 1006 1007 rc = styleCell( CI_STYLE_AREA ); 1008 gui_initRectCoord( rc, wp, 4 ); 1009 1010 1011 // Compile draw lists. 1012 1013 rc = styleCell( CI_STYLE_BUTTON_UP ); 1014 if( ur_is(rc, UT_DRAWLIST) ) 1015 ug_compileDrawList( ui->ut, rc, wd->dl[ BTN_STATE_UP ] ); 1016 1017 rc = styleCell( CI_STYLE_BUTTON_DOWN ); 1018 if( ur_is(rc, UT_DRAWLIST) ) 1019 ug_compileDrawList( ui->ut, rc, wd->dl[ BTN_STATE_DOWN ] ); 1020 } 1021 1022 1023 static void button_layout( GUI* ui, GWidget* wp, GRect* rect ) 1024 { 1025 if( AREA_CHANGED( wp, rect ) ) 1026 { 1027 SET_AREA( wp, rect ); 1028 button_buildLists( ui, wp ); 1029 } 1030 } 1031 1032 1033 static void button_render( GUI* ui, GWidget* wp ) 1034 { 1035 (void) ui; 1036 ButtonData* wd = BUTTON_DATA(wp); 1037 glCallList( wd->dl[ wd->state ] ); 1038 } 1039 1040 1041 //---------------------------------------------------------------------------- 1042 1043 813 #include "widgets/buttonw.c" 814 #include "widgets/labelw.c" 1044 815 #include "widgets/twidget.c" 1045 #include "widgets/listw.c"816 //#include "widgets/listw.c" 1046 817 1047 818 /* … … 1062 833 { "expand", 1063 834 base_parse, expand_init, no_mark, no_event, 1064 expand_sizeHint, no_layout, no_render,835 expand_sizeHint, base_layout, no_render, base_select, 1065 836 0, 0, 0 }, 1066 837 1067 838 { "hbox", 1068 839 box_parse, box_init, box_mark, no_event, 1069 hbox_sizeHint, hbox_layout, box_render, 840 hbox_sizeHint, hbox_layout, box_render, base_select, 1070 841 0, 0, 0 }, 1071 842 1072 843 { "vbox", 1073 844 box_parse, box_init, box_mark, no_event, 1074 vbox_sizeHint, vbox_layout, box_render, 845 vbox_sizeHint, vbox_layout, box_render, base_select, 1075 846 0, 0, 0 }, 1076 847 1077 848 { "window", 1078 849 window_parse, window_init, window_mark, no_event, 1079 window_sizeHint, window_layout, window_render, 850 window_sizeHint, window_layout, window_render, base_select, 1080 851 0, 0, 0 }, 1081 852 1082 853 { "button", 1083 854 button_parse, button_init, button_mark, button_event, 1084 button_sizeHint, button_layout, button_render, 855 button_sizeHint, button_layout, button_render, button_select, 856 0, 0, 0 }, 857 858 { "label", 859 label_parse, label_init, label_mark, no_event, 860 label_sizeHint, label_layout, label_render, label_select, 1085 861 0, 0, 0 }, 1086 862 1087 863 { "t-widget", 1088 864 twidget_parse, twidget_init, twidget_mark, twidget_event, 1089 expand_sizeHint, twidget_layout, twidget_render, 865 expand_sizeHint, twidget_layout, twidget_render, base_select, 1090 866 0, 0, 0 }, 1091 867 868 /* 1092 869 { "list", // "block! block!" 1093 870 listw_parse, listw_init, listw_mark, listw_event, 1094 expand_sizeHint, listw_layout, listw_render, 871 expand_sizeHint, listw_layout, listw_render, base_select, 1095 872 0, 0, 0 }, 1096 873 1097 /* 1098 { "option", 1099 { "choice", 1100 { "menu", 1101 { "data", // label 1102 { "data-edit", // spin box, line editor 874 "option", 875 "choice", 876 "menu", 877 "data", // label 878 "data-edit", // spin box, line editor 1103 879 */ 1104 880 }; … … 1116 892 assert( sizeof(BoxData) == 32 ); 1117 893 assert( sizeof(ButtonData) == 32 ); 894 assert( sizeof(LabelData) == 32 ); 1118 895 1119 896 ui->ut = ut; … … 1125 902 ui->rootList = NO_WID; 1126 903 ui->atom_gui_style = ur_intern( "gui-style", 9 ); 1127 ui->atom_hbox = ur_intern( "hbox", 4 ); 904 ui->atom_hbox = ur_intern( "hbox", 4 ); 905 ui->atom_action = ur_intern( "action", 6 ); 906 ui->atom_text = ur_intern( "text", 4 ); 1128 907 ui->rootW = 0; 1129 908 ui->rootH = 0; … … 1493 1272 1494 1273 1274 /* 1275 The select method returns non-zero if result is set, or zero if error. 1276 The select method must not throw errors. 1277 */ 1278 int gui_selectAtom( GUI* ui, GWidget* wp, UAtom atom, UCell* result ) 1279 { 1280 return CLASS( wp ).select( ui, wp, atom, result ); 1281 } 1282 1283 1495 1284 static inline void linkRoot( GUI* ui, GWidget* wp, GWidgetId id ) 1496 1285 { … … 1501 1290 1502 1291 /* 1503 Returns zero and throws error if fails. 1292 This implements the GUI layout dialect, which supports custom widget 1293 classes. 1504 1294 1505 1295 Calls the parse method of each widget to read from ms->it to ms->end. 1506 1296 1507 1297 If the parse method fails it should return zero and either throw an 1508 1298 error or point ms->error to an error message. 1299 1300 \param ms The blkN, it, & end members must be initialized for layout block. 1301 1302 \return Widget pointer or zero (and throws error) if fails. 1509 1303 */ 1510 1304 GWidget* gui_parseLayout( GUI* ui, GWidget* parent, GMakeState* ms ) trunk/thune/gl/gui.h
r528 r533 42 42 UAtom atom_gui_style; 43 43 UAtom atom_hbox; 44 UAtom atom_action; 45 UAtom atom_text; 44 46 GWidgetId root; 45 47 GWidgetId keyFocus; … … 103 105 void (*layout) ( GUI*, GWidget*, GRect* ); 104 106 void (*render) ( GUI*, GWidget* ); 107 int (*select) ( GUI*, GWidget*, UAtom, UCell* ); 105 108 /* 106 109 uint8_t sizeH; … … 155 158 int gui_widgetContains( GWidget*, int x, int y ); 156 159 void gui_render( GUI*, GWidgetId ); 160 int gui_selectAtom( GUI*, GWidget*, UAtom atom, UCell* result ); 157 161 GWidget* gui_parseLayout( GUI*, GWidget* parent, GMakeState* ); 158 162 const UCell* gui_matchArgs( GMakeState* ms, int argc, ... ); 159 163 GWidget* gui_root( const GUI* ui, GWidgetId id ); 160 void gui_initRectCoord( UCell*, GWidget*, int len );161 164 void gui_setKeyFocus( GUI*, GWidgetId ); 162 165 void gui_grabMouse( GUI*, GWidgetId ); … … 172 175 if(! wp) { GUI_PARSE_ERR( "allocWidget failed" ); } 173 176 177 // gui_styleCell may only be used by sizeHint, layout, &am
