Changeset 186

Show
Ignore:
Timestamp:
09/21/2007 02:44:26 (12 months ago)
Author:
why
Message:

* shoes/world.c: introduced the new shoes_world_t struct so I can start to implement multiple windows soon.
* shoes/app.c: the shoes_app struct is now wrapped by the App class.
* shoes/ruby.c: heavy reorganization of how blocks are called. prevalent use of instance_eval has been abandoned in favor of evaluation at the app-level and tracking of canvas nesting. i just think instance_eval was too confusing for beginners, I'm much happier with this. In this way, instance variables can be used to store elements rather than plain variables.
* samples/: use of instance variables to store controls and changes to reflect the new scoping. this revision breaks a lot of old code and doesn't yet compile on osx and win32.

Location:
trunk
Files:
2 added
14 modified

Legend:

Unmodified
Added
Removed
  • trunk/bin/main.skel

    r176 r186  
    1717#endif 
    1818{ 
     19  shoes_code code; 
     20  char *path = NULL; 
    1921#ifdef SHOES_WIN32 
    2022  int argc; 
     
    2325#endif 
    2426  %DEFAULTS% 
    25   shoes_init(); 
    26   shoes_app *app = shoes_app_new(); 
     27  code = shoes_init(); 
     28  if (code != SHOES_OK) 
     29    goto done; 
     30 
    2731#ifdef SHOES_WIN32 
    28   app->kit.instance = inst; 
    29   app->kit.style = style; 
    30   app->path = SHOE_ALLOC_N(char, SHOES_BUFSIZE); 
    31   GetModuleFileName(NULL, (LPSTR)app->path, SHOES_BUFSIZE); 
     32  world->instance = inst; 
     33  world->style = style; 
     34  path = SHOE_ALLOC_N(char, SHOES_BUFSIZE); 
     35  GetModuleFileName(NULL, (LPSTR)world->path, SHOES_BUFSIZE); 
    3236#else 
    33   app->path = argv[0]; 
     37  path = argv[0]; 
    3438#endif 
    3539  ruby_set_argv(argc - 1, &argv[1]); 
    36   if (shoes_app_load(app) != SHOES_QUIT) 
    37   { 
    38     shoes_app_open(app); 
    39     shoes_app_loop(app, "/"); 
    40     shoes_app_close(app); 
    41   } 
     40  code = shoes_load(path); 
     41  if (code != SHOES_OK) 
     42    goto done; 
     43 
     44  code = shoes_start("/"); 
     45  if (code != SHOES_OK) 
     46    goto done; 
     47 
     48done: 
    4249#ifdef SHOES_WIN32 
    43   SHOE_FREE(app->path); 
     50  if (path != NULL) 
     51    SHOE_FREE(path); 
    4452#endif 
    45   shoes_app_free(app); 
     53  shoes_final(); 
    4654  return 0; 
    4755} 
  • trunk/samples/book.rb

    r145 r186  
    1919  def incident(num) 
    2020    num = num.to_i 
    21     toc = table_of_contents 
    2221    flow :margin => 10, :margin_left => 200, :margin_top => 20 do 
    2322      text "<span font_desc='Arial 46px'>Incident</span>\n" + 
     
    2524    end 
    2625    flow :width => 180, :margin_left => 10 do 
    27       text toc 
     26      text table_of_contents 
    2827    end 
    2928    flow :width => -250, :margin_left => 10 do 
  • trunk/samples/bounce.rb

    r163 r186  
    33 
    44Shoes.app do 
    5   background "#DFA".."#F90", :angle => 45 
     5  background "#DFA" 
    66  border black, :strokewidth => 6 
    77 
    88  nostroke 
    9   icon = image "static/shoes-icon.png", :left => 100, :top => 100 
     9  @icon = image "static/shoes-icon.png", :left => 100, :top => 100 
    1010 
    1111  x, y = self.width / 2, self.height / 2 
    12   size = icon.size 
     12  size = @icon.size 
    1313  animate(30) do 
    1414    x += xspeed * xdir 
     
    1818    ydir *= -1 if y > self.height - size[1] or y < 0 
    1919 
    20     icon.move x.to_i, y.to_i 
     20    @icon.move x.to_i, y.to_i 
    2121  end 
    2222end 
  • trunk/samples/form.rb

    r84 r186  
    1 name, phone, address = nil 
    21Shoes.app :width => 320, :height => 350 do 
    32  background "static/menu-gray.png" 
     
    1110    stack :margin => 10 do 
    1211      text "Name" 
    13       name = list_box :items => ["Yes, please!", "NO.  No thankyou."] 
     12      @name = list_box :items => ["Yes, please!", "NO.  No thankyou."] 
    1413    end 
    1514    stack :margin => 10 do 
    1615      text "Address" 
    17       address = edit_line 
     16      @address = edit_line 
    1817    end 
    1918    stack :margin => 10 do 
    2019      text "Phone" 
    21       phone = edit_line 
     20      @phone = edit_line 
    2221    end 
    2322    stack :margin => 10 do 
    2423      button "Save" do 
    25         Shoes.p [name.text, address.text, phone.text] 
     24        Shoes.p [@name.text, @address.text, @phone.text] 
    2625      end 
    2726    end 
  • trunk/samples/rect.rb

    r123 r186  
    1 rectangles = proc do 
    2   20.times do 
    3     nostroke 
    4     fill rgb((0.6..1.0).rand, (0.1..1.0).rand, (0.2..1.0).rand, (0.4..1.0).rand) 
    5     r = rand(300) + 60 
    6     rect :left => (10..100).rand, :top => (10..200).rand, :width => r, :height => r 
     1Shoes.app :width => 400, :height => 500 do 
     2  rectangles = proc do 
     3    20.times do 
     4      nostroke 
     5      fill rgb((0.6..1.0).rand, (0.1..1.0).rand, (0.2..1.0).rand, (0.4..1.0).rand) 
     6      r = rand(300) + 60 
     7      rect :left => (10..100).rand, :top => (10..200).rand, :width => r, :height => r 
     8    end 
     9    button "OK", :left => 300, :top => 400 do 
     10      clear &rectangles 
     11    end 
    712  end 
    8   button "OK", :left => 300, :top => 400 do 
    9     clear &rectangles 
    10   end 
     13 
     14  rectangles[] 
    1115end 
    12  
    13 Shoes.app :width => 400, :height => 500, &rectangles 
  • trunk/samples/timer.rb

    r120 r186  
    1 label, time = nil, Time.now 
    21Shoes.app :height => 150, :width => 250 do 
    32  background rgb(240, 250, 208) 
    43  stack :margin => 10 do 
    54    button "Start" do 
    6       time = Time.now 
    7       label.replace "Stop watch started at #{time}" 
     5      @time = Time.now 
     6      @label.replace "Stop watch started at #@time" 
    87    end 
    98    button "Stop" do 
    10       label.replace "Stopped, #{Time.now - time} seconds elapsed." 
     9      @label.replace "Stopped, #{Time.now - @time} seconds elapsed." 
    1110    end 
    12     label = text "Press start to begin timing." 
     11    @label = text "Press start to begin timing." 
    1312  end 
    1413end 
  • trunk/shoes/app.c

    r183 r186  
    77#include "shoes/ruby.h" 
    88#include "shoes/canvas.h" 
     9#include "shoes/world.h" 
    910#include "node.h" 
    1011 
    11 shoes_app *global_app = NULL; 
    12  
    13 shoes_app * 
    14 shoes_app_new() 
     12static void 
     13shoes_app_mark(shoes_app *app) 
     14{ 
     15#ifndef SHOES_GTK 
     16  rb_gc_mark_maybe(app->slot.controls); 
     17#endif 
     18  rb_gc_mark_maybe(app->canvas); 
     19  rb_gc_mark_maybe(app->nesting); 
     20  rb_gc_mark_maybe(app->timers); 
     21} 
     22 
     23static void 
     24shoes_app_free(shoes_app *app) 
     25{ 
     26  free(app); 
     27} 
     28 
     29VALUE 
     30shoes_app_alloc(VALUE klass) 
    1531{ 
    1632  shoes_app *app = SHOE_ALLOC(shoes_app); 
     33  SHOE_MEMZERO(app, shoes_app, 1); 
    1734  app->canvas = shoes_canvas_new(cShoes, app); 
    18   rb_gc_register_address(&app->canvas); 
     35  app->nesting = rb_ary_new(); 
    1936  app->timers = rb_ary_new(); 
    20   rb_gc_register_address(&app->timers); 
    2137  app->title = Qnil; 
    2238  app->width = SHOES_APP_WIDTH; 
     
    2642  app->slot.window = NULL; 
    2743#else 
    28   app->kit.window = NULL; 
    29 #endif 
    30   return app; 
    31 } 
    32  
    33 void 
    34 shoes_app_free(shoes_app *app) 
    35 { 
    36 #ifdef SHOES_QUARTZ 
    37   CFRelease(app->kit.clip); 
    38   TECDisposeConverter(app->kit.converter); 
    39 #endif 
    40 #ifndef SHOES_GTK 
    41   if (!NIL_P(app->slot.controls)) 
    42     rb_gc_unregister_address(&app->slot.controls); 
    43 #endif 
    44   rb_gc_unregister_address(&app->canvas); 
    45   rb_gc_unregister_address(&app->timers); 
    46   if (app != NULL) 
    47     SHOE_FREE(app); 
     44  app->os.window = NULL; 
     45#endif 
     46  app->self = Data_Wrap_Struct(klass, shoes_app_mark, shoes_app_free, app); 
     47  return app->self; 
     48} 
     49 
     50VALUE 
     51shoes_app_new() 
     52{ 
     53  return shoes_app_alloc(cApp); 
    4854} 
    4955 
     
    8894{ 
    8995  shoes_app *app = (shoes_app *)data; 
    90   gtk_container_propagate_expose(GTK_CONTAINER(app->kit.window), widget, app->slot.expose); 
     96  gtk_container_propagate_expose(GTK_CONTAINER(app->os.window), widget, app->slot.expose); 
    9197} 
    9298 
     
    95101{  
    96102  shoes_app *app = (shoes_app *)data; 
    97   gtk_window_get_size(GTK_WINDOW(app->kit.window), &app->width, &app->height); 
     103  gtk_window_get_size(GTK_WINDOW(app->os.window), &app->width, &app->height); 
    98104  shoes_canvas_size(app->canvas, app->width, app->height); 
    99105  app->slot.expose = event; 
    100   gtk_container_forall(GTK_CONTAINER(app->kit.window), shoes_app_gtk_paint_children, app); 
     106  gtk_container_forall(GTK_CONTAINER(app->os.window), shoes_app_gtk_paint_children, app); 
    101107  app->slot.expose = NULL; 
    102108} 
     
    383389 
    384390OSStatus 
    385 shoes_slot_quartz_create(VALUE self, APPSLOT *parent, int w, int h) 
     391shoes_slot_quartz_create(VALUE self, SHOES_SLOT_OS *parent, int w, int h) 
    386392{ 
    387393  HIRect rect; 
     
    389395  EventRef event; 
    390396  shoes_canvas *canvas; 
    391   APPSLOT *slot; 
     397  SHOES_SLOT_OS *slot; 
    392398  Data_Get_Struct(self, shoes_canvas, canvas); 
    393399  slot = &canvas->slot; 
     
    458464    if (modifier & controlKey) \ 
    459465      KEY_STATE(control); \ 
    460     shoes_app_keypress(global_app, v); \ 
     466    shoes_app_keypress(app, v); \ 
    461467  } else 
    462468 
     
    569575 
    570576              text8 = SHOE_ALLOC_N(char, len); 
    571               status = TECConvertText(app->kit.converter, text, len, &nread, text8, len, &nwrite); 
     577              status = TECConvertText(app->os.converter, text, len, &nread, text8, len, &nwrite); 
    572578 
    573579              if (nwrite == 1 && text8[0] == '\r')  
     
    594600      INFO("kEventClassMouse\n", 0); 
    595601      GetMouse(&mouseLoc); 
    596       GetWindowBounds(app->kit.window, kWindowContentRgn, &bounds); 
     602      GetWindowBounds(app->os.window, kWindowContentRgn, &bounds); 
    597603      if (mouseLoc.h < bounds.left || mouseLoc.v < bounds.top) break; 
    598604      GetEventParameter(inEvent, kEventParamMouseButton, typeMouseButton, 0, sizeof(EventMouseButton), 0, &button); 
     
    628634   
    629635  SetRect(&windowRect, 0, 0, app->width, app->height); 
    630   InvalWindowRect(app->kit.window, &windowRect); 
     636  InvalWindowRect(app->os.window, &windowRect); 
    631637} 
    632638 
     
    647653  y = HIWORD(l) 
    648654 
    649 #define KEY_SYM(sym)  shoes_app_keypress(global_app, ID2SYM(rb_intern("" # sym))) 
     655#define KEY_SYM(sym)  shoes_app_keypress(app, ID2SYM(rb_intern("" # sym))) 
    650656#define KEYPRESS(name, sym) \ 
    651657  else if (w == VK_##name) { \ 
    652658    VALUE v = ID2SYM(rb_intern("" # sym)); \ 
    653     if (global_app->kit.altkey) \ 
     659    if (app->os.altkey) \ 
    654660      KEY_STATE(alt); \ 
    655     if (global_app->kit.shiftkey) \ 
     661    if (app->os.shiftkey) \ 
    656662      KEY_STATE(shift); \ 
    657     if (global_app->kit.ctrlkey) \ 
     663    if (app->os.ctrlkey) \ 
    658664      KEY_STATE(control); \ 
    659     shoes_app_keypress(global_app, v); \ 
     665    shoes_app_keypress(app, v); \ 
    660666  } 
    661667 
     
    678684    { 
    679685      RECT rect; 
    680       GetClientRect(global_app->slot.window, &rect); 
    681       global_app->width = rect.right; 
    682       global_app->height = rect.bottom; 
    683       shoes_canvas_size(global_app->canvas, global_app->width, global_app->height); 
    684       shoes_app_paint(global_app); 
     686      GetClientRect(app->slot.window, &rect); 
     687      app->width = rect.right; 
     688      app->height = rect.bottom; 
     689      shoes_canvas_size(app->canvas, app->width, app->height); 
     690      shoes_app_paint(app); 
    685691    } 
    686692    break; 
     
    688694    case WM_LBUTTONDOWN: 
    689695      WM_POINTS(); 
    690       shoes_app_click(global_app, 1, x, y); 
     696      shoes_app_click(app, 1, x, y); 
    691697    break; 
    692698 
    693699    case WM_RBUTTONDOWN: 
    694700      WM_POINTS(); 
    695       shoes_app_click(global_app, 2, x, y); 
     701      shoes_app_click(app, 2, x, y); 
    696702    break; 
    697703 
    698704    case WM_MBUTTONDOWN: 
    699705      WM_POINTS(); 
    700       shoes_app_click(global_app, 3, x, y); 
     706      shoes_app_click(app, 3, x, y); 
    701707    break; 
    702708 
    703709    case WM_LBUTTONUP: 
    704710      WM_POINTS(); 
    705       shoes_app_release(global_app, 1, x, y); 
     711      shoes_app_release(app, 1, x, y); 
    706712    break; 
    707713 
    708714    case WM_RBUTTONUP: 
    709715      WM_POINTS(); 
    710       shoes_app_release(global_app, 2, x, y); 
     716      shoes_app_release(app, 2, x, y); 
    711717    break; 
    712718 
    713719    case WM_MBUTTONUP: 
    714720      WM_POINTS(); 
    715       shoes_app_release(global_app, 3, x, y); 
     721      shoes_app_release(app, 3, x, y); 
    716722    break; 
    717723 
    718724    case WM_MOUSEMOVE: 
    719725      WM_POINTS(); 
    720       shoes_app_motion(global_app, x, y); 
     726      shoes_app_motion(app, x, y); 
    721727    break; 
    722728 
     
    733739 
    734740        case 0x0D: 
    735           shoes_app_keypress(global_app, rb_str_new2("\n")); 
     741          shoes_app_keypress(app, rb_str_new2("\n")); 
    736742        break; 
    737743 
     
    744750          str[len] = '\0'; 
    745751          v = rb_str_new(str, len); 
    746           shoes_app_keypress(global_app, v); 
     752          shoes_app_keypress(app, v); 
    747753        } 
    748754      } 
     
    752758    case WM_KEYDOWN: 
    753759      if (w == VK_CONTROL) 
    754         global_app->kit.ctrlkey = true; 
     760        app->os.ctrlkey = true; 
    755761      else if (w == VK_MENU) 
    756         global_app->kit.altkey = true; 
     762        app->os.altkey = true; 
    757763      else if (w == VK_SHIFT) 
    758         global_app->kit.shiftkey = true; 
     764        app->os.shiftkey = true; 
    759765      KEYPRESS(PRIOR, page_up) 
    760766      KEYPRESS(NEXT, page_down) 
     
    781787        char letter = w + 32; 
    782788        v = rb_str_new(&letter, 1); 
    783         if (global_app->kit.altkey) { 
     789        if (app->os.altkey) { 
    784790          KEY_STATE(alt); 
    785           shoes_app_keypress(global_app, v); 
     791          shoes_app_keypress(app, v); 
    786792        } 
    787793      } 
     
    791797    case WM_KEYUP: 
    792798      if (w == VK_CONTROL) 
    793         global_app->kit.ctrlkey = false; 
     799        app->os.ctrlkey = false; 
    794800      else if (w == VK_MENU) 
    795         global_app->kit.altkey = false; 
     801        app->os.altkey = false; 
    796802      else if (w == VK_SHIFT) 
    797         global_app->kit.shiftkey = false; 
     803        app->os.shiftkey = false; 
    798804    break; 
    799805 
     
    801807    { 
    802808      int id = LOWORD(w); 
    803       VALUE timer = rb_ary_entry(global_app->timers, id - SHOES_CONTROL1); 
     809      VALUE timer = rb_ary_entry(app->timers, id - SHOES_CONTROL1); 
    804810      if (!NIL_P(timer)) 
    805811        shoes_anim_call(timer); 
     
    811817      { 
    812818        int id = LOWORD(w); 
    813         VALUE control = rb_ary_entry(global_app->slot.controls, id - SHOES_CONTROL1); 
     819        VALUE control = rb_ary_entry(app->slot.controls, id - SHOES_CONTROL1); 
    814820        if (!NIL_P(control)) 
    815821          shoes_control_send(control, s_click); 
     
    822828 
    823829shoes_code 
    824 shoes_app_load(shoes_app *app) 
    825 { 
    826   char bootup[512]; 
    827   if (global_app == NULL) 
    828     global_app = app; 
    829  
    830   sprintf(bootup, 
    831     "begin;" 
    832       "DIR = File.expand_path(File.dirname(%%q<%s>));" 
    833       "$:.replace([DIR+'/ruby/lib/'+PLATFORM, DIR+'/ruby/lib', DIR+'/lib']);" 
    834       "require 'shoes';" 
    835       "'OK';" 
    836     "rescue Object => e;" 
    837       SHOES_META 
    838         "define_method :load do |path|; end;" 
    839         EXC_RUN 
    840       "end;" 
    841       "e.message;" 
    842     "end", 
    843     app->path); 
    844   VALUE str = rb_eval_string(bootup); 
    845   StringValue(str); 
    846   INFO("Bootup: %s\n", RSTRING(str)->ptr); 
    847  
    848   VALUE uri = rb_eval_string("$SHOES_URI = Shoes.args!"); 
    849   if (!RTEST(uri)) 
    850     return SHOES_QUIT; 
    851  
    852   sprintf(bootup, 
    853     "begin;" 
    854       "Shoes.load($SHOES_URI) if $SHOES_URI.is_a?(String);" 
    855     "rescue Object => e;" 
    856       SHOES_META 
    857         EXC_RUN 
    858       "end;" 
    859     "end;"); 
    860   rb_eval_string(bootup); 
    861  
    862   return SHOES_OK; 
    863 } 
    864  
    865 shoes_code 
    866830shoes_app_cursor(shoes_app *app, ID cursor) 
    867831{ 
    868832#ifdef SHOES_GTK 
    869   if (app->kit.window == NULL || app->kit.window->window == NULL || app->cursor == cursor) 
     833  if (app->os.window == NULL || app->os.window->window == NULL || app->cursor == cursor) 
    870834    goto done; 
    871835 
     
    882846    goto done; 
    883847 
    884   gdk_window_set_cursor(app->kit.window->window, c); 
     848  gdk_window_set_cursor(app->os.window->window, c); 
    885849#endif 
    886850 
    887851#ifdef SHOES_QUARTZ 
    888   if (app->kit.window == NULL || app->cursor == cursor) 
     852  if (app->os.window == NULL || app->cursor == cursor) 
    889853    goto done; 
    890854 
     
    931895 
    932896#ifdef SHOES_GTK 
    933   if (app->kit.window != NULL) 
    934     gtk_widget_set_size_request(app->kit.window, app->width, app->height); 
     897  if (app->os.window != NULL) 
     898    gtk_widget_set_size_request(app->os.window, app->width, app->height); 
    935899#endif 
    936900 
     
    955919  int width, height; 
    956920  VALUE attr, block; 
     921  GLOBAL_APP(app); 
     922 
    957923  rb_scan_args(argc, argv, "01&", &attr, &block); 
    958924  rb_iv_set(self, "@main_app", block); 
    959   global_app->title = ATTR(attr, title); 
    960   global_app->resizable = (ATTR(attr, resizable) != Qfalse); 
    961   shoes_app_resize(global_app, ATTR2(int, attr, width, SHOES_APP_WIDTH), ATTR2(int, attr, height, SHOES_APP_HEIGHT)); 
    962   shoes_canvas_init(global_app->canvas, global_app->slot, attr, global_app->width, global_app->height); 
     925 
     926  app->title = ATTR(attr, title); 
     927  app->resizable = (ATTR(attr, resizable) != Qfalse); 
     928  shoes_app_resize(app, ATTR2(int, attr, width, SHOES_APP_WIDTH), ATTR2(int, attr, height, SHOES_APP_HEIGHT)); 
     929  shoes_canvas_init(app->canvas, app->slot, attr, app->width, app->height); 
    963930  return self; 
    964931} 
     
    978945 
    979946#ifdef SHOES_GTK 
    980   gtk_window_set_title(GTK_WINDOW(app->kit.window), _(msg)); 
     947  gtk_window_set_title(GTK_WINDOW(app->os.window), _(msg)); 
    981948#endif 
    982949 
    983950#ifdef SHOES_QUARTZ 
    984951  CFStringRef cfmsg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingUTF8); 
    985   OSStatus err = SetWindowTitleWithCFString(app->kit.window, cfmsg); 
     952  OSStatus err = SetWindowTitleWithCFString(app->os.window, cfmsg); 
    986953#endif 
    987954 
     
    992959 
    993960shoes_code 
     961shoes_app_start(VALUE appobj, char *uri) 
     962{ 
     963  shoes_code code; 
     964  shoes_app *app; 
     965  Data_Get_Struct(appobj, shoes_app, app); 
     966 
     967  code = shoes_app_open(app); 
     968  if (code != SHOES_OK) 
     969    return code; 
     970 
     971  code = shoes_app_loop(app, uri); 
     972  if (code != SHOES_OK) 
     973    return code; 
     974 
     975  return shoes_app_close(app); 
     976} 
     977 
     978shoes_code 
    994979shoes_app_open(shoes_app *app) 
    995980{ 
     
    997982 
    998983#ifdef SHOES_GTK 
    999   shoes_app_gtk *gk = &app->kit; 
     984  shoes_app_gtk *gk = &app->os; 
    1000985  shoes_slot_gtk *gs = &app->slot; 
    1001986 
     
    10491034    ^ (app->resizable ? kWindowResizableAttribute : 0), 
    10501035    &gRect, 
    1051     &app->kit.window); 
     1036    &app->os.window); 
    10521037 
    10531038  if (err != noErr) 
     
    10721057 
    10731058  INFO("Event handler.\n", 0); 
    1074   err = InstallWindowEventHandler(app->kit.window, 
     1059  err = InstallWindowEventHandler(app->os.window, 
    10751060    gTestWindowEventProc, GetEventTypeCount(windowEvents), 
    10761061    windowEvents, app, NULL); 
    10771062 
    1078   HIViewFindByID(HIViewGetRoot(app->kit.window), kHIViewWindowContentID, &app->slot.view); 
    1079  
    1080   if (PasteboardCreate(kPasteboardClipboard, &app->kit.clip) != noErr) { 
     1063  HIViewFindByID(HIViewGetRoot(app->os.window), kHIViewWindowContentID, &app->slot.view); 
     1