Page 1 of 1

Editable ComboboxGadget - inserting/deleting items

Posted: Tue Sep 27, 2016 8:28 pm
by Andre
As I think the following example shouldn't get "lost" inside the thread with coding questions, and I think it's of valuable help, I post it here for easier finding:

Code: Select all

; original thread: http://www.purebasic.fr/english/viewtopic.php?f=13&t=45043
; by RASHAD, extended by Andre

; Demonstration of an editable Combobox:
;   - items can be deleted by pressing 'Delete' on the current selection
;   - items can be added by pressing 'Insert' or 'Return' for finishing the current input

Enumeration
  #InsertItem
  #DeleteItem
EndEnumeration

Enumeration
  #ComboBox
EndEnumeration

OpenWindow(0, 0, 0, 350, 100 , "Editable Combobox - delete+insert items", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
ComboBoxGadget(#ComboBox, 10, 10, 280, 21, #PB_ComboBox_Editable )
For a = 1 To 20
  AddGadgetItem(#ComboBox, -1, "item " + Str(a))
Next
SetGadgetState(#ComboBox, 0)

AddKeyboardShortcut(#ComboBox, #PB_Shortcut_Delete, #DeleteItem)
AddKeyboardShortcut(#ComboBox, #PB_Shortcut_Insert, #InsertItem)
AddKeyboardShortcut(#ComboBox, #PB_Shortcut_Return, #InsertItem)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
     
    Case #PB_Event_Menu
      Select EventMenu()
        Case #DeleteItem
          If GetGadgetState(#ComboBox) >= 0     ; a Combobox item was selected before pressing the 'Delete' key
            Debug "Combobox item removed: " + GetGadgetText(#ComboBox)
            RemoveGadgetItem(#ComboBox, GetGadgetState(#ComboBox))
          EndIf
         
        Case #InsertItem
          ; Get current state and item of the editable combobox:
          a$ = GetGadgetText(#ComboBox)
          state = GetGadgetState(#ComboBox)
         
          If state = -1   ; Combobox is in edit-mode
            ; Check if such an entry is already existing in the Combobox items:
            existing = #False
            b = CountGadgetItems(#ComboBox)
            For a = 0 To b
              If GetGadgetItemText(#ComboBox, a) = a$
                existing = #True
                Break
              EndIf
            Next
           
            ; Now add the new item, if it isn't present yet:
            If existing = #False
              AddGadgetItem(#ComboBox, state, a$)      ; as state = -1, the new item will the added to the end of the item list
              Debug "New combobox item added: " + a$
            Else
              Debug "Combobox item with this text is already existing: " + a$
            EndIf
          Else
            Debug "Combobox item no. " + state + " selected, showing following text: " + a$
          EndIf
      EndSelect           
     
  EndSelect
Until Quit = 1
End

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Wed Sep 28, 2016 11:28 pm
by WilliamL
Seems straight-foward enough...

Well, on my Mac lap-top the 'Delete' key seems to map to #PB_Shortcut_Back for the delete item.

Code: Select all

AddKeyboardShortcut(#ComboBox, #PB_Shortcut_Back, #DeleteItem)
I also got an error when b was too many items so I had to subtract 1 to get the proper array range. (0-19)

Code: Select all

b = CountGadgetItems(#ComboBox)-1
Also, the only way I could get state to equal -1 was to take out the line that set the gadget state.

Code: Select all

;SetGadgetState(#ComboBox, 0)
I'm not sure how to get back to state=-1 once a selection is made.

Now it works fine. :)

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Wed Sep 28, 2016 11:35 pm
by Andre
Thank you for your feedback, WilliamL! :D

I will try on my MacBook too, as soon I have finished my little project on Windows and begin testing/using it on MacOS too (including needed adaptions, if any). Currently I can't say yet, if there are differences between Windows/MacOS handling, which would lead to some needed CompilerIf's... 8)

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Wed Sep 28, 2016 11:45 pm
by WilliamL
Hey Andre!

Thanks for posting something I could understand!

I noticed that there wasn't an 'insert' key on my keyboard and that 'return' worked for me, with your code, so it was good that you included both shortcuts. I guess if you are writing code for several platforms you will need to be looking for the right keys. :) In this case you didn't need a 'CompilerIf'' statement.

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Thu Sep 29, 2016 10:48 pm
by Andre
WilliamL wrote: Thanks for posting something I could understand!

I noticed that there wasn't an 'insert' key on my keyboard and that 'return' worked for me, with your code, so it was good that you included both shortcuts. I guess if you are writing code for several platforms you will need to be looking for the right keys. :) In this case you didn't need a 'CompilerIf'' statement.
Hi William,

thanks :D

I hadn't the time to check / adapt the code for MacOS yet.

But anyway I don't want to invest too much effort into the 'Editing' component of my project, as this is editor for data and multimedia ressources is internal for now. Another story the project itself, which is mostly 'Read-only' displaying the saved data etc.... :P
Something to show hopefully next year. 8)

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Thu Sep 29, 2016 11:45 pm
by WilliamL
This seems to work on my Mac...

[edited]

Code: Select all

Enumeration
  #InsertItem
  #DeleteItem
EndEnumeration

#ComboWnd=0

Enumeration
  #ComboBox
EndEnumeration

OpenWindow(#ComboWnd, 0, 0, 350, 100 , "Editable Combobox - delete+insert items", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
ComboBoxGadget(#ComboBox, 10, 10, 280, 21, #PB_ComboBox_Editable )
For a = 1 To 20
  AddGadgetItem(#ComboBox, -1, "item " + Str(a))
Next
;SetGadgetState(#ComboBox,19)
;if no SetGadgetState() is used then the first value given by GetGadgetState() will be -1

;AddKeyboardShortcut(#ComboBox, #PB_Shortcut_Delete, #DeleteItem)
AddKeyboardShortcut(#ComboWnd, #PB_Shortcut_Back, #DeleteItem) ; keep in mind that you can't use the 'Delete' key when typing text
;AddKeyboardShortcut(#ComboWnd, #PB_Shortcut_Insert, #InsertItem) ; same as 'add'
AddKeyboardShortcut(#ComboWnd, #PB_Shortcut_Return, #InsertItem)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Menu
      Select EventMenu()
        Case #DeleteItem
          If GetGadgetState(#ComboBox) >= 0     ; a Combobox item must be selected before pressing the 'Delete' key
            state = GetGadgetState(#ComboBox) ;: Debug "State="+Str(state)
            Debug "ComboBox "+Str(state+1)+" removed: " + GetGadgetText(#ComboBox)
            RemoveGadgetItem(#ComboBox,state) ; : Debug "New state="+Str(state)
            If State>CountGadgetItems(#ComboBox)-1 : state=CountGadgetItems(#ComboBox)-1 : EndIf
            SetGadgetText(#ComboBox,GetGadgetItemText(#combobox,state))
          EndIf
        Case #InsertItem
          ; Get current state and item of the editable combobox:
          a$ = GetGadgetText(#ComboBox)
          state = GetGadgetState(#ComboBox) : Debug "State="+Str(state)
          If state = -1   ; Combobox is in edit-mode ; should never happen since we SetGadgetState(5) above
              existing = #False
          Else
            b = CountGadgetItems(#ComboBox) ; Check if such an entry is already existing in the Combobox items
            For a = 0 To b-1
              If GetGadgetItemText(#ComboBox, a) = a$
                existing = #True : Debug "Existing"
                Break
              EndIf
            Next
          EndIf
        ; Now add the new item, if it isn't present yet:
        If existing = #False
          If state=-1
            AddGadgetItem(#ComboBox,-1, a$) ; new item will be added to end of list
          Else
            AddGadgetItem(#ComboBox,state+1, a$) ; new item will the added after last selected spot in list
          EndIf
          Debug "New combobox item added: " + a$
        Else
          Debug "Combobox item with this text is already existing: " + a$
        EndIf
      EndSelect           
  EndSelect
Until Quit = 1
End

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Fri Sep 30, 2016 10:57 pm
by Andre
Hi William,

thanks, this also work on Windows 10 x64 (still not tested on MacOS here).
I could easily activate the additional KeyboardShortcuts again to have more supported keys (Del/Back for deleting; Ins/Return for inserting).

SetGadgetState(#ComboBox, 0) for selecting the first combobox item or SetGadgetState(#ComboBox,-1) to have no currently selected item is also possible here.

I just noticed, that new combobox items are always inserted at the top of the combobox item list, but not inbetween (e.g. after last current element) or at the end of the list like intended by your code (I think).

Re: Editable ComboboxGadget - inserting/deleting items

Posted: Fri Sep 30, 2016 11:27 pm
by WilliamL
new combobox items are always inserted at the top of the combobox item list
Yes, I see that if none of the items are selected then the added item is first otherwise (if some item is selected) it adds just after the selected item here. I think I fixed the code (above) so the addition is the last item.

I don't know what is happening if state=19 and we add 1 and it is beyond the created items like I am doing here (in fourth line). Seems to work.

Code: Select all

          If state=-1
            AddGadgetItem(#ComboBox,-1, a$) ; new item will be added to end of list
          Else
            AddGadgetItem(#ComboBox,state+1, a$) ; new item will the added after last selected spot in list
          EndIf
..but if I were cautious I would do this instead

Code: Select all

          If state=-1 or state=CountGadgetItems(#combobox)-1
            AddGadgetItem(#ComboBox,-1, a$) ; new item will be added to end of list
          Else
            AddGadgetItem(#ComboBox,state+1, a$) ; new item will the added after last selected spot in list
          EndIf