Tree Gadget Mini-Modul und Testprogramm (die Zweite)

Für allgemeine Fragen zur Programmierung mit PureBasic.
puretom
Beiträge: 109
Registriert: 06.09.2013 22:02

Tree Gadget Mini-Modul und Testprogramm (die Zweite)

Beitrag von puretom »

Hi!
Nach langer Abstinenz poste ich auch einmal wieder etwas.

Nachdem ich schon einmal eine kleine Tree-Gadget-Designstudie für mich gemacht habe und im Bereich "Code, Tipps und Tricks" gepostet habe, möchte ich meinen neuen Ansatz posten.
Den alten Code kann ich kaum mehr durchblicken, außerdem denke ich, dass ich das damals viel zu kompliziert gelöst habe.

Meine Bitte:
Guckt euch doch einmal, ob diese Sache funktioniert.
Ich habe mich persönlich mit Tree Gadgets immer furchtbar gequält.
Ist meine Lösung brauchbar, unkompliziert genug?
Kann man das besser oder anders machen?
Und vielleicht kann ja das Schnippsel jemand für sich brauchen.

Danke :-)

Code: Alles auswählen

EnableExplicit
;######################################################################################################################
;#  Routines
;######################################################################################################################
Procedure UnselectedFirstItem(tree)
  
  ; --- if no item is selected the new item will always placed as first item ---
  Protected selected_item_no = GetGadgetState(tree)  
  If selected_item_no = -1
    Protected node_name.s = InputRequester("Name", "Name:","")
    AddGadgetItem(tree, 0, node_name)
    SetGadgetState(tree, 0)
    ProcedureReturn #True
  EndIf
  
