SF.net SVN: supercollider: [7687] trunk

View: New views
1 Messages — Rating Filter:   Alert me  

SF.net SVN: supercollider: [7687] trunk

by mullmusik :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Revision: 7687
          http://supercollider.svn.sourceforge.net/supercollider/?rev=7687&view=rev
Author:   mullmusik
Date:     2008-07-15 12:00:51 -0700 (Tue, 15 Jul 2008)

Log Message:
-----------
Customised menus initial commit

Modified Paths:
--------------
    trunk/Headers/app/SCCocoaView.h
    trunk/Source/app/GUIPrimitives.M
    trunk/Source/app/SCCocoaView.M
    trunk/build/SCClassLibrary/Platform/osx/OSXPlatform.sc

Added Paths:
-----------
    trunk/build/SCClassLibrary/Platform/osx/CocoaMenu.sc

Modified: trunk/Headers/app/SCCocoaView.h
===================================================================
--- trunk/Headers/app/SCCocoaView.h 2008-07-15 15:34:44 UTC (rev 7686)
+++ trunk/Headers/app/SCCocoaView.h 2008-07-15 19:00:51 UTC (rev 7687)
@@ -60,6 +60,16 @@
 
 @end
 
+@interface SCNSMenuItem : NSMenuItem {
+ struct PyrObject *mMenuItemObj;
+}
+
+- (void)setSCObject: (struct PyrObject*)inObject;
+- (struct PyrObject*)getSCObject;
+- (void)doAction: (id)sender;
+
+@end
+
 class SCCocoaTextView : public SCView
 {
 public:

Modified: trunk/Source/app/GUIPrimitives.M
===================================================================
--- trunk/Source/app/GUIPrimitives.M 2008-07-15 15:34:44 UTC (rev 7686)
+++ trunk/Source/app/GUIPrimitives.M 2008-07-15 19:00:51 UTC (rev 7687)
@@ -32,6 +32,7 @@
 #import "GC.h"
 #import "SCTextView.h"
 #import "SCNSWindow.h"
+#import "SCCocoaView.h"
 
 extern ChangeCounter gUIChangeCounter;
 extern NSTextView* gPostView;
@@ -2944,8 +2945,158 @@
  r.bottom = finfo.descent;
 }
 
+int prNewMenuItem(struct VMGlobals *g, int numArgsPushed);
+int prNewMenuItem(struct VMGlobals *g, int numArgsPushed)
+{
+ if (!g->canCallOS) return errCantCallOS;
+
+ PyrSlot *caller = g->sp - 4; // the SC Object
+ PyrSlot *parentObj = g->sp - 3; // the parent menu or nil for app menu
+ PyrSlot *ind = g->sp - 2; // the index
+ PyrSlot *stringSlot = g->sp - 1; // name of the menu item
+ PyrSlot *submenbool = g->sp; // submenu bool
+
+ int menIndex, err;
+
+ err = slotIntVal(ind, &menIndex);
+ if (err) return err;
+
+ //NSLog(@"menIndex: %i", menIndex);
+
+ if (!(isKindOfSlot(stringSlot, class_string))) return errWrongType;
+
+ PyrString* string = stringSlot->uos;
+
+ NSString *label = [[NSString alloc] initWithCString: string->s length: string->size];
+
+ //NSLog(@"Label: %@", label);
+ // make a menu item
+ SCNSMenuItem *menuItem = [[SCNSMenuItem alloc] initWithTitle:label action:@selector(doAction:) keyEquivalent:@""];
+ [menuItem setTarget:menuItem];
+ [menuItem setSCObject: caller->uo];
+ SetPtr(caller->uo->slots + 0, menuItem); // set the dataptr
+
+ if (IsTrue(submenbool)) {
+ // make a submenu if needed
+ //NSLog(@"Is SubMenu");
+ [menuItem setSubmenu:[[NSMenu alloc] initWithTitle:label]];
+ [[menuItem submenu] setAutoenablesItems:NO];
+ }
+
+ NSMenu *parentMenu;
+ if (IsNil(parentObj)) {
+ // make a submenu if needed
+ //NSLog(@"Top Level");
+ parentMenu = [NSApp mainMenu];
+ } else {
+ SCNSMenuItem *parentItem = (SCNSMenuItem*)(parentObj->uo->slots->uptr);
+ if([parentItem hasSubmenu]) {
+ //NSLog(@"Parent has submenu");
+ parentMenu = [parentItem submenu];
+ } else {
+ return errFailed;
+ }
+ }
+
+ // protect against bad indices
+ int parentSize = [parentMenu numberOfItems];
+ //NSLog(@"parentSize: %i", parentSize);
+ if(menIndex > parentSize) {
+ //NSLog(@"Index > parentSize");
+ menIndex = parentSize;
+ }
+ if(menIndex < 0) {
+ //NSLog(@"Index < 0");
+ menIndex = 0;
+ }
+ //NSLog(@"Final Index: %i", menIndex);
+
+ [parentMenu insertItem:menuItem atIndex:menIndex];
+ if([menuItem hasSubmenu]) { [[menuItem submenu] release]; } // this has been retained
+ [label release];
+ return errNone;
+}
 
