Combo box item editable

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Combo box item editable

Post by Olliv »

Hello !

Here is an idea from Fig who asked a way to edit every item in a ComboBox gadget.
Also, if any body asked the same idea earlier, no problem to add a link to such a message !
So, you can see this code which allows you to edit each item of a combo box.

What I imagine clever is the graphical compactness allowed by a combo on the basis. Adding this feature, the coder does not worry about another one that the region characteristics of the gadget which stays constant and so, forseeable.
I apologize for my language mistakes the best writers can put back here : I do not use translating bot.

So... Back to the main : user process.




1) He clicks on the box : naturally, a prestored list is automatically displayed, as the classical combo offers to the user.

2) He clicks on one of the item he chose : the item, ever naturally, is copied to the main combo scope.

3) The user edits it as usually...

4) And, now is the change : two ways are offered to the user.

a) Abort the editing by a simple click away from the combo which removes the focus : editing is cancelled and the old item text is remained and displayed on the main combo scope.

b) Validate the editing by the [Enter] key press : in this way, item is updated by the new text content. The modifying can be checked by the step #1 of this process, and some other items can be changed like this...

Easy !




Now, coder process...


=>> Just replaces ComboxBoxGadget keyword statement with ComboGadget.

=>> Does not worry about the flags argument : ComboGadget() procedure does not care.

=>> If a specific item should be initially set, the coder will use ComboItem() procedure after having added initial item, exactly as classical ComboBox gadget.

=>> The coder can use classical ComboBoxGadget() statement. In this way, he has not to forget #PB_ComboBox_Editable flag on the 6th argument (see reference, and will use ComboCreate() procedure.

=>> ComboCreate() procedure returning a handle, see the following syntax to use it :

Code: Select all

SetGadgetData(Gadget, ComboCreate(Window, Gadget) )
If this method seems to be too complex, ComboGadget() procedure looks after that to simplify the coder task.

=>> To allow this technical break step, 2 internal values must be choosen by the coder : unique key internal code, and unique ghost menu internal code.

=>> Unique key internal code is easy to understand anymore : the program uses it to bypass combo charasteristics inefficience shortcut callback. This code is specific to identify [Enter] key data type event. Here, I chose then numeral 64-bits value 'GK13', but the coder can change it for its own needs.

=>> Unique ghost menu internal code is a little bit more difficult to understand : the program uses it to dicern each "high-level" combo gadget. It is a menu item identifier. I could set it a automatical identifier provider (in a domain between 0 and 64000). But, in this way, I prevented the coder from being free to choose its own menu item identifying values, and this could be source of conflict ! So, I let the coder to choose these. In the example below, in the queue of the following code, you can see I chose the 100 and 101 values. Free to the coder to set them !

=>> Whatever the coder uses ComboGadget() or ComboCreate(), he has to free internal buffer when he deletes the gadget or the host window. For that, there is ComboDelete() procedure. Do not forget !




This tip is on 32 or 64 bits modes : just adapt the first constant.
Hope this will be a new native feature...
Thank again to Fig.

If you see some technical or linguistic mistakes, please tell them.

Code: Select all

;*************************************************************************************************************************************************************************************************
; (An idea from Fig)

#ComboKeyEnter = 'GK13'

Structure COMBO
        Window.I
        Gadget.I
        Item.I
        kMenu.I
        kMenuItem.I
        ReturnKey.I
EndStructure

Declare ComboReturnKey()
Declare ComboCallBack()

Procedure ComboCreate(Window, Gadget, kMenuItemDefault = 64000)
        Define *A.COMBO = AllocateMemory(SizeOf(COMBO) )
        With *A
                \Window = Window
                \Gadget = Gadget
                \kMenuItem = kMenuItemDefault
                BindEvent(#PB_Event_Gadget, @ComboCallBack(), \Window, \Gadget)        
                \kMenu = CreateMenu(#PB_Any, WindowID(\Window) )
                BindMenuEvent(\kMenu, \kMenuItem, @ComboReturnKey() )        
        EndWith
        ProcedureReturn *A
EndProcedure

Procedure ComboDelete(Gadget)
        Define *A.COMBO = GetGadgetData(Gadget)
        With *A
                UnbindEvent(#PB_Event_Gadget, @ComboCallBack(), \Window, Gadget)
                UnbindMenuEvent(\kMenu, \kMenuItem, @ComboReturnKey() )        
                FreeMemory(*A)
        EndWith
EndProcedure

Procedure ComboReturnKey()
        PostEvent(#PB_Event_Gadget, GetActiveWindow(), GetActiveGadget(), #PB_EventType_FirstCustomValue, 'GK13')
EndProcedure

Procedure ComboCallBack()
        Define Gadget = EventGadget()
        Define *A.COMBO = GetGadgetData(Gadget)
        Define gState = GetGadgetState(Gadget)
        If *A
                With *A
                        Select EventType()
                                Case #PB_EventType_Focus
                                        AddKeyboardShortcut(\Window, #PB_Shortcut_Return, \kMenuItem)
                                Case #PB_EventType_LostFocus
                                        RemoveKeyboardShortcut(\Window, #PB_Shortcut_Return)
                                        SetGadgetText(Gadget, GetGadgetItemText(Gadget, \Item) )
                                Case #PB_EventType_Change
                                        If gState <> -1
                                                \Item = gState
                                        EndIf
                                Case #PB_EventType_FirstCustomValue
                                        If EventData() = 'GK13'
                                                SetGadgetItemText(Gadget, \Item, GetGadgetText(Gadget) )
                                        EndIf
                        EndSelect
                EndWith
        EndIf
EndProcedure

Procedure ComboGadget(Id, x, y, w, h, kMenuItemDefault = 64000)
        Define Result
        Define Gadget
        Result = ComboBoxGadget(Id, x, y, w, h, #PB_ComboBox_Editable)
        If Id = #PB_Any
                Gadget = Result
        Else
                Gadget = Id
        EndIf
        SetGadgetData(Gadget, ComboCreate(GetActiveWindow(), Gadget, kMenuItemDefault) )   
        ProcedureReturn Result
EndProcedure

Procedure ComboItem(Gadget, Item)
        Define *A.COMBO = GetGadgetData(Gadget)
        If *A
                With *A
                        SetGadgetState(Gadget, Item)
                        \Item = Item
                EndWith
        EndIf
EndProcedure








; Example

If OpenWindow(10, 0, 0, 270, 180, "Combo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        ComboGadget(20, 10, 10, 250, 100)
        AddGadgetItem(20, -1, "Option A")
        AddGadgetItem(20, -1, "Option B")
        AddGadgetItem(20, -1, "Option C")
        ComboItem(20, 1)
        ComboGadget(21, 10, 42, 250, 101)
        AddGadgetItem(21, -1, "Week 1")
        AddGadgetItem(21, -1, "Week 2")
        AddGadgetItem(21, -1, "Week 3")
        ComboItem(21, 2)
        Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
User avatar
Fig
Enthusiast
Enthusiast
Posts: 351
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: Combo box item editable

Post by Fig »

My only credit was to be ignorant in that matter.
So, all praise should go to you for understanding my demand and write a smart code. :wink:
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
Post Reply