Back to index

texmacs  1.0.7.15
aqua_widget.mm
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : aqua_widget.mm
00004 * DESCRIPTION: Aqua widget class
00005 * COPYRIGHT  : (C) 2007  Massimiliano Gubinelli
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "mac_cocoa.h" 
00013 
00014 #include "aqua_widget.h"
00015 #include "aqua_simple_widget.h"
00016 #include "aqua_other_widgets.h"
00017 #include "aqua_renderer.h"
00018 #include "aqua_utilities.h"
00019 #include "aqua_menu.h"
00020 
00021 
00022 #include "gui.hpp"
00023 #include "widget.hpp" 
00024 #include "message.hpp"
00025 #include "promise.hpp"
00026 #include "analyze.hpp"
00027 
00028 #include "aqua_basic_widgets.h"
00029 
00030 #import "TMView.h"
00031 #import "TMButtonsController.h"
00032 
00033 #define TYPE_CHECK(b) ASSERT (b, "type mismatch")
00034 #define NOT_IMPLEMENTED \
00035   { if (DEBUG_EVENTS) cout << "STILL NOT IMPLEMENTED\n"; }
00036 
00037 widget the_keyboard_focus(NULL);
00038 
00039 @interface TMWindowController : NSWindowController
00040 {
00041        aqua_window_widget_rep *wid;
00042 }
00043 - (void) setWidget:(widget_rep*) w;
00044 - (widget_rep*) widget;
00045 @end
00046 
00047 
00048 
00049 widget 
00050 aqua_widget_rep::plain_window_widget (string s) {
00051   (void) s;
00052   return widget ();
00053 }
00054 
00055 widget 
00056 aqua_widget_rep::make_popup_widget () {
00057   return this;
00058 }
00059 
00060 widget 
00061 aqua_widget_rep::popup_window_widget (string s) {
00062   (void) s;
00063   return widget();
00064 }
00065 
00066 
00067 
00068 TMMenuItem *
00069 aqua_widget_rep::as_menuitem() { 
00070   return [TMMenuItem alloc];  
00071 }
00072 
00073 /******************************************************************************
00074 * aqua_view_widget_rep
00075 ******************************************************************************/
00076 
00077 #pragma mark aqua_view_widget_rep
00078 
00079 aqua_view_widget_rep::aqua_view_widget_rep(NSView *v) : 
00080   aqua_widget_rep(), view(v) { 
00081   [v retain]; 
00082 }
00083 
00084 aqua_view_widget_rep::~aqua_view_widget_rep()  { 
00085   [view release]; 
00086 }
00087 
00088 
00089 
00090 void
00091 aqua_view_widget_rep::send (slot s, blackbox val) {
00092   switch (s) {
00093   case SLOT_NAME:
00094     {  
00095       check_type<string> (val, "SLOT_NAME");
00096       string name = open_box<string> (val);
00097       NSWindow *win = [view window];
00098       if (win) {
00099        [win setTitle:to_nsstring(name)];
00100       }
00101     }
00102     break;
00103   case SLOT_INVALIDATE:
00104     {
00105       TYPE_CHECK (type_box (val) == type_helper<coord4>::id);
00106       coord4 p= open_box<coord4> (val);
00107       NSRect rect = to_nsrect(p);
00108       if (DEBUG_EVENTS) NSLog(@"invalidating %@",NSStringFromRect(rect));
00109       [view setNeedsDisplayInRect:rect];
00110     }
00111     break;
00112   case SLOT_INVALIDATE_ALL:
00113     {
00114       ASSERT (is_nil (val), "type mismatch");
00115       [view setNeedsDisplay:YES];
00116     }
00117     break;
00118   case SLOT_MOUSE_GRAB:
00119     NOT_IMPLEMENTED;
00120     //               send_mouse_grab (THIS, val);
00121     break;
00122   case SLOT_MOUSE_POINTER:
00123     NOT_IMPLEMENTED;
00124     //               send_mouse_pointer (THIS, val);
00125     break;
00126     
00127   case SLOT_KEYBOARD_FOCUS:
00128     //               send_keyboard_focus (THIS, val);
00129     {
00130       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00131       if (open_box<bool>(val)) the_keyboard_focus = this;
00132     }
00133     break;
00134        
00135   default:
00136     cout << "slot type= " << slot_name (s) << "\n";
00137     FAILED ("cannot handle slot type");
00138   }
00139 }
00140 
00141 /******************************************************************************
00142 * Querying
00143 ******************************************************************************/
00144 
00145 blackbox
00146 aqua_view_widget_rep::query (slot s, int type_id) {
00147   switch (s) {
00148   case SLOT_IDENTIFIER:
00149     TYPE_CHECK (type_id == type_helper<int>::id);
00150     return close_box<int> ([view window] ? 1 : 0);
00151   case SLOT_RENDERER:
00152     TYPE_CHECK (type_id == type_helper<renderer>::id);
00153     return close_box<renderer> ((renderer) the_aqua_renderer());
00154   case SLOT_POSITION:  
00155     {
00156       typedef pair<SI,SI> coord2;
00157       TYPE_CHECK (type_id == type_helper<coord2>::id);
00158       NSPoint pos = [view frame].origin;
00159       return close_box<coord2> (from_nspoint(pos));
00160     }
00161     
00162   default:
00163     FAILED ("cannot handle slot type");
00164     return blackbox ();
00165   }
00166 }
00167 
00168 /******************************************************************************
00169  * Notification of state changes
00170  ******************************************************************************/
00171 
00172 void
00173 aqua_view_widget_rep::notify (slot s, blackbox new_val) {
00174   aqua_widget_rep::notify (s, new_val);
00175 }
00176 
00177 /******************************************************************************
00178  * Read and write access of subwidgets
00179  ******************************************************************************/
00180 
00181 widget
00182 aqua_view_widget_rep::read (slot s, blackbox index) {
00183   switch (s) {
00184   case SLOT_WINDOW:
00185     check_type_void (index, "SLOT_WINDOW");
00186     return [(TMWindowController*)[[view window] windowController] widget];
00187   default:
00188     FAILED ("cannot handle slot type");
00189     return widget();
00190   }
00191 }
00192 
00193 void
00194 aqua_view_widget_rep::write (slot s, blackbox index, widget w) {
00195   switch (s) {
00196   default:
00197     FAILED ("cannot handle slot type");
00198   }
00199 }
00200 
00201 
00202 widget 
00203 aqua_view_widget_rep::plain_window_widget (string s)
00204 // creates a decorated window with name s and contents w
00205 {
00206   NSRect screen_frame = [[NSScreen mainScreen] visibleFrame];
00207        
00208   NSWindow *nsw = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,100,100) 
00209                                  styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
00210                                  backing:NSBackingStoreBuffered
00211                                  defer:NO] autorelease];
00212   // NSView *view = ((aqua_view_widget_rep*)w.rep)->get_nsview();
00213   //   NSRect frame = [[nsw contentView] frame];
00214   //   [view setFrame:frame];
00215   [nsw setContentView:view];
00216   [nsw setTitle:to_nsstring(s)];
00217   [nsw setAcceptsMouseMovedEvents:YES];
00218   //   [[nsw contentView] addSubview:view];
00219   //   [nsw setToolbar:((aqua_tm_widget_rep*)w.rep)->toolbar];
00220   widget wid =  tm_new <aqua_window_widget_rep> (nsw);
00221   return wid; 
00222 }
00223 
00224 
00225 #pragma mark aqua_tm_widget_rep
00226 
00227 NSString *TMToolbarIdentifier = @"TMToolbarIdentifier";
00228 NSString *TMButtonsIdentifier = @"TMButtonsIdentifier";
00229 
00230 @interface TMToolbarItem : NSToolbarItem
00231 @end
00232 @implementation TMToolbarItem
00233 - (void)validate
00234 {
00235   NSSize s = [[self view] frame].size;
00236   NSSize s2 = [self minSize];
00237   if ((s.width != s2.width)||(s.height!=s2.height)) {
00238     [self setMinSize:s];
00239     [self setMaxSize:s];
00240   }
00241   //   NSLog(@"validate\n");
00242 }
00243 @end
00244 
00245 
00246 
00247 @interface TMWidgetHelper : NSObject
00248 {
00249 @public
00250   aqua_tm_widget_rep *wid;
00251   NSToolbarItem *ti;
00252 }
00253 - (void)notify:(NSNotification*)obj;
00254 @end
00255 
00256 @implementation TMWidgetHelper
00257 -(void)dealloc
00258 {
00259   [ti release]; [super dealloc];
00260 }
00261 - (void)notify:(NSNotification*)n
00262 {
00263   wid->layout();
00264 }
00265 - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
00266 {
00267   if (itemIdentifier == TMButtonsIdentifier) {
00268     if (!ti) {
00269       ti = [[TMToolbarItem alloc] initWithItemIdentifier:TMButtonsIdentifier];
00270       [ti setView:[wid->bc bar]];
00271       NSRect f = [[wid->bc bar] frame];
00272       //      NSSize s = NSMakeSize(900,70);
00273       NSSize s = f.size;
00274       [ti setMinSize:s];
00275       [ti setMaxSize:s];
00276       
00277     }
00278     return ti;
00279   }
00280   return nil;
00281 }
00282 - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
00283 {
00284   return [NSArray arrayWithObjects:TMButtonsIdentifier,nil];
00285 }
00286 - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
00287 {
00288   return [NSArray arrayWithObjects:TMButtonsIdentifier,nil];
00289 }
00290 @end
00291 
00292 
00293 aqua_tm_widget_rep::aqua_tm_widget_rep(int mask) : aqua_view_widget_rep([[[NSView alloc] initWithFrame:NSMakeRect(0,0,100,100)] autorelease]), 
00294   sv(nil), leftField(nil), rightField(nil), bc(nil), toolbar(nil) 
00295 {
00296   // decode mask
00297   visibility[0] = (mask & 1)  == 1;  // header
00298   visibility[1] = (mask & 2)  == 2;  // main
00299   visibility[2] = (mask & 4)  == 4;  // context
00300   visibility[3] = (mask & 8)  == 8;  // user
00301   visibility[4] = (mask & 16) == 16; // footer
00302   
00303   
00304   NSSize s = NSMakeSize(100,20); // size of the right footer;
00305   NSRect r = [view bounds];
00306   NSRect r0 = r;
00307   //   r.size.height -= 100;
00308   //   r0.origin.y =+ r.size.height; r0.size.height = 100;
00309   NSRect r1 = r; r1.origin.y += s.height; r1.size.height -= s.height;
00310   NSRect r2 = r; r2.size.height = s.height;
00311   NSRect r3 = r2; 
00312   r2.size.width -= s.width; r3.origin.x =+ r2.size.width;
00313   sv = [[[NSScrollView alloc] initWithFrame:r1] autorelease];
00314   [sv setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
00315   [sv setHasVerticalScroller:YES];
00316   [sv setHasHorizontalScroller:YES];
00317   [sv setBorderType:NSNoBorder];
00318   //  [sv setBackgroundColor:[NSColor redColor]];
00319   [sv setBackgroundColor:[NSColor grayColor]];
00320   [sv setDocumentView:[[[NSView alloc] initWithFrame: NSMakeRect(0,0,100,100)] autorelease]];
00321   [view addSubview:sv];
00322   
00323   leftField = [[[NSTextField alloc] initWithFrame:r2] autorelease];
00324   rightField = [[[NSTextField alloc] initWithFrame:r3] autorelease];
00325   [leftField setAutoresizingMask:NSViewWidthSizable|NSViewMaxYMargin];
00326   [rightField setAutoresizingMask:NSViewMinXMargin|NSViewMaxYMargin];
00327   [leftField setEditable: NO];
00328   [rightField setEditable: NO];
00329   [leftField setBackgroundColor:[NSColor windowFrameColor]];
00330   [rightField setBackgroundColor:[NSColor windowFrameColor]];
00331   [leftField setBezeled:NO];
00332   [rightField setBezeled:NO];
00333   [rightField setAlignment:NSRightTextAlignment];
00334   [view addSubview:leftField];
00335   [view addSubview:rightField];
00336   
00337   bc = [[TMButtonsController alloc] init];
00338   //NSView *mt = [bc bar];
00339   //[mt setFrame:r0];
00340   //[mt setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin];
00341   //[view addSubview:mt];
00342   //   [mt setPostsFrameChangedNotifications:YES];
00343   wh = [[TMWidgetHelper alloc] init];
00344   wh->wid = this;
00345 #if 0
00346   [(NSNotificationCenter*)[NSNotificationCenter defaultCenter] addObserver:wh
00347                        selector:@selector(notify:)
00348                        name:NSViewFrameDidChangeNotification 
00349                        object:mt];
00350 #endif
00351        
00352   toolbar = [[NSToolbar alloc] initWithIdentifier:TMToolbarIdentifier ];
00353   [toolbar setDelegate:wh];
00354   
00355   updateVisibility();
00356   
00357 }
00358 
00359 aqua_tm_widget_rep::~aqua_tm_widget_rep() 
00360 { 
00361   //   [(NSNotificationCenter*)[NSNotificationCenter defaultCenter] removeObserver:wh];
00362   [wh release];      
00363   [bc release]; 
00364 }
00365 
00366 
00367 void aqua_tm_widget_rep::layout()
00368 {
00369   NSSize s = NSMakeSize(100,20); // size of the right footer;
00370   NSRect r = [view bounds];
00371   NSRect r0 = r;
00372   //   NSRect rh = [[bc bar] frame];
00373   NSRect rh = NSMakeRect(0,0,0,0);
00374   r.size.height -= rh.size.height;
00375   r0.origin.y =+ r.size.height; r0.size.height = rh.size.height;
00376   NSRect r1 = r; r1.origin.y += s.height; r1.size.height -= s.height;
00377   NSRect r2 = r; r2.size.height = s.height;
00378   NSRect r3 = r2; 
00379   r2.size.width -= s.width; r3.origin.x =+ r2.size.width;
00380   r3.size.width -= r2.size.width + 15.0;
00381   [sv setFrame:r1];
00382   [leftField setFrame:r2];
00383   [rightField setFrame:r3];
00384   //[[bc bar] setFrame:r0];
00385   [NSApp setWindowsNeedUpdate:YES];
00386 }
00387 
00388 
00389 void aqua_tm_widget_rep::updateVisibility()
00390 {
00391   //FIXME: this implementation is from the Qt port. to be adapted.
00392 #if 0
00393   mainToolBar->setVisible (visibility[1] && visibility[0]);
00394   contextToolBar->setVisible (visibility[2] && visibility[0]);
00395   userToolBar->setVisible (visibility[3] && visibility[0]);
00396   tm_mainwindow()->statusBar()->setVisible (visibility[4]);
00397 #ifndef Q_WS_MAC
00398   tm_mainwindow()->menuBar()->setVisible (visibility[0]);
00399 #endif
00400 #endif
00401 }
00402 
00403 
00404 
00405 void
00406 aqua_tm_widget_rep::send (slot s, blackbox val) {
00407   switch (s) {
00408   case SLOT_EXTENTS:
00409     {
00410       TYPE_CHECK (type_box (val) == type_helper<coord4>::id);
00411       coord4 p= open_box<coord4> (val);
00412       NSRect rect = to_nsrect(p);
00413       NSSize ws = [sv contentSize];
00414       NSSize sz = rect.size;
00415       sz.height = max (sz.height, ws.height );
00416       //                    [[view window] setContentSize:rect.size];
00417       [[sv documentView] setFrameSize: sz];
00418     }
00419     break;
00420   case SLOT_HEADER_VISIBILITY:
00421     {
00422       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00423       bool f= open_box<bool> (val);
00424       visibility[0] = f;
00425       updateVisibility();
00426     }
00427     break;
00428   case SLOT_MAIN_ICONS_VISIBILITY:
00429     {
00430       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00431       bool f= open_box<bool> (val);
00432       visibility[1] = f;
00433       updateVisibility();
00434     }
00435     break;
00436   case SLOT_MODE_ICONS_VISIBILITY:
00437     {
00438       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00439       bool f= open_box<bool> (val);
00440       visibility[2] = f;
00441       updateVisibility();
00442     }
00443     break;
00444   case SLOT_USER_ICONS_VISIBILITY:
00445     {
00446       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00447       bool f= open_box<bool> (val);
00448       visibility[3] = f;
00449       updateVisibility();
00450     }
00451     break;
00452   case SLOT_FOOTER_VISIBILITY:
00453     {
00454       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00455       bool f= open_box<bool> (val);
00456       visibility[4] = f;
00457       updateVisibility();
00458     }
00459     break;
00460     
00461   case SLOT_LEFT_FOOTER:
00462     {
00463       TYPE_CHECK (type_box (val) == type_helper<string>::id);
00464       string msg = open_box<string> (val);
00465       [leftField setStringValue:to_nsstring_utf8 (tm_var_encode (msg))];
00466       [leftField displayIfNeeded];
00467     }
00468     break;
00469   case SLOT_RIGHT_FOOTER:
00470     {
00471       TYPE_CHECK (type_box (val) == type_helper<string>::id);
00472       string msg = open_box<string> (val);
00473       [rightField setStringValue:to_nsstring_utf8 (tm_var_encode (msg))];
00474       [rightField displayIfNeeded];
00475     }
00476     break;
00477     
00478   case SLOT_SCROLL_POSITION:
00479     {
00480       TYPE_CHECK (type_box (val) == type_helper<coord2>::id);
00481       coord2 p= open_box<coord2> (val);
00482       NSPoint pt = to_nspoint(p);
00483       NSSize sz = [[sv contentView] bounds].size;
00484       if (DEBUG_EVENTS) cout << "Scroll position :" << pt.x << "," << pt.y << LF;
00485       [[sv documentView] scrollPoint:pt];
00486  //     [[sv documentView] scrollRectToVisible:NSMakeRect(pt.x,pt.y,1.0,1.0)];
00487     }
00488     break;
00489     
00490   case SLOT_SCROLLBARS_VISIBILITY:
00491     // ignore this: cocoa handles scrollbars independently
00492     //               send_int (THIS, "scrollbars", val);
00493     break;
00494     
00495   case SLOT_INTERACTIVE_MODE:
00496     {
00497       TYPE_CHECK (type_box (val) == type_helper<bool>::id);
00498       if (open_box<bool>(val) == true) {
00499         //FIXME: to postpone once we return to the runloop
00500            do_interactive_prompt();
00501       }
00502     }
00503     break;
00504     
00505   case SLOT_SHRINKING_FACTOR:
00506     {
00507       TYPE_CHECK (type_box (val) == type_helper<int>::id);
00508       simple_widget_rep *w = (simple_widget_rep *)[(TMView*)[sv documentView] widget];
00509       if (w) {
00510         int new_sf = open_box<int> (val);
00511         if (DEBUG_EVENTS) cout << "New shrinking factor :" << new_sf << LF;
00512         w->handle_set_shrinking_factor (new_sf);
00513       }
00514       break;
00515     }
00516 
00517   case SLOT_FILE:
00518     {
00519       TYPE_CHECK (type_box (val) == type_helper<string>::id);
00520       string file = open_box<string> (val);
00521       if (DEBUG_EVENTS) cout << "File: " << file << LF;
00522 //      view->window()->setWindowFilePath(to_qstring(file));
00523     }
00524       break;
00525       
00526       
00527   default:
00528     aqua_view_widget_rep::send(s,val);
00529   }
00530 }
00531 
00532 blackbox
00533 aqua_tm_widget_rep::query (slot s, int type_id) {
00534   switch (s) {
00535   case SLOT_SCROLL_POSITION:
00536     {
00537       TYPE_CHECK (type_id == type_helper<coord2>::id);
00538       NSPoint pt = [[sv documentView] frame].origin;
00539       if (DEBUG_EVENTS)
00540         cout << "Position (" << pt.x << "," << pt.y << ")\n"; 
00541       return close_box<coord2> (from_nspoint(pt));
00542     }
00543         
00544   case SLOT_EXTENTS:
00545     {
00546       TYPE_CHECK (type_id == type_helper<coord4>::id);
00547       NSRect rect= [[sv documentView] frame];
00548       coord4 c= from_nsrect (rect);
00549       if (DEBUG_EVENTS) cout << "Canvas geometry (" << rect.origin.x 
00550         << "," << rect.origin.y
00551         << "," << rect.size.width
00552         << "," << rect.size.height
00553         << ")" << LF;
00554       return close_box<coord4> (c);
00555     }
00556         
00557         
00558   case SLOT_VISIBLE_PART:
00559     {
00560       TYPE_CHECK (type_id == type_helper<coord4>::id);
00561       NSRect rect= [sv documentVisibleRect];
00562       coord4 c= from_nsrect (rect);
00563       if (DEBUG_EVENTS) cout << "Visible region (" << rect.origin.x 
00564         << "," << rect.origin.y
00565         << "," << rect.size.width
00566         << "," << rect.size.height
00567         << ")" << LF;
00568       return close_box<coord4> (c);
00569     }
00570 
00571         
00572   case SLOT_USER_ICONS_VISIBILITY:
00573     TYPE_CHECK (type_id == type_helper<bool>::id);
00574     return close_box<bool> (visibility[3]);
00575         
00576   case SLOT_MODE_ICONS_VISIBILITY:
00577     TYPE_CHECK (type_id == type_helper<bool>::id);
00578     return close_box<bool> (visibility[2]);
00579     
00580   case SLOT_MAIN_ICONS_VISIBILITY:
00581     TYPE_CHECK (type_id == type_helper<bool>::id);
00582     return close_box<bool> (visibility[1]);
00583     
00584   case SLOT_HEADER_VISIBILITY:
00585     TYPE_CHECK (type_id == type_helper<bool>::id);
00586     return close_box<bool> (visibility[0]);
00587     
00588   case SLOT_FOOTER_VISIBILITY:
00589     TYPE_CHECK (type_id == type_helper<bool>::id);
00590     return close_box<bool> (visibility[4]);
00591     
00592   case SLOT_INTERACTIVE_INPUT:
00593     {
00594       TYPE_CHECK (type_id == type_helper<string>::id);
00595       return close_box<string> ( ((aqua_input_text_widget_rep*) int_input.rep)->text );
00596       
00597     }
00598   case SLOT_INTERACTIVE_MODE:
00599     {
00600       TYPE_CHECK (type_id == type_helper<bool>::id);
00601       return close_box<bool> (false);  // FIXME: who needs this info?
00602     }
00603     
00604     
00605   default:
00606     return aqua_view_widget_rep::query(s,type_id);
00607   }
00608 }
00609 
00610 widget
00611 aqua_tm_widget_rep::read (slot s, blackbox index) {
00612   switch (s) {
00613   default:
00614     return aqua_view_widget_rep::read(s,index);
00615   }
00616 }
00617 
00618 
00619 
00620 @interface TMMenuHelper : NSObject
00621 {
00622 @public
00623   NSMenuItem *mi;
00624   NSMenu *menu;
00625 }
00626 + (TMMenuHelper *)sharedHelper;
00627 - init;
00628 - (void)setMenu:(NSMenu *)_mi;
00629 @end
00630 
00631 TMMenuHelper *the_menu_helper = nil;
00632 
00633 @implementation TMMenuHelper
00634 - init { 
00635   [super init]; mi = nil; menu = nil; 
00636   
00637   mi = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Menu" action:NULL keyEquivalent:@""];
00638   NSMenu *sm = [[[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Menu"] autorelease];
00639   [mi  setSubmenu:sm];
00640   //[[NSApp mainMenu] removeItem: [[NSApp mainMenu] itemWithTitle:@"Help"]]; //FIXME: Help menu causes problems (crash)
00641   
00642   [[NSApp mainMenu] insertItem: mi atIndex:1];   
00643   //   [sm setDelegate: self];
00644   
00645   return self; 
00646 }
00647 - (void)setMenu:(NSMenu *)_m  
00648 { 
00649   if (menu) [menu release];  menu = _m; [menu retain];
00650   [mi  setSubmenu:menu];
00651   [menu setTitle:@"Menu"];  
00652 };
00653 - (void)dealloc { [mi release]; [menu release]; [super dealloc]; }
00654 + (TMMenuHelper *)sharedHelper 
00655 { 
00656   if (!the_menu_helper) 
00657     {
00658       the_menu_helper = [[TMMenuHelper alloc] init];
00659     }
00660   return the_menu_helper; 
00661 }
00662 
00663 #if 0
00664 - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(int)index shouldCancel:(BOOL)shouldCancel
00665 {
00666   return NO;
00667 }
00668 #endif
00669 @end
00670 
00671 
00672 
00673 
00674 void
00675 aqua_tm_widget_rep::write (slot s, blackbox index, widget w) {
00676   switch (s) {
00677   case SLOT_SCROLLABLE: 
00678     {
00679       check_type_void (index, "SLOT_SCROLLABLE");
00680       NSView *v = ((aqua_view_widget_rep*) w.rep)->view;
00681       [sv setDocumentView: v];
00682       [[sv window] makeFirstResponder:v];
00683     }
00684     break;
00685   case SLOT_MAIN_MENU:
00686     check_type_void (index, "SLOT_MAIN_MENU");
00687     [[TMMenuHelper sharedHelper] setMenu:to_nsmenu(w)];
00688     break;
00689   case SLOT_MAIN_ICONS:
00690     check_type_void (index, "SLOT_MAIN_ICONS");
00691     [bc setMenu:to_nsmenu(w) forRow:0];
00692     layout();
00693     break;
00694   case SLOT_MODE_ICONS:
00695     check_type_void (index, "SLOT_MODE_ICONS");
00696     [bc setMenu:to_nsmenu(w) forRow:1];
00697     layout();
00698     break;
00699   case SLOT_FOCUS_ICONS:
00700     check_type_void (index, "SLOT_FOCUS_ICONS");
00701     [bc setMenu:to_nsmenu(w) forRow:2];
00702     layout();
00703     break;
00704   case SLOT_USER_ICONS:
00705     check_type_void (index, "SLOT_USER_ICONS");
00706     [bc setMenu:to_nsmenu(w) forRow:3];
00707     layout();
00708     break;
00709   case SLOT_INTERACTIVE_PROMPT:
00710     check_type_void (index, "SLOT_INTERACTIVE_PROMPT");
00711     int_prompt = concrete(w); 
00712     //               THIS << set_widget ("interactive prompt", concrete (w));
00713     break;
00714   case SLOT_INTERACTIVE_INPUT:
00715     check_type_void (index, "SLOT_INTERACTIVE_INPUT");
00716     int_input = concrete(w);
00717     //               THIS << set_widget ("interactive input", concrete (w));
00718     break;
00719   default:
00720     aqua_view_widget_rep::write(s,index,w);
00721   }
00722 }
00723 
00724 widget
00725 aqua_tm_widget_rep::plain_window_widget (string s) {
00726   // creates a decorated window with name s and contents w
00727   widget w = aqua_view_widget_rep::plain_window_widget(s);
00728   // to manage correctly retain counts
00729   aqua_window_widget_rep * wid = (aqua_window_widget_rep *)(w.rep);
00730   [[wid->get_windowcontroller() window] setToolbar:toolbar];
00731   return wid;
00732 }
00733 
00734 
00735 
00736 #pragma mark aqua_window_widget_rep
00737 
00738 
00739 
00740 @implementation TMWindowController
00741 - (void)setWidget:(widget_rep*) w
00742 {
00743   wid = (aqua_window_widget_rep*)w;
00744 }
00745 
00746 - (widget_rep*)widget
00747 {
00748   return (aqua_widget_rep*)wid;
00749 }
00750 
00751 @end
00752 
00753 aqua_window_widget_rep::aqua_window_widget_rep(NSWindow *win) 
00754 : widget_rep(), wc([[[TMWindowController alloc] initWithWindow:win] autorelease]) 
00755 { [wc retain]; [wc setWidget:this]; }
00756 
00757 aqua_window_widget_rep::~aqua_window_widget_rep()  { [wc release]; }
00758 
00759 TMWindowController *aqua_window_widget_rep::get_windowcontroller() { return wc; }
00760 
00761 
00762 
00763 void
00764 aqua_window_widget_rep::send (slot s, blackbox val) {
00765   switch (s) {
00766   case SLOT_SIZE:
00767     {
00768       TYPE_CHECK (type_box (val) == type_helper<coord2>::id);
00769       coord2 p= open_box<coord2> (val);
00770       NSWindow *win = [wc window];
00771       if (win) {
00772         NSSize size = to_nssize(p);
00773         [win setContentSize:size];
00774       }
00775     }
00776     break;
00777   case SLOT_POSITION:
00778     {
00779       TYPE_CHECK (type_box (val) == type_helper<coord2>::id);
00780       coord2 p= open_box<coord2> (val);
00781       NSWindow *win = [wc window];
00782       if (win) { 
00783         [win setFrameOrigin:to_nspoint(p)];
00784       }
00785     }
00786     break;
00787   case SLOT_VISIBILITY:
00788     {  
00789       check_type<bool> (val, "SLOT_VISIBILITY");
00790       bool flag = open_box<bool> (val);
00791       NSWindow *win = [wc window];
00792       if (win) {
00793         if (flag) [win makeKeyAndOrderFront:nil] ;
00794         else [win orderOut:nil]  ;
00795       }
00796     }  
00797     break;
00798   case SLOT_NAME:
00799     {  
00800       check_type<string> (val, "SLOT_NAME");
00801       string name = open_box<string> (val);
00802       NSWindow *win = [wc window];
00803       if (win) {
00804         NSString *title = to_nsstring(name);
00805         [win setTitle:title];
00806       }
00807     }
00808     break;
00809   case SLOT_FULL_SCREEN:
00810     check_type<bool> (val, "SLOT_FULL_SCREEN");
00811     //FIXME: Implement fullscreen mode
00812     // win->set_full_screen (open_box<bool> (val));
00813     break;
00814   case SLOT_UPDATE:
00815     NOT_IMPLEMENTED ;
00816     // send_update (THIS, val);
00817     break;
00818   case SLOT_REFRESH:
00819     NOT_IMPLEMENTED ;
00820     // send_refresh (THIS, val);
00821     break;
00822     
00823   default:
00824     FAILED ("cannot handle slot type");
00825   }
00826 }
00827 
00828 
00829 blackbox
00830 aqua_window_widget_rep::query (slot s, int type_id) {
00831   switch (s) {
00832   case SLOT_IDENTIFIER:
00833     TYPE_CHECK (type_id == type_helper<int>::id);
00834     return close_box<int> ((intptr_t) [wc window] ? 1 : 0);
00835   case SLOT_POSITION:  
00836     {
00837       typedef pair<SI,SI> coord2;
00838       TYPE_CHECK (type_id == type_helper<coord2>::id);
00839       NSRect frame = [[wc window] frame];
00840       return close_box<coord2> (from_nspoint(frame.origin));
00841     }
00842   case SLOT_SIZE:
00843     {
00844       typedef pair<SI,SI> coord2;
00845       TYPE_CHECK (type_id == type_helper<coord2>::id);
00846       NSRect frame = [[wc window] frame];
00847       return close_box<coord2> (from_nssize(frame.size));
00848     }
00849   default:
00850     FAILED ("cannot handle slot type");
00851     return blackbox ();
00852   }
00853 }
00854 
00855 /******************************************************************************
00856  * Notification of state changes
00857  ******************************************************************************/
00858 
00859 void
00860 aqua_window_widget_rep::notify (slot s, blackbox new_val) {
00861   widget_rep::notify (s, new_val);
00862 }
00863 
00864 widget
00865 aqua_window_widget_rep::read (slot s, blackbox index) {
00866   switch (s) {
00867   default:
00868     FAILED ("cannot handle slot type");
00869     return widget();
00870   }
00871 }
00872 
00873 void
00874 aqua_window_widget_rep::write (slot s, blackbox index, widget w) {
00875   switch (s) {
00876   default:
00877     FAILED ("cannot handle slot type");
00878   }
00879 }
00880 
00881 
00882 /******************************************************************************
00883 * simple_widget_rep
00884 ******************************************************************************/
00885 #pragma mark simple_widget_rep
00886 
00887 /******************************************************************************
00888 * Constructor
00889 ******************************************************************************/
00890 
00891 simple_widget_rep::simple_widget_rep ()
00892 : aqua_view_widget_rep ([[[TMView alloc] initWithFrame:NSMakeRect(0,0,1000,1000)] autorelease]) 
00893 { 
00894   [(TMView*)view setWidget:this];
00895 }
00896 
00897 
00898 /******************************************************************************
00899 * Empty handlers for redefinition later on
00900 ******************************************************************************/
00901 
00902 void
00903 simple_widget_rep::handle_get_size_hint (SI& w, SI& h) {
00904   gui_root_extents (w, h);  
00905 }
00906 
00907 void
00908 simple_widget_rep::handle_notify_resize (SI w, SI h) {
00909   (void) w; (void) h; 
00910 }
00911 
00912 void
00913 simple_widget_rep::handle_keypress (string key, time_t t) {
00914   (void) key; (void) t;
00915 }
00916 
00917 void
00918 simple_widget_rep::handle_keyboard_focus (bool has_focus, time_t t) {
00919   (void) has_focus; (void) t;
00920 }
00921 
00922 void
00923 simple_widget_rep::handle_mouse (string kind, SI x, SI y, int mods, time_t t) {
00924   (void) kind; (void) x; (void) y; (void) mods; (void) t;
00925 }
00926 
00927 void
00928 simple_widget_rep::handle_set_shrinking_factor (int sf) {
00929   (void) sf;
00930 }
00931 
00932 void
00933 simple_widget_rep::handle_clear (SI x1, SI y1, SI x2, SI y2) {
00934   (void) x1; (void) y1; (void) x2; (void) y2;
00935 }
00936 
00937 void
00938 simple_widget_rep::handle_repaint (SI x1, SI y1, SI x2, SI y2) {
00939   (void) x1; (void) y1; (void) x2; (void) y2;
00940 }
00941 
00942 
00943 void
00944 simple_widget_rep::send (slot s, blackbox val) {
00945   if (DEBUG_QT) cout << "aqua_simple_widget_rep::send " << slot_name(s) << LF;
00946   switch (s) {
00947     case SLOT_INVALIDATE:
00948     {
00949       TYPE_CHECK (type_box (val) == type_helper<coord4>::id);
00950       coord4 p= open_box<coord4> (val);
00951       if (DEBUG_QT)
00952         cout << "Invalidating rect " << rectangle(p.x1,p.x2,p.x3,p.x4) << LF;
00953       aqua_renderer_rep* ren = (aqua_renderer_rep*)get_renderer (this);
00954       if (ren) {
00955         SI x1 = p.x1, y1 = p.x2, x2 = p.x3, y2 = p.x4;    
00956         ren->outer_round (x1, y1, x2, y2);
00957         ren->decode (x1, y1);
00958         ren->decode (x2, y2);
00959         //tm_canvas()->invalidate_rect (x1,y2,x2,y1);
00960       }
00961     }
00962       break;
00963     case SLOT_INVALIDATE_ALL:
00964     {
00965       ASSERT (is_nil (val), "type mismatch");
00966       if (DEBUG_QT)
00967         cout << "Invalidating all"<<  LF;
00968       //tm_canvas()->invalidate_all ();
00969     }
00970       break;
00971     case SLOT_CURSOR:
00972     {
00973       TYPE_CHECK (type_box (val) == type_helper<coord2>::id);
00974       coord2 p= open_box<coord2> (val);
00975       //QPoint pt = to_qpoint(p);
00976       //tm_canvas() -> setCursorPos(pt);
00977     }
00978       break;
00979       
00980     default:
00981       if (DEBUG_QT) cout << "[aqua_simple_widget_rep] ";
00982       aqua_view_widget_rep::send (s, val);
00983       //      FAILED ("unhandled slot type");
00984   }
00985   
00986 }
00987 
00988 
00989 
00990 blackbox
00991 simple_widget_rep::query (slot s, int type_id) {
00992   return aqua_view_widget_rep::query(s,type_id);
00993 }
00994 
00995 void
00996 simple_widget_rep::notify (slot s, blackbox new_val) {
00997   aqua_view_widget_rep::notify (s, new_val);
00998 }
00999 
01000 /******************************************************************************
01001  * Read and write access of subwidgets
01002  ******************************************************************************/
01003 
01004 widget
01005 simple_widget_rep::read (slot s, blackbox index) {
01006   return aqua_view_widget_rep::read(s,index);
01007 }
01008 
01009 void
01010 simple_widget_rep::write (slot s, blackbox index, widget w) {
01011   aqua_view_widget_rep::write(s,index,w);
01012 }
01013 
01014 
01015 
01016 
01017 /******************************************************************************
01018 * Window widgets
01019 ******************************************************************************/
01020 
01021 #pragma mark Widget interface
01022 
01023 
01024 widget plain_window_widget (widget w, string s) 
01025 // creates a decorated window with name s and contents w
01026 {
01027   return concrete(w)->plain_window_widget(s);
01028 }
01029 
01030 widget popup_window_widget (widget w, string s) 
01031 // creates an undecorated window with name s and contents w
01032 {
01033   return concrete(w)->popup_window_widget(s);
01034 }
01035 
01036 void   destroy_window_widget (widget w) {  
01037 // destroys a window as created by the above routines
01038   (void) w;
01039 }
01040 
01041 /******************************************************************************
01042  * Top-level widgets, typically given as an argument to plain_window_widget
01043  * See also message.hpp for specific messages for these widgets
01044  ******************************************************************************/
01045 
01046 widget texmacs_widget (int mask, command quit) 
01047 // the main TeXmacs widget and a command which is called on exit
01048 // the mask variable indicates whether the menu, icon bars, status bar, etc.
01049 // are visible or not
01050 {
01051   (void) mask; (void) quit; // FIXME: handle correctly mask and quit
01052 
01053   widget w = tm_new <aqua_tm_widget_rep> (mask);
01054   return w; 
01055 }
01056 
01057 
01058 
01059 
01060 
01061 widget popup_widget (widget w) 
01062 // a widget container which results w to be unmapped as soon as
01063 // the pointer quits the widget
01064 // used in edit_mouse.cpp to implement a contextual menu in the canvas
01065 {
01066   return concrete(w)->make_popup_widget();
01067 }
01068 
01069 
01070 /******************************************************************************
01071  *  Widgets which are not strictly required by TeXmacs
01072  *  their implementation is void
01073  ******************************************************************************/
01074 
01075 widget
01076 empty_widget () {
01077   // an empty widget of size zero
01078   NOT_IMPLEMENTED;
01079   return widget();
01080 }
01081 
01082 widget
01083 glue_widget (bool hx, bool vx, SI w, SI h) {
01084   //{ return widget(); }
01085   // an empty widget of minimal width w and height h and which is horizontally
01086   // resp. vertically extensible if hx resp. vx is true
01087   NOT_IMPLEMENTED;
01088   (void) hx; (void) vx; (void) w; (void) h;
01089   return tm_new <aqua_view_widget_rep> ([[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 50, 50)] autorelease]);
01090 }
01091 
01092 widget
01093 glue_widget (tree col, bool hx, bool vx, SI w, SI h) {
01094   (void) col;
01095   return glue_widget (hx, vx, w, h);
01096 }
01097 
01098 widget
01099 extend (widget w, array<widget> a) {
01100   (void) a;
01101   return w;
01102 }
01103 
01104 widget
01105 wait_widget (SI width, SI height, string message) { 
01106   // a widget of a specified width and height, displaying a wait message
01107   // this widget is only needed when using the X11 plugin
01108   (void) width; (void) height; (void) message;
01109   return widget(); 
01110 }