+int prRemoveMenuItem(struct VMGlobals *g, int numArgsPushed);
+int prRemoveMenuItem(struct VMGlobals *g, int numArgsPushed)
+{
+ PyrSlot *caller = g->sp;
+
+ SCNSMenuItem *menuItem = (SCNSMenuItem*)(caller->uo->slots->uptr);
+ if(!menuItem) return errFailed;
+ [[menuItem menu] removeItem:menuItem];
+ SetNil(caller->uo->slots); // we're now a lame duck
+ //if([menuItem hasSubmenu]) { [[menuItem submenu] release] };
+ [menuItem release];
+ return errNone;
+}
 
+int prEnableMenuItem(struct VMGlobals *g, int numArgsPushed);
+int prEnableMenuItem(struct VMGlobals *g, int numArgsPushed)
+{
+ PyrSlot *caller = g->sp - 1;
+ PyrSlot *boolean = g->sp;
+
+ SCNSMenuItem *menuItem = (SCNSMenuItem*)(caller->uo->slots->uptr);
+ if(!menuItem) return errFailed;
+ if(IsTrue(boolean)) {
+ [menuItem setEnabled:YES];
+ } else {
+ [menuItem setEnabled:NO];
+ }
+ return errNone;
+}
+
+int prSetMenuItemState(struct VMGlobals *g, int numArgsPushed);
+int prSetMenuItemState(struct VMGlobals *g, int numArgsPushed)
+{
+ PyrSlot *caller = g->sp - 1;
+ PyrSlot *boolean = g->sp;
+
+ SCNSMenuItem *menuItem = (SCNSMenuItem*)(caller->uo->slots->uptr);
+ if(!menuItem) return errFailed;
+ if(IsTrue(boolean)) {
+ [menuItem setState:NSOnState];
+ } else {
+ [menuItem setState:NSOffState];
+ }
+ return errNone;
+}
+
+int prSetMenuItemKeyboardEquivalent(struct VMGlobals *g, int numArgsPushed);
+int prSetMenuItemKeyboardEquivalent(struct VMGlobals *g, int numArgsPushed)
+{
+ PyrSlot *caller = g->sp - 3;
+ PyrSlot *stringSlot = g->sp - 2;
+ PyrSlot *alt = g->sp - 1;
+ PyrSlot *ctrl = g->sp;
+
+ SCNSMenuItem *menuItem = (SCNSMenuItem*)(caller->uo->slots->uptr);
+ if(!menuItem) return errFailed;
+
+ if (!(isKindOfSlot(stringSlot, class_string))) return errWrongType;
+
+ PyrString* string = stringSlot->uos;
+
+ NSString *kbEquiv = [[NSString alloc] initWithCString: string->s length: string->size];
+
+ [menuItem setKeyEquivalent:kbEquiv];
+
+ int mod = NSCommandKeyMask;
+ if(IsTrue(alt)) {
+ mod = mod | NSAlternateKeyMask;
+ }
+
+ if(IsTrue(ctrl)) {
+ mod = mod | NSControlKeyMask;
+ }
+
+ [menuItem setKeyEquivalentModifierMask:mod];
+
+ [kbEquiv release];
+ return errNone;
+}
+
 void initGUIPrimitives()
 {
  int base, index;
@@ -3086,5 +3237,11 @@
 
  definePrimitive(base, index++, "_TextWindow_LinkAtClickPos", prTextWindow_LinkAtClickPos, 2, 0);
  definePrimitive(base, index++, "_Pen_SetSmoothing", prPen_SetSmoothing, 2, 0);
+
+ definePrimitive(base, index++, "_NewMenuItem", prNewMenuItem, 5, 0);
+ definePrimitive(base, index++, "_RemoveMenuItem", prRemoveMenuItem, 1, 0);
+ definePrimitive(base, index++, "_EnableMenuItem", prEnableMenuItem, 2, 0);
+ definePrimitive(base, index++, "_SetMenuItemState", prSetMenuItemState, 2, 0);
+ definePrimitive(base, index++, "_SetMenuItemKeyboardEquivalent", prSetMenuItemKeyboardEquivalent, 4, 0);
 }
 

