From d58c1bcc004eb528549b53b75ea8cce369b5a859 Mon Sep 17 00:00:00 2001 From: Ian C Date: Sun, 15 Jan 2006 01:04:56 +0000 Subject: Development checkin --- mwidget.mod/mwidget.bmx | 595 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 549 insertions(+), 46 deletions(-) diff --git a/mwidget.mod/mwidget.bmx b/mwidget.mod/mwidget.bmx index 11ff5ae..00ca593 100644 --- a/mwidget.mod/mwidget.bmx +++ b/mwidget.mod/mwidget.bmx @@ -338,6 +338,13 @@ Type TMWidget Abstract End Select End Method + Rem + bbdoc: Activate the widget (give it keyboard focus). + EndRem + Method Activate(state:Int) + ActivateGadget(gadget) + End Method + Rem bbdoc: Enables/disables a widget. EndRem @@ -656,6 +663,13 @@ Type TMWindow Extends TMWidget EndRem Field closed:Int + Rem + bbdoc: Activate the window. + EndRem + Method Activate(state:Int) + ActivateWindow(gadget) + End Method + Rem bbdoc: Send a close event to this window. EndRem @@ -781,35 +795,6 @@ Type TMWindow Extends TMWidget End Type -Rem -bbdoc: Defines a managed menu. -EndRem -Type TMMenu Extends TMWidget - - Rem - bbdoc: Creates a managed menu. - returns: The created button. - about: @label, @tag, @group, @hotkey and @modifier act the same as the MaxGUI arguments to @CreateMenu(), except that @group is a TMWidget. - EndRem - Method Create:TMMenu(label:String, tag:Int, group:TMWidget, hotkey:Int=0, modifier:Int=0) - BaseInitialise(CreateMenu(label,tag,group.gadget,hotkey,modifier),group) - typename="TMMenu" - Return Self - End Method - - Method Delete() - FreeMenu(gadget) - End Method - - Method Handle(e:TEvent) - Select e.id - Default - super.Handle(e) - End Select - End Method -End Type - - Rem bbdoc: Defines a managed button push button. EndRem @@ -1812,11 +1797,15 @@ Type TMTreeView Extends TMWidget End Method Rem - bbdoc: The number of nodes in the view. + bbdoc: The number of nodes in the view that are direct children on the passed node. returns: The number of nodes. - about: @path is the path to count from. / is the root node. + about: @path is the path to count from. Unfortunately counting from the root (/) doesn't work, so it returns -1. EndRem Method CountChildren:Int(path:String) + If path="/" + Return -1 + EndIf + Local node:TMTreeNode=ResolvePath(path) If node @@ -1861,7 +1850,7 @@ Type TMTreeView Extends TMWidget bbdoc: Add/modify nodes in the tree. about: @path is the path to the node. This silently fails if the parent nodes don't exist. @tag is an Object that the entry is tagged with. ToString() is called on this to create the text for the entry (so passing a String works fine). - @icon is the icon to use. + @icon is the icon to use. Note that if you set an icon strip, then this seems to use the first icon (on Win32 at least) if set to -1. EndRem Method Set(path:String, tag:Object, icon:Int=-1) Local parent:TMTreeNode=ResolvePath(FixedExtractDir(path)) @@ -2033,6 +2022,499 @@ Type TMTreeView Extends TMWidget End Type +Type TMenuItem + Field id:Int + Field owner:TMMenu + Field path:String + Field tag:Object + Field gadget:TGadget + Field callback(menu:TMMenu, path:String, tag:Object) + Function Create:TMenuItem(owner:TMMenu, id:Int, path:String, gadget:TGadget, tag:Object, callback(menu:TMMenu, path:String, tag:Object)) + Local o:TMenuItem=New TMenuItem + o.owner=owner + o.id=id + o.path=path + o.gadget=gadget + o.tag=tag + o.callback=callback + Return o + End Function +End Type + + +Rem +bbdoc: Defines a managed menu. +about: Note that TMMenu is NOT a TMWidget. +EndRem +Type TMMenu + + Field root:TGadget + Field map:TMap + Field win:TMWindow + + Rem + bbdoc: Creates a managed menu that is associated as a window menu. + returns: The created menu. + about: @window is the window the menu is attached to. + EndRem + Method CreateWindowMenu:TMMenu(window:TMWindow) + map=New TMap + root=WindowMenu(window.gadget) + win=window + SetRoot() + Return Self + End Method + + Rem + bbdoc: Creates a managed menu that can be used as a popup menu. + returns: The created menu. + EndRem + Method CreatePopupMenu:TMMenu() + map=New TMap + root=CreateMenu("",0,Null) + win=Null + SetRoot() + Return Self + End Method + + Method Delete() + Clear() + If Not win + FreeMenu(root) + EndIf + End Method + + Rem + bbdoc: Clear all items from the menu + EndRem + Method Clear() + For Local m:TMenuItem=EachIn map + FreeMenu(m.gadget) + Static.DeregisterMenuItem(m) + Next + map.Clear() + SetRoot() + End Method + + Method SetRoot() + map.Insert("/",TMenuItem.Create(Self,0,"/",root,Null,Null)) + End Method + + Method ResolvePath:TMenuItem(path:String) + Return TMenuItem(map.ValueForKey(path)) + End Method + + Method Prune(path:String) + Local l:TList=CreateList() + + ' Not sure if this is overly ineffecient -- just being safe as in most languages deleting whilst iterating + ' is not recommended... + ' + For Local k:String=EachIn map.Keys() + If k=path Or k.Find(path+"/")=0 + l.AddLast(k) + EndIf + Next + + For Local k:String=EachIn l + Local n:TMenuItem=ResolvePath(k) + map.Remove(k) + Static.DeregisterMenuItem(n) + FreeMenu(n.gadget) + Next + End Method + + Rem + bbdoc: Add a menu option. + about: @path is the path to the menu item. This silently fails if the parent menus don't exist. @tag is an Object that the entry is tagged with. + ToString() is called on this to create the text for the menu (so passing a String works fine). If @callback is not null, then it is called when + this option is selected. + @hotkey and @modifier are as in MaxGUI's CreateMenu(). + EndRem + Method Set(path:String, tag:Object, callback(menu:TMMenu, path:String, tag:Object)=Null, hotkey:Int=0, modifier:Int=0) + If path<>"/" + Local parent:TMenuItem=ResolvePath(FixedExtractDir(path)) + + If parent + Local node:TMenuItem=ResolvePath(path) + + If node + SetMenuText(node.gadget,tag.ToString()) + Else + Local id:Int=Static.NextMenuID() + node=TMenuItem.Create(Self,id,path,CreateMenu(tag.ToString(),id,parent.gadget,hotkey,modifier),tag,callback) + map.Insert(path,node) + Static.RegisterMenuItem(node) + EndIf + + node.tag=tag + + If win + UpdateWindowMenu(win.gadget) + EndIf + EndIf + EndIf + End Method + + Rem + bbdoc: Remove menu item and its children. + about: @path is the path to the menu item. Root cannot be removed. + EndRem + Method Remove(path:String) + If path<>"/" + Prune(path) + + If win + UpdateWindowMenu(win.gadget) + EndIf + EndIf + End Method + + Rem + bbdoc: Change a menu tag (and therefore its text). + about: @path is the path to the menu item. Root cannot be changed. + EndRem + Method SetTag(path:String, tag:Object) + If path<>"/" + Local node:TMenuItem=ResolvePath(path) + + If node + SetMenuText(node.gadget,tag.ToString()) + node.tag=tag + + If win + UpdateWindowMenu(win.gadget) + EndIf + EndIf + EndIf + End Method + + Rem + bbdoc: Change a menu check. + about: @path is the path to the menu item. Root cannot be changed. + EndRem + Method Check(path:String, check:Int) + If path<>"/" + Local node:TMenuItem=ResolvePath(path) + + If node + If check + CheckMenu(node.gadget) + Else + UncheckMenu(node.gadget) + EndIf + + If win + UpdateWindowMenu(win.gadget) + EndIf + EndIf + EndIf + End Method + + Rem + about: Is a menu item checked. + EndRem + Method IsChecked:Int(path:String) + Local ret:Int=False + + If path<>"/" + Local node:TMenuItem=ResolvePath(path) + + If node + ret=MenuChecked(node.gadget) + EndIf + EndIf + + Return ret + End Method + + Rem + bbdoc: Enable/disable a menu item. + about: @path is the path to the menu item. Root cannot be changed. + EndRem + Method Enable(path:String, enab:Int) + If path<>"/" + Local node:TMenuItem=ResolvePath(path) + + If node + If enab + EnableMenu(node.gadget) + Else + DisableMenu(node.gadget) + EndIf + + If win + UpdateWindowMenu(win.gadget) + EndIf + EndIf + EndIf + End Method + + Rem + about: Is a menu item enabled. + EndRem + Method IsEnabled:Int(path:String) + Local ret:Int=False + + If path<>"/" + Local node:TMenuItem=ResolvePath(path) + + If node + ret=MenuEnabled(node.gadget) + EndIf + EndIf + + Return ret + End Method + + Rem + bbdoc: Called when the an item is selected in the menu. + EndRem + Method OnMenuItem(path:String, tag:Object) + End Method + + Rem + bbdoc: Popup the menu. + about: @win is a gadget to pass to MaxGUI. For some reason you need this, and the docs say it should be a window. + When I've tried any gadget would suffice, but don't come crying to me if it stops working for non-window gadgets. + EndRem + Method Popup(g:TMWidget) + PopupWindowMenu(g.gadget,root) + End Method + + Method ToString:String() + Return "TMMenu:"+super.ToString() + End Method +End Type + + +Rem +bbdoc: Defines a managed canvas. +EndRem +Type TMCanvas Extends TMWidget + + Rem + bbdoc: Creates a managed canvas. + returns: The created canvas. + about: @x, @y, @w, @h, @group, @style and @gfxflags act the same as the MaxGUI arguments to @CreateTreeView(), except that @group is a TMWidget. + EndRem + Method Create:TMCanvas(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0, gfxflags:Int=GRAPHICS_BACKBUFFER) + OnRedrawEvent=New TMWEventListVoid + OnButtonDownEvent=New TMWEventListInt + OnButtonUpEvent=New TMWEventListInt + OnMouseMoveEvent=New TMWEventListIntInt + OnMouseWheelEvent=New TMWEventListInt + OnKeyDownEvent=New TMWEventListInt + OnKeyUpEvent=New TMWEventListInt + OnKeyEvent=New TMWEventListInt + BaseInitialise(CreateCanvas(x,y,w,h,group.gadget,style,gfxflags),group) + typename="TMCanvas" + Return Self + End Method + + Rem + bbdoc: Set the graphics so that the canvas can be drawn onto. + EndRem + Method SetupGraphics() + SetGraphics(CanvasGraphics(gadget)) + End Method + + Rem + bbdoc: Called when the canvas should be redrawn. + EndRem + Method OnRedraw() + End Method + + Rem + bbdoc: Called when the canvas should be redrawn. + EndRem + Field OnRedrawEvent:TMWEventListVoid + + Rem + bbdoc: Called when the a mouse button is pressed. + about: @button is the pressed button. + EndRem + Method OnButtonDown(button:Int) + End Method + + Rem + bbdoc: Called when the a mouse button is pressed. + EndRem + Field OnButtonDownEvent:TMWEventListInt + + Rem + bbdoc: Called when the a mouse button is released. + about: @button is the released button. + EndRem + Method OnButtonUp(button:Int) + End Method + + Rem + bbdoc: Called when the a mouse button is released. + EndRem + Field OnButtonUpEvent:TMWEventListInt + + Rem + bbdoc: Called when the mouse moves. + about: @x and @y are the mouse co-ordinates. + EndRem + Method OnMouseMove(x:Int, y:Int) + End Method + + Rem + bbdoc: Called when the an item is selected. + EndRem + Field OnMouseMoveEvent:TMWEventListIntInt + + Rem + bbdoc: Called when the mouse wheel moves. + about: @delta is the amount the wheel moves. + EndRem + Method OnMouseWheel(delta:Int) + End Method + + Rem + bbdoc: Called when the mouse wheel moves. + EndRem + Field OnMouseWheelEvent:TMWEventListInt + + Rem + bbdoc: Called when a key is held down. + about: @code is the key code. + EndRem + Method OnKeyDown(code:Int) + End Method + + Rem + bbdoc: Called when a key is held down. + EndRem + Field OnKeyDownEvent:TMWEventListInt + + Rem + bbdoc: Called when a key is released. + about: @code is the key code. + EndRem + Method OnKeyUp(code:Int) + End Method + + Rem + bbdoc: Called when a key is released. + EndRem + Field OnKeyUpEvent:TMWEventListInt + + Rem + bbdoc: Called when a key character is generated. + about: @code is the unicode value. + EndRem + Method OnKey(code:Int) + End Method + + Rem + bbdoc: Called when a key character is generated. + EndRem + Field OnKeyEvent:TMWEventListInt + + Method Handle(e:TEvent) + Select e.id + Case EVENT_GADGETPAINT + OnRedraw() + OnRedrawEvent.Fire(Self) + Case EVENT_MOUSEDOWN + OnButtonDown(e.data) + OnButtonDownEvent.Fire(Self,e.data) + Case EVENT_MOUSEUP + OnButtonUp(e.data) + OnButtonUpEvent.Fire(Self,e.data) + Case EVENT_MOUSEMOVE + OnMouseMove(e.x,e.y) + OnMouseMoveEvent.Fire(Self,e.x,e.y) + Case EVENT_MOUSEWHEEL + OnMouseWheel(e.data) + OnMouseWheelEvent.Fire(Self,e.data) + Case EVENT_KEYDOWN + OnKeyDown(e.data) + OnKeyDownEvent.Fire(Self,e.data) + Case EVENT_KEYUP + OnKeyUp(e.data) + OnKeyUpEvent.Fire(Self,e.data) + Case EVENT_KEYCHAR + OnKey(e.data) + OnKeyEvent.Fire(Self,e.data) + Default + super.Handle(e) + End Select + End Method +End Type + + +Rem +bbdoc: Defines a toolbar. +EndRem +Type TMToolbar Extends TMWidget + Rem + bbdoc: Creates a managed toolbar. + returns: The created toolbar. + about: @source, @group and @style act the same as the MaxGUI arguments to @CreateComboBox(), except that @group is a TMWidget. + If @values is not NULL it is used to load up the initial options. + IMPORTANT: It is really not recommended to use COMBOBOX_EDITABLE as OnIndexChanged() is called when the user edits the field. + There seems to be no easy way to remedy this. + EndRem + Method Create:TMToolbar(source:Object, group:TMWidget, style:Int=0) + OnSelectedEvent=New TMWEventListInt + BaseInitialise(CreateToolBar(source,0,0,0,0,group.gadget,style),group) + typename="TMToolbar" + Return Self + End Method + + Rem + bbdoc: Adds an item to the toolbar. + EndRem + Method AddItem(icon:Int, flags:Int=0, tooltip:String=Null) + AddGadgetItem(gadget,"",flags,icon,tooltip,Null) + End Method + + Rem + bbdoc: Set the tooltips. + EndRem + Method SetTooltips(tips:String[]) + SetToolBarTips(gadget,tips) + End Method + + Rem + bbdoc: Enable or disable a particular item. + EndRem + Method ItemEnabled(index:Int, state:Int) + If state + EnableGadgetItem(gadget,index) + Else + DisableGadgetItem(gadget,index) + EndIf + End Method + + Rem + bbdoc: Called when an icon is selected. + about: @index is the selected index. + EndRem + Method OnSelected(index:Int) + End Method + + Rem + bbdoc: Called when an icon is selected. + EndRem + Field OnSelectedEvent:TMWEventListInt + + Method Handle(e:TEvent) + Select e.id + Case EVENT_GADGETACTION + OnSelected(e.data) + OnSelectedEvent.Fire(Self,e.data) + Default + super.Handle(e) + End Select + End Method +End Type + + Rem bbdoc: Enters the event processing loop. about: @top is the top level TMWindow For the application. The loop continues Until the @closed Field of this window is TRUE. @@ -2058,9 +2540,13 @@ End Function Type Static Global list:TList + Global menu:TList + Global menuid:Int Function Init() list=CreateList() + menu=CreateList() + menuid=0 AddHook(EmitEventHook,EventHandler) End Function @@ -2070,12 +2556,24 @@ Type Static DebugLog "Got event : " + e.ToString() If e - For Local g:TMWidget=EachIn list - If g And g.gadget And g.gadget=e.source - DebugLog "Passing event to " + g.ToString() - g.Handle(e) - EndIf - Next + If e.id=EVENT_MENUACTION + For Local m:TMenuItem=EachIn menu + If m.id=e.data + DebugLog "Passing menu event to " + m.owner.ToString() + m.owner.OnMenuItem(m.path,m.tag) + If m.callback + m.callback(m.owner,m.path,m.tag) + EndIf + EndIf + Next + Else + For Local g:TMWidget=EachIn list + If g And g.gadget And g.gadget=e.source + DebugLog "Passing event to " + g.ToString() + g.Handle(e) + EndIf + Next + EndIf EndIf Return e @@ -2088,18 +2586,23 @@ Type Static End Function Function Deregister(w:TMWidget) - If w.children.Count() - For Local c:TMWidget=EachIn w.children - If c - Deregister(c) - EndIf - Next - EndIf - w.OnUnmanage() w.OnUnmanageEvent.Fire(w) list.Remove(w) End Function + + Function RegisterMenuItem(m:TMenuItem) + menu.AddLast(m) + End Function + + Function DeregisterMenuItem(m:TMenuItem) + menu.Remove(m) + End Function + + Function NextMenuID:Int() + menuid:+1 + Return menuid + End Function End Type Static.Init() \ No newline at end of file -- cgit v1.2.3