EndProcedure
Procedure AddAsFirstChild(tree)
  
  ; --- if no item is selected the new item will always placed as first item ---
  If UnselectedFirstItem(tree): ProcedureReturn: EndIf
  
  ; --- get name, finally add item and select the new added item ---
  Protected selected_item_no = GetGadgetState(tree)  
  Protected node_name.s = InputRequester("Name", "Name:","")
  Protected selected_sublevel =  GetGadgetItemAttribute(tree, selected_item_no, #PB_Tree_SubLevel)
  
  AddGadgetItem(tree, selected_item_no+1, node_name, 0, selected_sublevel+1)
  SetGadgetState(tree, selected_item_no+1)
  
EndProcedure
Procedure AddAsLastChild(tree)
  
  ; --- if no item is selected the new item will always placed as first item ---
  If UnselectedFirstItem(tree): ProcedureReturn: EndIf
  
  ; --- search for adding position ---
  Protected selected_item_no  = GetGadgetState(tree)    
  Protected selected_sublevel = GetGadgetItemAttribute(tree, selected_item_no, #PB_Tree_SubLevel)
  Protected no_tree_items     = CountGadgetItems(tree)-1
  Protected adding_item_no
  
  Debug "----"
  For adding_item_no = selected_item_no+1 To no_tree_items
    Protected current_sublevel = GetGadgetItemAttribute(tree, adding_item_no, #PB_Tree_SubLevel)
    Debug "Pos: "+adding_item_no+" Text: "+GetGadgetItemText(tree, adding_item_no)+"; If current_sublevel("+current_sublevel+") <= selected_sublevel("+selected_sublevel+")"
    If current_sublevel <= selected_sublevel: Break: EndIf ; <--- compare with debug output
  Next
  
  ; --- get name, finally add item and select the new added item ---
  Protected node_name.s = InputRequester("Name", "Name:","")  
  AddGadgetItem(tree, adding_item_no, node_name, 0, selected_sublevel+1); (*) <--
  SetGadgetState(tree, adding_item_no)  
  
EndProcedure
Procedure AddParallel(tree)
  
  ; --- if no item is selected the new item will always placed as first item ---
  If UnselectedFirstItem(tree): ProcedureReturn: EndIf
  
  ; --- search for adding position ---
  Protected selected_item_no  = GetGadgetState(tree)    
  Protected selected_sublevel = GetGadgetItemAttribute(tree, selected_item_no, #PB_Tree_SubLevel)
  Protected no_tree_items     = CountGadgetItems(tree)-1
  Protected adding_item_no
  
  Debug "----"
  For adding_item_no = selected_item_no+1 To no_tree_items
    Protected current_sublevel = GetGadgetItemAttribute(tree, adding_item_no, #PB_Tree_SubLevel)
    Debug "Pos: "+adding_item_no+" Text: "+GetGadgetItemText(tree, adding_item_no)+"; If current_sublevel("+current_sublevel+") <= selected_sublevel("+selected_sublevel+")"
    If current_sublevel <= selected_sublevel: Break: EndIf ; <--- compare with debug output
  Next
  
  ; --- get name, finally add item and select the new added item ---
  Protected node_name.s = InputRequester("Name", "Name:","")  
  AddGadgetItem(tree, adding_item_no, node_name, 0, selected_sublevel); (*) <--
  SetGadgetState(tree, adding_item_no)  
  
  
EndProcedure

; Info:
; AddParallel(tree) and AddAsLastChild(tree) are similiar except for one
; line of code (here --> (*))
; One could put it into one routine maybe with an option procedure argument.
; One could also put AddAsFirstChild(tree) in it with another procedure argument.
; For better understanding I let it like it is for now.

;######################################################################################################################
;#  Test Program
;######################################################################################################################
Enumeration Gadgets
  #tree
  #btnAddAsFirstChild
  #btnAddAsLastChild
  #btnAddParallel  
EndEnumeration
Procedure TestProgram()
  If OpenWindow(0, 0, 0, 800, 600, "Tree Gadget Procedures", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    
    TreeGadget(#tree, 0, 0, 600, 600, #PB_Tree_AlwaysShowSelection )
    ButtonGadget(#btnAddAsFirstChild, 620, 10, 160, 30, "Add as first child") 
    ButtonGadget(#btnAddAsLastChild, 620, 50, 160, 30, "Add as last child") 
    ButtonGadget(#btnAddParallel, 620, 100, 160, 30, "Add parallel") 
    
    Repeat
      Protected Event = WaitWindowEvent()
      Protected EventGadget = EventGadget()
      
      If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
        End
      ElseIf EventGadget = #btnAddAsFirstChild
        AddAsFirstChild(#tree)
      ElseIf EventGadget = #btnAddAsLastChild
        AddAsLastChild(#tree)
      ElseIf EventGadget = #btnAddParallel
        AddParallel(#tree)        
      EndIf
      
    ForEver
    
  EndIf
  
EndProcedure

TestProgram()
P.S. Die Comments sind in (schlechtem) Englisch ;-)
Windows 7 und Windows 10 (Laptop), PB 5.62 | Projekt: Tutorial - Compiler und Virtual Machine | vielleicht einmal ein Old School Text-Adventure Tutorial | Neu: Spielereien, Üben rund um OOP in PB
puretom
Beiträge: 109
Registriert: 06.09.2013 22:02

Re: Tree Gadget Mini-Modul und Testprogramm (die Zweite)

Beitrag von puretom »

Da ich gerade für mich an einer Design- und Machbarkeitsstudie zum Thema XMLDialog Editor herumspiele, habe ich eine bessere TreeGadget-Routine zum Einfügen eines items/nodes gebraucht:

Drum, zum selben Thema eine All-in-one-Procedure inspiriert von CreateXMLNode(...).

Vielleicht kanns ja mal wer testen und mir sagen, ob brauchbar bzw. Bugs :) ?

LG, puretom

Code: Alles auswählen

Procedure CreateTreeNode(tree, new_node_name.s, parent_node_pos, pos_mode=0, image=-1, select_new=#True)
  
  ; pos_mode   = -1     -> Tree node is inserted as LAST child of its parent
  ; pos_mode   =  0     -> Tree node is inserted as FIRST child of its parent (Standard)
  ; pos_mode   =  1     -> Tree node is inserted as PARALLEL node of its "parent"  
  ; image      = -1     -> no image
  ; select_new = #True  -> new added node will be selected
  
  Protected parent_node_sublevel, no_tree_items, added_childs_pos, current_sublevel
  Protected added_childs_sublevel
  
  ;---- forbidden: no item selected (-> nothing will happen) --------------------------------------
  If parent_node_pos < 0: ProcedureReturn: EndIf  
  
  ;---- get sublevel of the parent node -----------------------------------------------------------
  parent_node_sublevel = GetGadgetItemAttribute(tree, parent_node_pos, #PB_Tree_SubLevel)
  
  ;---- search for added_childs_pos ---------------------------------------------------------------
  no_tree_items  = CountGadgetItems(tree)-1
  
  Select pos_mode
      
    ;<--- -1: Tree node is inserted as LAST child of its parent       --->  
    ;<---  1: Tree node is inserted as PARALLEL node of its "parent"  --->        
    Case -1, 1
      For added_childs_pos = parent_node_pos + 1 To no_tree_items
        current_sublevel = GetGadgetItemAttribute(tree, added_childs_pos, #PB_Tree_SubLevel)
        If current_sublevel <= parent_node_sublevel: Break: EndIf
      Next
      If    pos_mode = -1 ; last child
        added_childs_sublevel = parent_node_sublevel + 1
      Else ;pos_mode =  1 ; parallel
        added_childs_sublevel = parent_node_sublevel
      EndIf
      
    ;<--- Tree node is inserted as FIRST child of its parent          --->    
    Case 0
      added_childs_pos = parent_node_pos + 1
      added_childs_sublevel = parent_node_sublevel + 1
      
    ;<--- outside of allowed range (-> nothing will happen)           --->  
    Default
      ProcedureReturn
      
  EndSelect
  
  ;---- add item and select the new added child item (take care of image) -------------------------
  Select image 
    Case -1: AddGadgetItem(tree, added_childs_pos, new_node_name, 0, added_childs_sublevel)    
    Default: AddGadgetItem(tree, added_childs_pos, new_node_name, ImageID(image), added_childs_sublevel)    
  EndSelect
  If select_new
    SetGadgetState(tree, added_childs_pos)  
  EndIf

  ;---- return back the pos of added child item ---------------------------------------------------
  ProcedureReturn added_childs_pos
  
EndProcedure
(Edit: Mit wählbarer Option, ob erzeugter Node gewählt werden soll, oder nicht)
Windows 7 und Windows 10 (Laptop), PB 5.62 | Projekt: Tutorial - Compiler und Virtual Machine | vielleicht einmal ein Old School Text-Adventure Tutorial | Neu: Spielereien, Üben rund um OOP in PB
Antworten