Modified: trunk/Source/app/SCCocoaView.M
===================================================================
--- trunk/Source/app/SCCocoaView.M 2008-07-15 15:34:44 UTC (rev 7686)
+++ trunk/Source/app/SCCocoaView.M 2008-07-15 19:00:51 UTC (rev 7687)
@@ -222,6 +222,37 @@
 
 @end
 
+@implementation SCNSMenuItem
+
+- (void)setSCObject: (struct PyrObject*)inObject
+{
+    mMenuItemObj = inObject;
+}
+
+- (struct PyrObject*)getSCObject
+{
+    return mMenuItemObj;
+}
+
+- (void)doAction: (id)sender
+{
+ // post("doAction \n");
+    pthread_mutex_lock (&gLangMutex);
+ PyrObject * pobj = [self getSCObject];
+ if(compiledOK && pobj){
+ PyrSymbol *method = getsym("doAction");
+ VMGlobals *g = gMainVMGlobals;
+ g->canCallOS = true;
+ ++g->sp;  SetObject(g->sp, pobj);
+ ++g->sp;  SetInt(g->sp, 1);
+ runInterpreter(g, method, 2);
+ g->canCallOS = false;
+ }
+    pthread_mutex_unlock (&gLangMutex);
+}
+
+@end
+
 NSRect SCtoNSRect(SCRect screct);
 
 SCView* NewSCCocoaTextView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds)

Added: trunk/build/SCClassLibrary/Platform/osx/CocoaMenu.sc
===================================================================
--- trunk/build/SCClassLibrary/Platform/osx/CocoaMenu.sc                        (rev 0)
+++ trunk/build/SCClassLibrary/Platform/osx/CocoaMenu.sc 2008-07-15 19:00:51 UTC (rev 7687)
@@ -0,0 +1,71 @@
+CocoaMenuItem {
+ classvar topLevelItems;
+
+ var dataptr;
+ var name;
+ var parent; // nil = top level
+ var <>action;
+ var children;
+ var <state = false;
+
+ *new { |parent, index, name = "", submenu = false, action|
+ ^super.new.init(parent, index, name, submenu, action);
+ }
+
+ *clearCustomItems {
+ topLevelItems.do({|item| item.remove });
+ }
+
+ init { |argparent, argindex, argname, submenu, argaction|
+
+ parent = argparent;
+ name = argname;
+ action = argaction;
+ parent.notNil.if({parent.addChild(this)}, {topLevelItems = topLevelItems.add(this);});
+ this.prAddMenuItem(argparent, argindex, argname, submenu);
+ }
+
+ remove {
+ children.do({|child| child.remove}); // cleanup my kids
+ children = nil;
+ this.prRemoveMenuItem;
+ }
+
+ addChild {|child|
+ children = children.add(child);
+ }
+
+ enabled_ {|bool|
+ _EnableMenuItem
+ ^this.primitiveFailed;
+ }
+
+ state_ {|bool|
+ state = bool;
+ this.prSetState(bool);
+ }
+
+ // Cmd is assumed
+ setShortCut {|string, alt = false, ctrl = false|
+ _SetMenuItemKeyboardEquivalent
+ }
+
+ prSetState {|bool|
+ _SetMenuItemState
+ ^this.primitiveFailed;
+ }
+
+ prAddMenuItem { |parent, index, name, submenu|
+ _NewMenuItem
+ ^this.primitiveFailed;
+ }
+
+ prRemoveMenuItem {
+ _RemoveMenuItem
+ ^this.primitiveFailed;
+ }
+
+ doAction {
+ action.value(this);
+ }
+}
\ No newline at end of file


Property changes on: trunk/build/SCClassLibrary/Platform/osx/CocoaMenu.sc
___________________________________________________________________
Name: svn:eol-style:native
   +
Name: svn:mime-type
   + text/plain

Modified: trunk/build/SCClassLibrary/Platform/osx/OSXPlatform.sc
===================================================================
--- trunk/build/SCClassLibrary/Platform/osx/OSXPlatform.sc 2008-07-15 15:34:44 UTC (rev 7686)
+++ trunk/build/SCClassLibrary/Platform/osx/OSXPlatform.sc 2008-07-15 19:00:51 UTC (rev 7687)
@@ -21,6 +21,7 @@
  }
  shutdown {
  HIDDeviceService.releaseDeviceList;
+ CocoaMenuItem.clearCustomItems;
  }
 
  // only osx uses Cocoa guis


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

_______________________________________________
sc-dev mailing list

info (subscribe and unsubscribe): http://swiki.hfbk-hamburg.de:8888/MusicTechnology/880
archive: http://www.listarc.bham.ac.uk/marchives/sc-dev/
search: http://www.listarc.bham.ac.uk/lists/sc-dev/search/
LightInTheBox - Buy quality products at wholesale price