;/------------------------ ;| ;| Dialog Design0R V1.00 ;| ©HeX0R 2018 ;| ;| Simple but powerful dialog designer ;| ;| Thanks to Shardik for the Linux and MacOS Api! ;| ;| Button Images from: ;| http://www.purebasic.fr/english/viewtopic.php?f=12&t=65091 ;| ;/------------------------ ; ---------------------------------------------------------------------------- ; "THE BEER-WARE LICENSE": ; wrote this file. as long as you retain this notice you ; can do whatever you want with this stuff. If we meet some day, and you think ; this stuff is worth it, you can buy me a beer in return ; (see address on http://hex0rs.coderbu.de/). ; Or just go out and drink a few on your own/with your friends ;) ;============================================================================= UsePNGImageDecoder() CompilerIf #PB_Compiler_OS = #PB_OS_Linux ImportC "" gtk_widget_style_get(*Widget.GtkWidget, PropertyName.P-UTF8, *Value, Null) EndImport CompilerEndIf EnableExplicit #Update_Interval = 1000 ;delay for updating the preview windows. Unfortunately we don't have any command to update a dialog, when XML has been changed. #XML_Main = 0 #XML_Loaded = 1 #Dialog_Main = 0 #Main_Timer = 0 #Popup_Menu_Tree = 0 Enumeration #DialogType_Dialogs #DialogType_Window #DialogType_Button #DialogType_ButtonImage #DialogType_Calendar #DialogType_Canvas #DialogType_CheckBox #DialogType_ComboBox #DialogType_Container #DialogType_Date #DialogType_Editor #DialogType_Empty #DialogType_ExplorerCombo #DialogType_ExplorerList #DialogType_ExplorerTree #DialogType_Frame #DialogType_HyperLink #DialogType_Image #DialogType_IPAddress #DialogType_ListIcon #DialogType_ListView #DialogType_Option #DialogType_Panel #DialogType_ProgressBar #DialogType_ScrollArea #DialogType_ScrollBar #DialogType_Spin #DialogType_Splitter #DialogType_String #DialogType_Tab #DialogType_Text #DialogType_TrackBar #DialogType_Tree #DialogType_Web #DialogType_HBox #DialogType_VBox #DialogType_GridBox #DialogType_MultiBox #DialogType_SingleBox ; #TreeMenu_AddWindow #TreeMenu_MoveChildUp #TreeMenu_MoveChildDown #TreeMenu_Delete EndEnumeration Structure _DIALOG_DATA_ ;used for map DD(), please see "LoadDialogTypeData()" and the DataSection on the bottom Type.i ;<- see enumeration above MaxChilds.i ;<- how many childs can this type contain? -1 = unlimited UsableChilds.i ;<- can we use any available child? (e.g. panel can only contain tab) PossibleFlags.s ;<- flags, this type supports (texts, separated by |) MinSupport.i ;<- does this type support the min attribute? MaxSupport.i ;<- does this type support the max attribute? ValueSupport.i ;<- does this type support the value attribute? GroupSupport.i ;<- does this type support the group attribute? ImageID.i ;<- Icon for the Tree, not supported yet, need images... EndStructure Structure _OPEN_DIALOGS_ ;used for list OpenDialogs(), will keep the temporary open preview dialogs DialogID.i ;<- the DialogID of this Dialog WindowID.i ;<- the WindowID of this Window UpdateTimeOUT.i ;<- a delay timer to update the window *Node ;<- XML node of the node for fast access EndStructure Structure _SORTHELPER_ ;used in temp. list SH(). Maps can't be sorted, but we want to have our menu items sorted, see "OpenWindow_Main()" Name.s ;<- Name, or MapKey of the according DD() *DD._DIALOG_DATA_ ;<- pointer to the DD() map item EndStructure Global NewMap DD._DIALOG_DATA_() ;stores all of the dialog types, like button, panel, window, ... Global NewMap DID.i() ;used to keep the gadget IDs of our main window Global NewList OpenDialogs._OPEN_DIALOGS_() ;stores temporary dialog/window-previews Global ActiveFile.s ;will keep the xml file name loaded (for the save button) Global DragNode.i ;will keep the *Node of the currently dragged node Procedure LogIT(Text.s) ;Log text in the log editor If Text Text = FormatDate("%hh:%ii:%ss", Date()) + " " + Text EndIf AddGadgetItem(DialogGadget(#Dialog_Main, "log"), -1, Text) ;scroll to the bottom CompilerSelect #PB_Compiler_OS CompilerCase #PB_OS_Windows SendMessage_(GadgetID(DialogGadget(#Dialog_Main, "log")), #EM_SCROLLCARET, #SB_BOTTOM, 0) CompilerCase #PB_OS_Linux ;Thanks to Dave: http://www.purebasic.fr/english/viewtopic.php?f=15&t=43753 Protected *buffer, end_iter.GtkTextIter *buffer = gtk_text_view_get_buffer_(GadgetID(DialogGadget(#Dialog_Main, "log"))) gtk_text_buffer_get_end_iter_(*buffer, @end_iter) gtk_text_view_scroll_mark_onscreen_(GadgetID(DialogGadget(#Dialog_Main, "log")), gtk_text_buffer_create_mark_(*buffer, "end_mark", @end_iter, #False)) CompilerCase #PB_OS_MacOS ;?? CompilerEndSelect EndProcedure Procedure SelectDDFromTree() Protected Index, *Node Index = GetGadgetState(DID("tree_objects")) If Index > -1 *Node = GetGadgetItemData(DID("tree_objects"), Index) If FindMapElement(DD(), GetXMLNodeName(*Node)) = 0 *Node = 0 EndIf EndIf ProcedureReturn *Node EndProcedure Procedure ResetOnEvents() Protected i ClearGadgetItems(DID("onevents")) For i = 1 To 9 AddGadgetItem(DID("onevents"), -1, StringField("onevent,onchange,onfocus,onlostfocus,ondragstart,onrightclick,onleftclick,onrightdoubleclick,onleftdoubleclick", i, ",")) Next EndProcedure Procedure ResetMarginCombo() Protected i ClearGadgetItems(DID("margincombo")) For i = 1 To 6 AddGadgetItem(DID("margincombo"), -1, StringField("top:,left:,right:,bottom:,vertical:,horizontal:", i, ",")) Next i EndProcedure Procedure DisableAll(Mode) ;en/disable visible gadgets ForEach DID() Select MapKey(DID()) Case "_id", "name", "text", "min", "max", "value", "colspan", "rowspan", "width", "height", "flags", "invisible", "disabled", "group", "onevents", "onevent_proc" DisableGadget(DID(), Mode) EndSelect Next EndProcedure Procedure.s GetTempName(Type.s) ;will create temporary names of the nodes, e.g. window_1, tree_2, ... Protected Result.s, a$, j Protected *Node, i, Max.i For i = 0 To CountGadgetItems(DID("tree_objects")) - 1 *Node = GetGadgetItemData(DID("tree_objects"), i) If GetXMLNodeName(*Node) = Type a$ = GetXMLAttribute(*Node, "name") j = Val(Mid(a$, Len(Type) + 2)) If j > Max Max = j EndIf EndIf Next Result = Type + "_" + Str(Max + 1) ProcedureReturn Result EndProcedure Procedure UpdateDialog(*Node, Delayed.i = 0) ;will set the UpdateTimeOUT of this dialog, the real update is done in the timer procedure OnTimerEvent() then Repeat If LCase(GetXMLNodeName(*Node)) = "window" Break EndIf *Node = ParentXMLNode(*Node) Until *Node = 0 ;if we would have the possibility to update a dialog on-the-run, this would be a uber-feature. ;until now, we will update the dialog after a delay If *Node If XMLNodeType(*Node) = #PB_XML_Normal ForEach OpenDialogs() If OpenDialogs()\Node = *Node OpenDialogs()\UpdateTimeOUT = ElapsedMilliseconds() + Delayed Break EndIf Next EndIf EndIf EndProcedure Procedure ShowAllDialogs() ;called as soon as a xml has been loaded, to open all included windows Protected i, *Node, Name.s, Attr.s Protected DID For i = 0 To CountGadgetItems(DID("tree_objects")) - 1 *Node = GetGadgetItemData(DID("tree_objects"), i) If XMLNodeType(*Node) = #PB_XML_Normal Name = GetXMLNodeName(*node) If LCase(Name) = "window" DID = CreateDialog(#PB_Any) Attr = GetXMLAttribute(*node, "name") AddElement(OpenDialogs()) OpenDialogs()\DialogID = DID OpenDialogs()\Node = *node OpenDialogs()\UpdateTimeOUT = 0 If OpenXMLDialog(DID, #XML_Loaded, Attr) = 0 MessageRequester("Error!", DialogError(DID)) ;FreeDialog(DID) Else OpenDialogs()\WindowID = DialogWindow(DID) EndIf EndIf EndIf Next i EndProcedure Procedure OnTimerEvent() ;timer event, will be called any 50ms and only used to take care of window updates Protected Name.s, DID, x = #PB_Ignore, y = #PB_Ignore, ActiveGadget ForEach OpenDialogs() If IsDialog(OpenDialogs()\DialogID) And OpenDialogs()\UpdateTimeOUT <> 0 And OpenDialogs()\UpdateTimeOUT <= ElapsedMilliseconds() ActiveGadget = GetActiveGadget() DID = OpenDialogs()\DialogID If OpenDialogs()\WindowID And IsWindow(OpenDialogs()\WindowID) x = WindowX(OpenDialogs()\WindowID) y = WindowY(OpenDialogs()\WindowID) EndIf OpenDialogs()\UpdateTimeOUT = 0 FreeDialog(DID) DID = CreateDialog(#PB_Any) If DID OpenDialogs()\DialogID = DID Name = GetXMLAttribute(OpenDialogs()\Node, "name") If OpenXMLDialog(DID, #XML_Loaded, Name, x, y) = 0 LogIT("Error loading dialog: " + DialogError(DID)) Else OpenDialogs()\WindowID = DialogWindow(DID) ResizeWindow(OpenDialogs()\WindowID, x, y, #PB_Ignore, #PB_Ignore) HideWindow(OpenDialogs()\WindowID, 0) EndIf EndIf SetActiveGadget(ActiveGadget) EndIf Next EndProcedure Procedure ClearTexts() ;clears all available gadgets Protected Key.s HideGadget(DialogGadget(#Dialog_Main, "container_window"), 1) HideGadget(DialogGadget(#Dialog_Main, "container_boxes"), 1) HideGadget(DialogGadget(#Dialog_Main, "container_gridbox"), 1) HideGadget(DialogGadget(#Dialog_Main, "container_multibox"), 1) HideGadget(DialogGadget(#Dialog_Main, "container_singlebox"), 1) HideGadget(DialogGadget(#Dialog_Main, "container_splitter"), 1) ResetOnEvents() ForEach DID() Key = MapKey(DID()) Select Key Case "invisible", "disabled" SetGadgetState(DID(), 0) Case "alignbox", "expandbox", "colexpand", "expandsingle", "rowexpand", "margincombo" SetGadgetState(DID(), -1) Case "flags" ;will be cleared anyway ClearGadgetItems(DID()) Case "tree_objects" ;do nothing Default SetGadgetText(DID(), "") Select Key Case "expandboxitem", "colexpanditem", "rowexpanditem" DisableGadget(DID(), 1) EndSelect EndSelect Next EndProcedure Runtime Procedure OnCheckBoxChanged() ;checkbox value changed, set attributes accordingly Protected *node, i i = GetGadgetState(DID("tree_objects")) If i > -1 *node = GetGadgetItemData(DID("tree_objects"), i) If GetGadgetState(DID("invisible")) SetXMLAttribute(*node, "invisible", "yes") Else RemoveXMLAttribute(*node, "invisible") EndIf If GetGadgetState(DID("disabled")) SetXMLAttribute(*node, "disabled", "yes") Else RemoveXMLAttribute(*node, "disabled") EndIf UpdateDialog(*node) EndIf EndProcedure Runtime Procedure OnTreeClick() ;user clicked on a tree gadget (NOT main tree!, this is OnObjectTreeClick()!) Protected *node, a$, i i = GetGadgetState(DID("tree_objects")) If i > -1 *node = GetGadgetItemData(DID("tree_objects"), i) a$ = "" For i = 0 To CountGadgetItems(DID("flags")) - 1 If GetGadgetItemState(DID("flags"), i) & #PB_Tree_Checked If a$ = "" a$ = GetGadgetItemText(DID("flags"), i) Else a$ + " | " + GetGadgetItemText(DID("flags"), i) EndIf EndIf Next i If a$ SetXMLAttribute(*node, "flags", a$) Else RemoveXMLAttribute(*node, "flags") EndIf UpdateDialog(*node) EndIf EndProcedure Runtime Procedure OnComboBoxChanged() ;combo box state changed Protected *node, a$, Key.s, i, Selected, Gadget i = GetGadgetState(DID("tree_objects")) If i > -1 *node = GetGadgetItemData(DID("tree_objects"), i) Gadget = EventGadget() Selected = GetGadgetState(Gadget) a$ = GetGadgetText(Gadget) ForEach DID() If DID() = Gadget Key = MapKey(DID()) Select Key Case "alignbox" Key = "align" Case "onevents" SetGadgetText(DID("onevent_proc"), StringField(a$, 2, ":")) ProcedureReturn Case "expandbox" If Selected = 1 DisableGadget(DID("alignbox"), 0) SetXMLAttribute(*node, "align", GetGadgetText(DID("alignbox"))) Else DisableGadget(DID("alignbox"), 1) RemoveXMLAttribute(*node, "align") SetGadgetState(DID("alignbox"), -1) EndIf If Selected = 3 DisableGadget(DID("expandboxitem"), 0) a$ + GetGadgetText(DID("expandboxitem")) Else DisableGadget(DID("expandboxitem"), 1) EndIf Key = "expand" Case "colexpand", "rowexpand" If Selected = 3 DisableGadget(DID(Key + "item"), 0) a$ + GetGadgetText(DID(Key + "item")) Else DisableGadget(DID(Key + "item"), 1) EndIf Case "margincombo" If Selected = -1 ;user entered a value DisableGadget(DID("marginext"), 1) SetXMLAttribute(*node, "margin", a$) Else DisableGadget(DID("marginext"), 0) SetGadgetText(DID("marginext"), StringField(GetGadgetItemText(DID("margincombo"), Selected), 2, ":")) EndIf ProcedureReturn Case "expandsingle" Key = "expand" EndSelect SetXMLAttribute(*node, Key, a$) Break EndIf Next UpdateDialog(*node) EndIf EndProcedure Runtime Procedure OnStringChanged() ;string text changed Protected *node, a$, b$, c$, Key.s, Gadget, Selected, i, j, k i = GetGadgetState(DID("tree_objects")) If i > -1 b$ = GetGadgetItemText(DID("tree_objects"), i) *node = GetGadgetItemData(DID("tree_objects"), i) Gadget = EventGadget() j = FindString(b$, "(", 1) ForEach DID() If DID() = Gadget Key = MapKey(DID()) a$ = GetGadgetText(Gadget) Select Key Case "onevent_proc" k = GetGadgetState(DID("onevents")) If k = -1 Break Else c$ = GetGadgetText(DID("onevents")) Key = StringField(c$, 1, ":") If a$ SetGadgetItemText(DID("onevents"), k, Key + ":" + a$) EndIf Key = "_" + Key EndIf Case "expandboxitem" Key = "expand" a$ = "item:" + a$ Case "colexpanditem" Key = "colexpand" a$ = "item:" + a$ Case "rowexpanditem" Key = "rowexpand" a$ = "item:" + a$ Case "marginext" Key = "margin" Selected = GetGadgetState(DID("margincombo")) If Selected > -1 c$ = StringField(GetGadgetItemText(DID("margincombo"), Selected), 1, ":") SetGadgetItemText(DID("margincombo"), Selected, c$ + ":" + GetGadgetText(DID("marginext"))) a$ = "" For i = 0 To CountGadgetItems(DID("margincombo")) - 1 c$ = GetGadgetItemText(DID("margincombo"), i) If StringField(c$, 2, ":") If a$ a$ + "," + c$ Else a$ = c$ EndIf EndIf Next Else ProcedureReturn EndIf Case "_id" c$ = GetGadgetText(DID("_id")) If j = 0 SetGadgetItemText(DID("tree_objects"), i, b$ + " (id: " + c$ + ")") ElseIf Mid(b$, j + 1, 3) = "id:" If c$ SetGadgetItemText(DID("tree_objects"), i, Left(b$, j - 2) + " (id: " + c$ + ")") Else SetGadgetItemText(DID("tree_objects"), i, Left(b$, j - 2)) EndIf EndIf Case "name" c$ = GetGadgetText(DID("name")) If j = 0 SetGadgetItemText(DID("tree_objects"), i, b$ + " (" + c$ + ")") ElseIf Mid(b$, j + 1, 3) <> "id:" If c$ SetGadgetItemText(DID("tree_objects"), i, Left(b$, j - 2) + " (" + c$ + ")") Else SetGadgetItemText(DID("tree_objects"), i, Left(b$, j - 2)) EndIf EndIf EndSelect If a$ SetXMLAttribute(*node, Key, a$) Else RemoveXMLAttribute(*node, Key) EndIf Break EndIf Next UpdateDialog(*node, 1000) EndIf EndProcedure Procedure DisableMenuItems(AddWindow, MoveChildUp, MoveChildDown, AddChilds, AddContainer, Delete, UsableChilds) ;make sure, that only allowed menu items are enabled Protected i DisableMenuItem(#Popup_Menu_Tree, #TreeMenu_AddWindow, AddWindow) DisableMenuItem(#Popup_Menu_Tree, #TreeMenu_MoveChildUp, MoveChildUp) DisableMenuItem(#Popup_Menu_Tree, #TreeMenu_MoveChildDown, MoveChildDown) DisableMenuItem(#Popup_Menu_Tree, #TreeMenu_Delete, Delete) For i = #DialogType_Button To #DialogType_Web If AddChilds = 1 DisableMenuItem(#Popup_Menu_Tree, i, AddChilds) ElseIf UsableChilds = -1 If i = #DialogType_Tab DisableMenuItem(#Popup_Menu_Tree, i, 1) Else DisableMenuItem(#Popup_Menu_Tree, i, AddChilds) EndIf ElseIf i = UsableChilds DisableMenuItem(#Popup_Menu_Tree, i, 0) Else DisableMenuItem(#Popup_Menu_Tree, i, 1) EndIf Next i For i = #DialogType_HBox To #DialogType_SingleBox DisableMenuItem(#Popup_Menu_Tree, i, AddContainer) Next i EndProcedure Runtime Procedure OnObjectTreeRClick() ;user clicked on ObjectTree via right mouse button, show popup menu Protected *Node, *First, *Parent, i, j, k *Node = SelectDDFromTree() If *Node Select DD()\Type Case #DialogType_Dialogs DisableMenuItems(0, 1, 1, 1, 1, 1, DD()\UsableChilds) Case #DialogType_Window i = 0 If DD()\MaxChilds > -1 And XMLChildCount(*Node) >= DD()\MaxChilds i = 1 EndIf DisableMenuItems(1, 1, 1, i, i, 0, DD()\UsableChilds) Default i = 0 j = 0 k = 1 If DD()\MaxChilds > -1 And XMLChildCount(*Node) >= DD()\MaxChilds i = 1 EndIf *Parent = ParentXMLNode(*Node) *First = ChildXMLNode(*Parent, 1) If *Node = *First j = 1 EndIf If NextXMLNode(*Node) k = 0 EndIf DisableMenuItems(1, j, k, i, i, 0, DD()\UsableChilds) EndSelect EndIf DisplayPopupMenu(#Popup_Menu_Tree, WindowID(DialogWindow(#Dialog_Main))) EndProcedure Runtime Procedure OnObjectTreeClick() ;new item selected, set all gadgets accordingly Protected *node, *parent, Name.s, a$, b$, c$, i, j, Box ClearTexts() i = GetGadgetState(DID("tree_objects")) If i = -1 DisableAll(1) Else DisableAll(0) *node = GetGadgetItemData(DID("tree_objects"), i) Name = GetXMLNodeName(*node) If LCase(Name) = "dialogs" ;clear all data DisableAll(1) Else *parent = ParentXMLNode(*node) If *parent And XMLNodeType(*parent) = #PB_XML_Normal And LCase(GetXMLNodeName(*parent)) = "gridbox" DisableGadget(DID("colspan"), 0) DisableGadget(DID("rowspan"), 0) Else DisableGadget(DID("colspan"), 1) DisableGadget(DID("rowspan"), 1) EndIf Name = LCase(Name) If FindMapElement(DD(), Name) ClearGadgetItems(DID("flags")) If DD()\PossibleFlags For i = 0 To CountString(DD()\PossibleFlags, "|") AddGadgetItem(DID("flags"), -1, Trim(StringField(DD()\PossibleFlags, i + 1, "|"))) Next i EndIf Select DD()\Type Case #DialogType_Window HideGadget(DialogGadget(#Dialog_Main, "container_window"), 0) Case #DialogType_GridBox HideGadget(DialogGadget(#Dialog_Main, "container_gridbox"), 0) Case #DialogType_HBox, #DialogType_VBox Box = #True HideGadget(DialogGadget(#Dialog_Main, "container_boxes"), 0) Case #DialogType_MultiBox HideGadget(DialogGadget(#Dialog_Main, "container_multibox"), 0) Case #DialogType_SingleBox HideGadget(DialogGadget(#Dialog_Main, "container_singlebox"), 0) DisableGadget(DID("marginext"), 1) Case #DialogType_Splitter HideGadget(DialogGadget(#Dialog_Main, "container_splitter"), 0) EndSelect DisableGadget(DID("group"), 1 - DD()\GroupSupport) DisableGadget(DID("value"), 1 - DD()\ValueSupport) DisableGadget(DID("min"), 1 - DD()\MinSupport) DisableGadget(DID("max"), 1 - DD()\MaxSupport) ResetOnEvents() ResetMarginCombo() If ExamineXMLAttributes(*node) While NextXMLAttribute(*node) a$ = LCase(XMLAttributeName(*node)) b$ = XMLAttributeValue(*node) c$ = LCase(b$) Select a$ Case "invisible", "disabled" If c$ = "yes" SetGadgetState(DID(a$), 1) EndIf Case "flags" ;handle flags For i = 0 To CountString(b$, "|") For j = 0 To CountGadgetItems(DID("flags")) - 1 If LCase(GetGadgetItemText(DID("flags"), j)) = Trim(StringField(c$, i + 1, "|")) SetGadgetItemState(DID("flags"), j, #PB_Tree_Checked) Break EndIf Next j Next i Case "align" If Box If c$ = "center" SetGadgetState(DID("alignbox"), 1) ElseIf c$ = "bottom/right" SetGadgetState(DID("alignbox"), 2) ElseIf c$ = "top/left" SetGadgetState(DID("alignbox"), 0) EndIf If GetGadgetState(DID("expandbox")) = 1 DisableGadget(DID("alignbox"), 0) Else DisableGadget(DID("alignbox"), 1) EndIf Else ;singlebox For i = 0 To CountString(b$, ",") For j = 0 To CountGadgetItems(DID("alignsingle")) - 1 If LCase(GetGadgetItemText(DID("alignsingle"), j)) = Trim(StringField(c$, i + 1, ",")) SetGadgetItemState(DID("alignsingle"), j, #PB_Tree_Checked) Break EndIf Next j Next i If GetGadgetState(DID("expandsingle")) > 0 DisableGadget(DID("alignsingle"), 0) Else DisableGadget(DID("alignsingle"), 1) EndIf EndIf Case "expand" ;check if it is a singlebox or hbox or vbox If Box DisableGadget(DID("alignbox"), 1) DisableGadget(DID("expandboxitem"), 1) If c$ = "yes" SetGadgetState(DID("expandbox"), 0) ElseIf c$ = "no" SetGadgetState(DID("expandbox"), 1) DisableGadget(DID("alignbox"), 0) ElseIf c$ = "equal" SetGadgetState(DID("expandbox"), 2) ElseIf Left(c$, 4) = "item" And FindString(b$, ":") SetGadgetState(DID("expandbox"), 3) SetGadgetText(DID("expandboxitem"), Trim(StringField(c$, 2, ":"))) DisableGadget(DID("expandboxitem"), 0) Else SetGadgetState(DID("expandbox"), -1) EndIf Else DisableGadget(DID("alignsingle"), 0) If c$ = "yes" DisableGadget(DID("alignsingle"), 1) SetGadgetState(DID("expandsingle"), 0) ElseIf c$ = "no" SetGadgetState(DID("expandsingle"), 1) ElseIf c$ = "vertical" SetGadgetState(DID("expandsingle"), 2) ElseIf c$ = "horizontal" SetGadgetState(DID("expandsingle"), 3) Else SetGadgetState(DID("expandsingle"), -1) DisableGadget(DID("alignsingle"), 1) EndIf EndIf Case "colexpand", "rowexpand" ;combo box! DisableGadget(DID(a$ + "item"), 1) If c$ = "yes" SetGadgetState(DID(a$), 0) ElseIf c$ = "no" SetGadgetState(DID(a$), 1) ElseIf c$ = "equal" SetGadgetState(DID(a$), 2) ElseIf Left(c$, 4) = "item" And FindString(b$, ":") SetGadgetState(DID(a$), 3) DisableGadget(DID(a$ + "item"), 0) SetGadgetText(DID(a$ + "item"), StringField(Trim(b$), 2, ":")) Else SetGadgetState(DID(a$), -1) EndIf Case "margin" ;combobox! If Str(Val(c$)) = c$ ;this is just a number! SetGadgetText(DID("margincombo"), c$) DisableGadget(DID("marginext"), 1) Else For i = 0 To CountGadgetItems(DID("margincombo")) - 1 For j = 0 To CountString(c$, ",") If FindString(StringField(c$, j + 1, ","), GetGadgetItemText(DID("margincombo"), i)) SetGadgetItemText(DID("margincombo"), i, StringField(c$, j + 1, ",")) Break EndIf Next j Next i SetGadgetState(DID("margincombo"), 0) SetGadgetText(DID("marginext"), StringField(GetGadgetText(DID("margincombo")), 2, ":")) DisableGadget(DID("marginext"), 0) EndIf Case "minwidth", "minheight", "minheight", "maxwidth" If c$ = "auto" SetGadgetText(DID(a$), "") Else SetGadgetText(DID(a$), b$) EndIf Case "_onevent", "_onchange", "_onfocus", "_ondragstart", "_onrightclick", "_onleftclick", "_onrightdoubleclick", "_onleftdoubleclick" For i = 0 To CountGadgetItems(DID("onevents")) - 1 If GetGadgetItemText(DID("onevents"), i) = Mid(a$, 2) SetGadgetItemText(DID("onevents"), i, Mid(a$, 2) + ":" + c$) Break EndIf Next i Default SetGadgetText(DID(a$), b$) EndSelect Wend EndIf EndIf EndIf EndIf RefreshDialog(#Dialog_Main) EndProcedure Procedure BuildUpTree(*node = 0, TreePos = 0) ;rebuild the whole ObjectTree Protected *NextNode, Type, Name.s, Attr.s, a$, b$, First, i Protected *Parent, Count, *Last ;xml fix If *node = 0 First = #True *node = RootXMLNode(#XML_Loaded) ClearGadgetItems(DID("tree_objects")) EndIf Type = XMLNodeType(*node) If Type = #PB_XML_Root ;o.k., nothing to do here, go on BuildUpTree(ChildXMLNode(*node)) ElseIf Type = #PB_XML_Normal *Parent = ParentXMLNode(*node) Count = XMLChildCount(*Parent) *Last = ChildXMLNode(*Parent, Count) ;change attributes, which we can't directly handle ;e.g. "id" into "_id", because we would need runtime variables to show such a dialog. Repeat Name = GetXMLNodeName(*node) If ExamineXMLAttributes(*node) While NextXMLAttribute(*node) a$ = XMLAttributeName(*node) Select LCase(a$) Case "id", "onevent", "onchange", "onfocus", "ondragstart", "onrightclick", "onleftclick", "onrightdoubleclick", "onleftdoubleclick" b$ = XMLAttributeValue(*node) RemoveXMLAttribute(*node, a$) SetXMLAttribute(*node, "_" + a$, b$) EndSelect Wend EndIf Attr = GetXMLAttribute(*node, "name") If Attr Name + " (" + Attr + ")" Else Attr = GetXMLAttribute(*node, "_id") If Attr Name + " (id: " + Attr + ")" EndIf EndIf AddGadgetItem(DID("tree_objects"), -1, Name, 0, TreePos) SetGadgetItemData(DID("tree_objects"), CountGadgetItems(DID("tree_objects")) - 1, *node) *NextNode = ChildXMLNode(*node) If *NextNode BuildUpTree(*NextNode, TreePos + 1) EndIf ;fix If *node = *Last Break EndIf *node = NextXMLNode(*node) Until *node = 0 EndIf If First For i = 0 To CountGadgetItems(DID("tree_objects")) - 1 SetGadgetItemState(DID("tree_objects"), i, #PB_Tree_Expanded) Next i EndIf EndProcedure Runtime Procedure OnObjectTreeDrag() ;User starts a drag&drop action, store Item in variable "DragNode" Protected i i = GetGadgetState(DID("tree_objects")) If i > -1 DragNode = GetGadgetItemData(DID("tree_objects"), i) Select GetXMLNodeName(DragNode) Case "window", "dialogs" ;no moving supported Default DragPrivate(1, #PB_Drag_Move) EndSelect EndIf EndProcedure Procedure DropCallback(ZielHandle, Status, Format, Aktion, x, y) ;callback, while dragging. We need to find the item under the mouse. Need API unfortunately here. Protected i, *Node, *Parent, a$, MovedType, H, Add, Count, Name.s, MaxChilds.i, UsableChilds.i, ParentType.s, *Temp, GoOn CompilerIf #PB_Compiler_OS = #PB_OS_MacOS Protected Frame.NSRect CompilerEndIf Static Result Select Status Case #PB_Drag_Enter, #PB_Drag_Leave Result = #True Case #PB_Drag_Update CompilerSelect #PB_Compiler_OS CompilerCase #PB_OS_Windows H = SendMessage_(GadgetID(DID("tree_objects")), 4380, 0, 0) ;#TVM_GETITEMHEIGHT = 4380 CompilerCase #PB_OS_Linux gtk_tree_view_column_cell_get_size_(gtk_tree_view_get_column_(GadgetID(DID("tree_objects")), 0), #Null, #Null, #Null, #Null, @H) gtk_widget_style_get(GadgetID(DID("tree_objects")), "vertical-separator", @Add, 0) H + Add CompilerCase #PB_OS_MacOS CocoaMessage(@Frame, GadgetID(DID("tree_objects")), "frameOfOutlineCellAtRow:", 0) H = Frame\size\height CompilerEndSelect Count = CountGadgetItems(DID("tree_objects")) i = Int(y / H) Result = #False If i >= 0 And i < Count ;not all combinations are allowed, we try to find out if the node under the mouse cursor is o.k. or not *Node = GetGadgetItemData(DID("tree_objects"), i) Name = GetXMLNodeName(*Node) a$ = GetXMLNodeName(DragNode) MovedType = DD(a$)\Type *Parent = ParentXMLNode(DragNode) If *Parent ParentType = GetXMLNodeName(*Parent) EndIf If Name <> "dialogs" And *Node <> DragNode And *Node <> *Parent ;AND Name <> "window" GoOn = #True If ParentType = "window" ;be careful, if we move the child of a window inside the same window, the whole childs will be no longer reachable! ;so make sure, that our new position is not inside the same window! *Temp = *Node While GetXMLNodeName(*Temp) <> "window" *Temp = ParentXMLNode(*Temp) Wend If *Temp = *Parent ;moving to same window is NOT allowed! GoOn = #False EndIf EndIf If GoOn MaxChilds = DD(Name)\MaxChilds UsableChilds = DD(Name)\UsableChilds If (UsableChilds = -1 Or MovedType = UsableChilds) And (MaxChilds = -1 Or MaxChilds > XMLChildCount(*Node)) Result = #True EndIf EndIf EndIf EndIf EndSelect ProcedureReturn Result EndProcedure Procedure SelectTreeItem(*Node) ;just a stupid procedure, because I needed it quite often. Rebuild the whole ObjectTree and select the correct item afterwards Protected i BuildUpTree() For i = 0 To CountGadgetItems(DID("tree_objects")) - 1 If GetGadgetItemData(DID("tree_objects"), i) = *Node SetGadgetState(DID("tree_objects"), i) Break EndIf Next i EndProcedure Procedure OnObjectTreeDrop() ;We took care already within the DropCallBack(), so just drop it without any further testing Protected i, *Node i = GetGadgetState(DID("tree_objects")) If i > -1 *Node = GetGadgetItemData(DID("tree_objects"), i) MoveXMLNode(DragNode, *Node, -1) SelectTreeItem(DragNode) UpdateDialog(*Node) EndIf EndProcedure Procedure OnMenuMoveUp() ;user wants to move the node up within the same parent Protected *Prev, *Parent, Index, *Node Index = GetGadgetState(DID("tree_objects")) If Index > -1 *Node = GetGadgetItemData(DID("tree_objects"), Index) *Parent = ParentXMLNode(*Node) If *Parent *Prev = PreviousXMLNode(*Node) If *Prev If *Prev = ChildXMLNode(*Parent, 1) *Prev = 0 Else *Prev = PreviousXMLNode(*Prev) EndIf MoveXMLNode(*Node, *Parent, *Prev) SelectTreeItem(*Node) UpdateDialog(*Node) EndIf EndIf EndIf EndProcedure Procedure OnMenuMoveDown() ;user wants to move the node down within the same parent Protected *Next, *Parent, Index, *Node, *N2 Index = GetGadgetState(DID("tree_objects")) If Index > -1 *Node = GetGadgetItemData(DID("tree_objects"), Index) *Parent = ParentXMLNode(*Node) If *Parent *Next = NextXMLNode(*Node) If *Node = ChildXMLNode(*Parent, 1) *N2 = 0 Else *N2 = PreviousXMLNode(*Node) EndIf If *Next MoveXMLNode(*Next, *Parent, *N2) SelectTreeItem(*Node) UpdateDialog(*Node) EndIf EndIf EndIf EndProcedure Procedure OnMenuAddWindow() ;Add a new window and show the temporary preview already Protected *Node, Index, *NewNode *Node = SelectDDFromTree() If *Node Index = GetGadgetState(DID("tree_objects")) If DD()\Type = #DialogType_Dialogs *NewNode = CreateXMLNode(*Node, "window", -1) SetXMLAttribute(*NewNode, "name", GetTempName("window")) AddElement(OpenDialogs()) OpenDialogs()\DialogID = CreateDialog(#PB_Any) OpenDialogs()\Node = *NewNode OpenDialogs()\UpdateTimeOUT = 100 SelectTreeItem(*NewNode) OnObjectTreeClick() EndIf EndIf EndProcedure Procedure OnMenuAddChild() ;Add a child Protected *Node, Index, Type, *NewNode Index = GetGadgetState(DID("tree_objects")) If Index > -1 *Node = GetGadgetItemData(DID("tree_objects"), Index) Type = EventMenu() ForEach DD() If DD()\Type = Type Break EndIf Next *NewNode = CreateXMLNode(*Node, MapKey(DD()), -1) Select Type Case #DialogType_HBox, #DialogType_MultiBox, #DialogType_Empty, #DialogType_GridBox, #DialogType_SingleBox, #DialogType_Tab, #DialogType_VBox ;no name Default SetXMLAttribute(*NewNode, "name", GetTempName(MapKey(DD()))) EndSelect SelectTreeItem(*NewNode) OnObjectTreeClick() EndIf EndProcedure Procedure OnMenuDelete() ;Delete a child Protected *Node, Index, *Parent Index = GetGadgetState(DID("tree_objects")) If Index > -1 *Node = GetGadgetItemData(DID("tree_objects"), Index) If GetXMLNodeName(*Node) <> "dialogs" And MessageRequester("Delete", "If you delete this node, all childs will be deleted also!" + #LF$ + "Proceed?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes *Parent = ParentXMLNode(*Node) If GetXMLNodeName(*Node) = "window" ForEach OpenDialogs() If OpenDialogs()\Node = *Node CloseWindow(OpenDialogs()\WindowID) FreeDialog(OpenDialogs()\DialogID) DeleteElement(OpenDialogs()) Break EndIf Next EndIf DeleteXMLNode(*Node) SelectTreeItem(*Parent) UpdateDialog(*Node) EndIf EndIf EndProcedure Procedure LoadXMLFile(FileName.s) ;load a new XML file Protected Result.i If LoadXML(#XML_Loaded, FileName) = 0 LogIt("Unable to load '" + FileName + "'!") ElseIf XMLStatus(#XML_Loaded) <> #PB_XML_Success LogIt("Error in XML: " + XMLError(#XML_Loaded)) FreeXML(#XML_Loaded) Else BuildUpTree() Result = #True EndIf ProcedureReturn Result EndProcedure Procedure LoadDialogTypeData() ;read the gadget attributes and fill the DD() map Protected Name.s, a$, b$, Type, i Dim Flags.i(6) ClearMap(DD()) Restore DialogInfo Repeat Read.i Type If Type > -1 For i = 0 To 5 Read.i Flags(i) Next i Read.s Name AddMapElement(DD(), Name) DD()\Type = Type DD()\ImageID = 0 a$ = "" Repeat Read.s b$ If b$ If a$ a$ + "|" + b$ Else a$ = b$ EndIf EndIf Until b$ = "" DD()\PossibleFlags = a$ DD()\MaxChilds = Flags(0) DD()\UsableChilds = Flags(1) DD()\MinSupport = Flags(2) DD()\MaxSupport = Flags(3) DD()\ValueSupport = Flags(4) DD()\GroupSupport = Flags(5) EndIf Until Type = -1 EndProcedure Procedure SwitchAttributes(Mode = 0) ;some attributes will disturb the preview window. Therefore we will store them as _name and have to restore them before saving the XML. Protected i, *Node, Text.s, Attr.s, Search.s, Replace.s If Mode Replace = "_" Search = "" Else Replace = "" Search = "_" EndIf For i = 0 To CountGadgetItems(DID("tree_objects")) - 1 *Node = GetGadgetItemData(DID("tree_objects"), i) Restore ChangeAttributes Read.s Attr While Attr Text = GetXMLAttribute(*Node, Search + Attr) If Text RemoveXMLAttribute(*Node, Search + Attr) SetXMLAttribute(*Node, Replace + Attr, Text) EndIf Read.s Attr Wend Next i EndProcedure Runtime Procedure OnEventSaveDialog() ;Save or Save As clicked Protected FileName.s If ActiveFile And EventGadget() = DialogGadget(#Dialog_Main, "savefile") SwitchAttributes() FormatXML(#XML_Loaded, #PB_XML_ReFormat, 2) If SaveXML(#XML_Loaded, ActiveFile) = 0 LogIT("Unable to save '" + ActiveFile + "'!") EndIf SwitchAttributes(1) Else FileName = SaveFileRequester("Save Dialog", ActiveFile, "Dialogs (*.xml)|*.xml|All Files (*.*)|*.*", 0) If FileName If GetExtensionPart(FileName) <> "xml" FileName + ".xml" EndIf SwitchAttributes() FormatXML(#XML_Loaded, #PB_XML_ReFormat, 2) If SaveXML(#XML_Loaded, FileName) = 0 LogIT("Unable to save '" + ActiveFile + "'!") EndIf SwitchAttributes(1) ActiveFile = FileName EndIf EndIf EndProcedure Runtime Procedure OnEventNewDialog() ;New Dialog clicked If IsXML(#XML_Loaded) ForEach OpenDialogs() If OpenDialogs()\WindowID And IsWindow(OpenDialogs()\WindowID) CloseWindow(OpenDialogs()\WindowID) EndIf DeleteElement(OpenDialogs()) Next FreeXML(#XML_Loaded) EndIf If CreateXML(#XML_Loaded) CreateXMLNode(RootXMLNode(#XML_Loaded), "dialogs") EndIf ClearTexts() BuildUpTree() EndProcedure Runtime Procedure OnEventLoadDialog() ;Open Dialog clicked Protected FileName.s, Error.s FileName = OpenFileRequester("Open Dialog", ActiveFile, "Dialogs (*.xml)|*.xml|All Files (*.*)|*.*", 0) If FileName OnEventNewDialog() If LoadXMLFile(FileName) ActiveFile = FileName ShowAllDialogs() LogIt("'" + GetFilePart(FileName) + "' successfully loaded!") EndIf EndIf EndProcedure Procedure OpenWindow_Main() ;Opens main window, set all tooltipps, bind events, add items, add menus, ... Protected i NewList SH._SORTHELPER_() ForEach DD() If DD()\Type <> #DialogType_Dialogs AddElement(SH()) SH()\Name = MapKey(DD()) SH()\DD = @DD() EndIf Next SortStructuredList(SH(), #PB_Sort_Ascending, OffsetOf(_SORTHELPER_\Name), #PB_String) CatchXML(#XML_Main, ?MainDialog, ?MainDialogEnd - ?MainDialog, 0, #PB_Unicode) CreateDialog(#Dialog_Main) OpenXMLDialog(#Dialog_Main, #XML_Main, "Window_Main") DID("tree_objects") = DialogGadget(#Dialog_Main, "tree_objects") DID("_id") = DialogGadget(#Dialog_Main, "_id") DID("name") = DialogGadget(#Dialog_Main, "name") DID("text") = DialogGadget(#Dialog_Main, "text") DID("min") = DialogGadget(#Dialog_Main, "min") DID("max") = DialogGadget(#Dialog_Main, "max") DID("value") = DialogGadget(#Dialog_Main, "value") DID("group") = DialogGadget(#Dialog_Main, "group") DID("invisible") = DialogGadget(#Dialog_Main, "invisible") DID("disabled") = DialogGadget(#Dialog_Main, "disabled") DID("width") = DialogGadget(#Dialog_Main, "width") DID("height") = DialogGadget(#Dialog_Main, "height") DID("flags") = DialogGadget(#Dialog_Main, "flags") DID("onevents") = DialogGadget(#Dialog_Main, "onevents") DID("onevent_proc") = DialogGadget(#Dialog_Main, "onevent_proc") DID("minwidth") = DialogGadget(#Dialog_Main, "minwidth") DID("minheight") = DialogGadget(#Dialog_Main, "minheight") DID("maxwidth") = DialogGadget(#Dialog_Main, "maxwidth") DID("maxheight") = DialogGadget(#Dialog_Main, "maxheight") DID("spacing") = DialogGadget(#Dialog_Main, "spacing") DID("alignbox") = DialogGadget(#Dialog_Main, "alignbox") DID("expandbox") = DialogGadget(#Dialog_Main, "expandbox") DID("expandboxitem") = DialogGadget(#Dialog_Main, "expandboxitem") DID("columns") = DialogGadget(#Dialog_Main, "columns") DID("colspacing") = DialogGadget(#Dialog_Main, "colspacing") DID("rowspacing") = DialogGadget(#Dialog_Main, "rowspacing") DID("colexpand") = DialogGadget(#Dialog_Main, "colexpand") DID("colexpanditem") = DialogGadget(#Dialog_Main, "colexpanditem") DID("rowexpand") = DialogGadget(#Dialog_Main, "rowexpand") DID("rowexpanditem") = DialogGadget(#Dialog_Main, "rowexpanditem") DID("margincombo") = DialogGadget(#Dialog_Main, "margincombo") DID("marginext") = DialogGadget(#Dialog_Main, "marginext") DID("expandsingle") = DialogGadget(#Dialog_Main, "expandsingle") DID("alignsingle") = DialogGadget(#Dialog_Main, "alignsingle") DID("expandwidth") = DialogGadget(#Dialog_Main, "expandwidth") DID("expandheight") = DialogGadget(#Dialog_Main, "expandheight") DID("firstmin") = DialogGadget(#Dialog_Main, "firstmin") DID("secondmin") = DialogGadget(#Dialog_Main, "secondmin") DID("colspan") = DialogGadget(#Dialog_Main, "colspan") DID("rowspan") = DialogGadget(#Dialog_Main, "rowspan") SetGadgetAttribute(DialogGadget(#Dialog_Main, "newfile"), #PB_Button_Image, ImageID(CatchImage(#PB_Any, ?Icon_New))) SetGadgetAttribute(DialogGadget(#Dialog_Main, "loadfile"), #PB_Button_Image, ImageID(CatchImage(#PB_Any, ?Icon_Load))) SetGadgetAttribute(DialogGadget(#Dialog_Main, "savefile"), #PB_Button_Image, ImageID(CatchImage(#PB_Any, ?Icon_Save))) SetGadgetAttribute(DialogGadget(#Dialog_Main, "savefileas"), #PB_Button_Image, ImageID(CatchImage(#PB_Any, ?Icon_SaveAs))) EnableGadgetDrop(DID("tree_objects"), #PB_Drop_Private, #PB_Drag_Move, 1) SetDropCallback(@DropCallback()) AddWindowTimer(DialogWindow(#Dialog_Main), #Main_Timer, 50) GadgetToolTip(DialogGadget(#Dialog_Main, "newfile"), "New Dialog") GadgetToolTip(DialogGadget(#Dialog_Main, "loadfile"), "Open Dialog...") GadgetToolTip(DialogGadget(#Dialog_Main, "savefile"), "Save Dialog") GadgetToolTip(DialogGadget(#Dialog_Main, "savefileas"), "Save Dialog As...") GadgetToolTip(DID("_id"), "Leave empty for #PB_Any") GadgetToolTip(DID("min"), "Leave empty if you don't need it") GadgetToolTip(DID("max"), "Leave empty if you don't need it") GadgetToolTip(DID("invisible"), "If ticked, it will be not shown") GadgetToolTip(DID("disabled"), "If ticked, it will be disabled") GadgetToolTip(DID("flags"), "De/Activate Flags") GadgetToolTip(DID("minwidth"), "Leave empty for auto mode") GadgetToolTip(DID("maxwidth"), "Leave empty for auto mode") GadgetToolTip(DID("minheight"), "Leave empty for auto mode") GadgetToolTip(DID("maxheight"), "Leave empty for auto mode") GadgetToolTip(DID("spacing"), "Spacing between Childs, leave empty to use default") GadgetToolTip(DID("colspacing"), "Leave empty to use default value") GadgetToolTip(DID("rowspacing"), "Leave empty to use default value") GadgetToolTip(DID("margincombo"), "Enter value or select item wise") GadgetToolTip(DID("expandwidth"), "Leave empty tp use default value") ;Init Comboboxes AddGadgetItem(DID("expandbox"), -1, "yes") AddGadgetItem(DID("expandbox"), -1, "no") AddGadgetItem(DID("expandbox"), -1, "equal") AddGadgetItem(DID("expandbox"), -1, "item:") AddGadgetItem(DID("alignbox"), -1, "top/left") AddGadgetItem(DID("alignbox"), -1, "center") AddGadgetItem(DID("alignbox"), -1, "bottom/right") AddGadgetItem(DID("colexpand"), -1, "yes") AddGadgetItem(DID("colexpand"), -1, "no") AddGadgetItem(DID("colexpand"), -1, "equal") AddGadgetItem(DID("colexpand"), -1, "item:") AddGadgetItem(DID("rowexpand"), -1, "yes") AddGadgetItem(DID("rowexpand"), -1, "no") AddGadgetItem(DID("rowexpand"), -1, "equal") AddGadgetItem(DID("rowexpand"), -1, "item:") AddGadgetItem(DID("expandsingle"), -1, "yes") AddGadgetItem(DID("expandsingle"), -1, "no") AddGadgetItem(DID("expandsingle"), -1, "vertical") AddGadgetItem(DID("expandsingle"), -1, "horizontal") AddGadgetItem(DID("alignsingle"), -1, "top") AddGadgetItem(DID("alignsingle"), -1, "left") AddGadgetItem(DID("alignsingle"), -1, "bottom") AddGadgetItem(DID("alignsingle"), -1, "right") AddGadgetItem(DID("alignsingle"), -1, "center") ResetMarginCombo() ResetOnEvents() ;BindEvents BindEvent(#PB_Event_GadgetDrop, @OnObjectTreeDrop(), DialogWindow(#Dialog_Main), DID("tree_objects")) BindEvent(#PB_Event_Timer, @OnTimerEvent(), DialogWindow(#Dialog_Main)) CreatePopupMenu(#Popup_Menu_Tree) MenuItem(#TreeMenu_AddWindow, "Add Window") MenuBar() OpenSubMenu("Add container") MenuItem(#DialogType_VBox, "vBox") MenuItem(#DialogType_HBox, "hBox") MenuItem(#DialogType_GridBox, "GridBox") MenuItem(#DialogType_MultiBox, "MultiBox") MenuItem(#DialogType_SingleBox, "SingleBox") CloseSubMenu() OpenSubMenu("Add Child") ForEach SH() Select SH()\DD\Type Case #DialogType_HBox, #DialogType_VBox, #DialogType_GridBox, #DialogType_MultiBox, #DialogType_SingleBox, #DialogType_Window ;ignore Default MenuItem(SH()\DD\Type, SH()\Name) EndSelect Next CloseSubMenu() MenuItem(#TreeMenu_MoveChildUp, "Move up") MenuItem(#TreeMenu_MoveChildDown, "Move down") MenuBar() MenuItem(#TreeMenu_Delete, "Delete...") BindMenuEvent(#Popup_Menu_Tree, #TreeMenu_MoveChildUp, @OnMenuMoveUp()) BindMenuEvent(#Popup_Menu_Tree, #TreeMenu_MoveChildDown, @OnMenuMoveDown()) BindMenuEvent(#Popup_Menu_Tree, #TreeMenu_AddWindow, @OnMenuAddWindow()) BindMenuEvent(#Popup_Menu_Tree, #TreeMenu_Delete, @OnMenuDelete()) For i = #DialogType_Window To #DialogType_SingleBox BindMenuEvent(#Popup_Menu_Tree, i, @OnMenuAddChild()) Next i RefreshDialog(#Dialog_Main) EndProcedure Procedure main() ;main procedure, not much in it, we use almost only bind events Protected F ;Init ElapsedMilliseconds() ;need this, because it will not run before you call it once (since when? PB5.62??) LoadDialogTypeData() ;initialize the DD() map OpenWindow_Main() ;open main window OnEventNewDialog() ;reset all gadgets to default OnObjectTreeClick() ;make sure that all is disabled, as long as no tree item is selected Repeat Select WaitWindowEvent() Case #PB_Event_CloseWindow F = #False ForEach OpenDialogs() If OpenDialogs()\WindowID And OpenDialogs()\WindowID = EventWindow() F = #True HideWindow(EventWindow(), 1) ;we just hide the window, no need to close it now, will reopen as soon as user changes something Break EndIf Next If F = #False Break ;main window closing... EndIf EndSelect ForEver EndProcedure main() End DataSection DialogInfo: Data.i #DialogType_Dialogs, -1, #DialogType_Window, 0, 0, 0, 0 ;<- Type, Max Childs (-1 = no limit), Possible Childs, min support, max support, value support, group support Data.s "dialogs", "" ;<- name in XML, pssible flags ends with "" ; Data.i #DialogType_Window, 1, -1, 0, 0, 0, 0 Data.s "window" Data.s "#PB_Window_SystemMenu", "#PB_Window_MinimizeGadget", "#PB_Window_MaximizeGadget", "#PB_Window_SizeGadget", "#PB_Window_Invisible" Data.s "#PB_Window_TitleBar", "#PB_Window_Tool", "#PB_Window_BorderLess", "#PB_Window_ScreenCentered", "#PB_Window_WindowCentered" Data.s "#PB_Window_Maximize", "#PB_Window_Minimize", "#PB_Window_NoGadgets", "#PB_Window_NoActivate", "" ; Data.i #DialogType_Button, 0, 0, 0, 0, 0, 0 Data.s "button" Data.s "#PB_Button_Right", "#PB_Button_Left", "#PB_Button_MultiLine", "#PB_Button_Default", "#PB_Button_Toggle", "" ; Data.i #DialogType_ButtonImage, 0, 0, 0, 0, 0, 0 Data.s "buttonimage" Data.s "#PB_Button_Toggle", "" ; Data.i #DialogType_Calendar, 0, 0, 0, 0, 0, 0 Data.s "calendar" CompilerIf #PB_Compiler_OS = #PB_OS_Windows Data.s "#PB_Calendar_Borderless" CompilerEndIf Data.s "" ; Data.i #DialogType_Canvas, 0, 0, 0, 0, 0, 0 Data.s "canvas" Data.s "#PB_Canvas_Border", "#PB_Canvas_ClipMouse", "#PB_Canvas_Keyboard", "#PB_Canvas_DrawFocus", "" ; Data.i #DialogType_CheckBox, 0, 0, 0, 0, 0, 0 Data.s "checkbox" Data.s "#PB_CheckBox_Right", "#PB_CheckBox_Center", "#PB_CheckBox_ThreeState", "" ; Data.i #DialogType_ComboBox, 0, 0, 0, 0, 0, 0 Data.s "combobox" Data.s "#PB_ComboBox_Editable", "#PB_ComboBox_LowerCase", "#PB_ComboBox_UpperCase", "#PB_ComboBox_Image", "" ; Data.i #DialogType_Container, 1, -1, 0, 0, 0, 0 Data.s "container" Data.s "#PB_Container_BorderLess", "#PB_Container_Flat", "#PB_Container_Raised", "#PB_Container_Single", "#PB_Container_Double", "" ; Data.i #DialogType_Date, 0, 0, 0, 0, 0, 0 Data.s "date" Data.s "#PB_Date_UpDown", "#PB_Date_CheckBox", "" ; Data.i #DialogType_Editor, 0, 0, 0, 0, 0, 0 Data.s "editor" Data.s "#PB_Editor_ReadOnly", "" ; Data.i #DialogType_ExplorerCombo, 0, 0, 0, 0, 0, 0 Data.s "explorercombo" Data.s "#PB_Explorer_DrivesOnly", "#PB_Explorer_Editable", "#PB_Explorer_NoMyDocuments", "" ; Data.i #DialogType_ExplorerList, 0, 0, 0, 0, 0, 0 Data.s "explorerlist" Data.s "#PB_Explorer_BorderLess", "#PB_Explorer_AlwaysShowSelection", "#PB_Explorer_MultiSelect", "#PB_Explorer_GridLines", "#PB_Explorer_HeaderDragDrop" Data.s "#PB_Explorer_FullRowSelect", "#PB_Explorer_NoFiles", "#PB_Explorer_NoFolders", "#PB_Explorer_NoParentFolder", "#PB_Explorer_NoDirectoryChange" Data.s "#PB_Explorer_NoDriveRequester", "#PB_Explorer_NoSort", "#PB_Explorer_NoMyDocuments", "#PB_Explorer_AutoSort", "" ; Data.i #DialogType_ExplorerTree, 0, 0, 0, 0, 0, 0 Data.s "explorertree" Data.s "#PB_Explorer_BorderLess", "#PB_Explorer_AlwaysShowSelection", "#PB_Explorer_NoLines", "#PB_Explorer_NoButtons", "#PB_Explorer_NoFiles" Data.s "#PB_Explorer_NoDriveRequester", "#PB_Explorer_NoMyDocuments", "#PB_Explorer_AutoSort", "" ; Data.i #DialogType_Frame, 1, -1, 0, 0, 0, 0 Data.s "frame" Data.s "#PB_Frame_Single", "#PB_Frame_Double", "#PB_Frame_Flat", "" ; Data.i #DialogType_HyperLink, 0, 0, 0, 0, 0, 0 Data.s "hyperlink" Data.s "#PB_Hyperlink_Underline", "" ; Data.i #DialogType_Image, 0, 0, 0, 0, 0, 0 Data.s "image" Data.s "#PB_Image_Border", "" ; Data.i #DialogType_IPAddress, 0, 0, 0, 0, 0, 0 Data.s "ipaddress", "" ; Data.i #DialogType_ListIcon, 0, 0, 0, 0, 0, 0 Data.s "listicon" Data.s "#PB_ListIcon_CheckBoxes", "#PB_ListIcon_ThreeState", "#PB_ListIcon_MultiSelect", "#PB_ListIcon_GridLines", "#PB_ListIcon_FullRowSelect" Data.s "#PB_ListIcon_HeaderDragDrop", "#PB_ListIcon_AlwaysShowSelection", "" ; Data.i #DialogType_ListView, 0, 0, 0, 0, 0, 0 Data.s "listview" Data.s "#PB_ListView_Multiselect", "#PB_ListView_ClickSelect", "" ; Data.i #DialogType_Option, 0, 0, 0, 0, 0, 1 Data.s "option", "" ; Data.i #DialogType_Panel, -1, #DialogType_Tab, 0, 0, 0, 0 Data.s "panel", "" ; Data.i #DialogType_ProgressBar, 0, 0, 1, 1, 1, 0 Data.s "progressbar" Data.s "#PB_ProgressBar_Smooth", "#PB_ProgressBar_Vertical", "" ; Data.i #DialogType_ScrollArea, 1, -1, 0, 0, 0, 0 Data.s "scrollarea" Data.s "#PB_ScrollArea_Flat", "#PB_ScrollArea_Raised", "#PB_ScrollArea_Single", "#PB_ScrollArea_BorderLess", "#PB_ScrollArea_Center", "" ; Data.i #DialogType_ScrollBar, 0, 0, 1, 1, 0, 0 Data.s "scrollbar" Data.s "#PB_ScrollBar_Vertical", "" ; Data.i #DialogType_Spin, 0, 0, 1, 1, 1, 0 Data.s "spin" Data.s "#PB_Spin_ReadOnly", "#PB_Spin_Numeric", "" ; Data.i #DialogType_Splitter, 2, -1, 0, 0, 0, 0 Data.s "splitter" Data.s "#PB_Splitter_Vertical", "#PB_Splitter_Separator", "#PB_Splitter_FirstFixed", "#PB_Splitter_SecondFixed", "" ; Data.i #DialogType_String, 0, 0, 0, 0, 0, 0 Data.s "string" Data.s "#PB_String_Numeric", "#PB_String_Password", "#PB_String_ReadOnly", "#PB_String_LowerCase", "#PB_String_UpperCase", "#PB_String_BorderLess", "" ; Data.i #DialogType_Text, 0, 0, 0, 0, 0, 0 Data.s "text" Data.s "#PB_Text_Center", "#PB_Text_Right", "#PB_Text_Border", "" ; Data.i #DialogType_TrackBar, 0, 0, 1, 1, 1, 0 Data.s "trackbar" Data.s "#PB_TrackBar_Ticks", "#PB_TrackBar_Vertical", "" ; Data.i #DialogType_Tree, 0, 0, 0, 0, 0, 0 Data.s "tree" Data.s "#PB_Tree_AlwaysShowSelection", "#PB_Tree_NoLines", "#PB_Tree_NoButtons", "#PB_Tree_CheckBoxes", "#PB_Tree_ThreeState", "" ; Data.i #DialogType_Web, 0, 0, 0, 0, 0, 0 Data.s "web", "" ; Data.i #DialogType_Tab, 1, -1, 0, 0, 0, 0 Data.s "tab", "" ; Data.i #DialogType_Empty, 0, 0, 0, 0, 0, 0 Data.s "empty", "" ; Data.i #DialogType_HBox, -1, -1, 0, 0, 0, 0 Data.s "hbox", "" ; Data.i #DialogType_VBox, -1, -1, 0, 0, 0, 0 Data.s "vbox", "" ; Data.i #DialogType_GridBox, -1, -1, 0, 0, 0, 0 Data.s "gridbox", "" ; Data.i #DialogType_MultiBox, -1, -1, 0, 0, 0, 0 Data.s "multibox", "" ; Data.i #DialogType_SingleBox, 1, -1, 0, 0, 0, 0 Data.s "singlebox", "" ; Data.i -1 ;end ; ChangeAttributes: ;those attributes can be used, but we will store them different, e.g. "_id" instead of "id", otherwise the live previews might make problems Data.s "id", "onevent", "onchange", "onfocus", "ondragstart", "onrightclick", "onleftclick", "onrightdoubleclick", "onleftdoubleclick", "" MainDialog: Data.s ~"" + ~"" + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~" " + ~"" MainDialogEnd: Icon_New: Data.l $474E5089, $0A1A0A0D, $0D000000, $52444849, $18000000, $18000000, $00000608, $3D77E000, $010000F8, $41444928, $63C74854, $0E038060, $87060601, $4BB1D206, $BF030307, $E061033C Data.l $B0E0E0D0, $FD7D7FE0, $BDB0927E, $9CFFFCFD, $196FD59C, $08385818, $40D2005A, $09E9002A, $57FE5C0C, $07753050, $E1002CCD, $1F55A4A4, $2B1D3939, $08016669, $784C1818, $E0A0C0CF Data.l $600B7540, $BE5E5771, $6F2F3FFB, $060657E3, $169C3D71, $FDFF7FBC, $0AC0407F, $787C26B0, $60F3FCFE, $7F9FCE0B, $0CE9118E, $F0333E0C, $FEFF60FA, $FDF104FB, $FA71EFFB, $A97C9208 Data.l $5B244414, $A1106C40, $11505063, $826203ED, $1C831D08, $08823436, $70201416, $F27DFEFF, $A0989922, $07070100, $7ED8A007, $B222A5DA, $4416C02C, $CBB23E20, $B601F629, $900181A0 Data.l $606C3081, $BFBFF060, $8C451FBF, $190220A2, $0C357200, $8008080B, $8B16412D, $2F27EF8F, $EC141515, $21106DA0, $9DC1CF27, $EB01488A, $0607AFD7, $2DE27BE9, $47D2A720, $703320C7 Data.l $40612058, $1B05B35E, $01059906, $37AFFD00, $23B2C5B9, $000000B7, $4E454900, $6042AE44 Data.b $82 Icon_Load: Data.l $474E5089, $0A1A0A0D, $0D000000, $52444849, $18000000, $18000000, $00000608, $3D77E000, $000000F8, $414449BA, $63C74854, $C0361860, $66DD9D58, $01C48D71, $2A9ADC64, $8B8F873C Data.l $C3628049, $9745B2FB, $F0A45F5D, $DD82DD1B, $AFB7327D, $A9FF942E, $47A6CB26, $97370591, $65C5FC28, $C8967748, $12B5A592, $3935CD07, $18C5881C, $AA5ADC86, $E5971FF0, $569A20A0 Data.l $497EB628, $627EC48D, $B269B1F1, $38F56DCF, $80B2883D, $CA2D201C, $04B200A2, $60DC82C5, $626A0681, $ACEC9990, $200C1C8C, $B43883EF, $A4DB1BC0, $CAD033CE, $B51E1870, $5182D460 Data.l $0585860B, $568F52A0, $205E5F86, $54019DFF, $D652936E, $EC838293, $7E861278, $36000263, $61D3C731, $001E3CCA, $49000000, $AE444E45 Data.b $42, $60, $82 Icon_Save: Data.l $474E5089, $0A1A0A0D, $0D000000, $52444849, $18000000, $18000000, $00000608, $3D77E000, $000000F8, $41444994, $63C74854, $16030060, $8086060E, $0D0C0CF9, $4383A9FF, $F0303396 Data.l $80203048, $A2480649, $5500E1A1, $9B12C430, $1C0B240A, $D482401A, $400B1002, $405A8E66, $A5700B2D, $460B5196, $416FC02D, $A206C242, $5A901ECB, $8C407CB2, $9386E825, $2CF8441C Data.l $593866C1, $12CD8071, $5D93865C, $825B2054, $CA8A70CF, $84C19022, $AE2D1F0C, $A005AD07, $95DA9A0A, $A0058A3E, $7DC14626, $4A5B35EA, $4830339E, $064C8018, $E48D6100, $52583C56 Data.l $00000030, $4E454900, $6042AE44 Data.b $82 Icon_SaveAs: Data.l $474E5089, $0A1A0A0D, $0D000000, $52444849, $18000000, $18000000, $00000608, $3D77E000, $000000F8, $414449B0, $63C74854, $FF030060, $190C0CB9, $29C789E7, $121819C7, $1EC7E3F6 Data.l $D0080CFD, $1C349FF0, $418180B0, $063F01C1, $02DB23A9, $82060687, $905B7060, $4C120171, $1C7EB0B8, $C7C9059A, $1084B748, $6481394E, $0DCBC801, $B005A9FF, $B770E304, $8F385700 Data.l $016A305A, $12120B7E, $6B9D1036, $F2C96A41, $A0963101, $10724E1B, $9B04B3E1, $01C564E1, $19704B36, $8151764E, $C33E096C, $408B2A29, $7C321306, $9B3B0AA0, $4360900A, $60AA01C3 Data.l $48F0162C, $DC143030, $566D5EA7, $41819CF2, $326400C2, $F5309100, $F5D2A3C0, $00000075, $4E454900, $6042AE44 Data.b $82 EndDataSection ; IDE Options = PureBasic 5.62 (Windows - x86) ; CursorPosition = 349 ; FirstLine = 323 ; Folding = ------- ; EnableXP ; EnableUser ; UseIcon = ..\Icons\Weby Icon Set\ICO\Tools.ico ; Executable = dd.exe ; CompileSourceDirectory ; EnableCompileCount = 447 ; EnableBuildCount = 4 ; EnableExeConstant