TreeGadget/ExplorerTreeGadget extended key control

Linux specific forum
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

TreeGadget/ExplorerTreeGadget extended key control

Post by Oma »

The gtk3 implementation in PureBasic 5.46B1 has made significant progress in terms of usability.
To test it out, the Linux-API-Library-Viewer is currently being additionally converted to gtk3 and some functional extensions are being tested.

As a by-product, a function for quick and effective keyboard control of the TreeGadget on gtk2/gtk3 has been refined and I would like to make it available here:

The key controls:
[Right key / right arrow] on selected node: expands the node,
[Left key / left arrow] on selected expanded node: collapses the node,
[Left key / left arrow] on selected collapsed node: collapses and selects the parent node(if existing) !!!,
[Left key / left arrow] on selected item: collapses and selects the parent node (if existing) !!!,
[Space] on selected node: toggles the expansion state.

And: it's expandable, compatible extended for gtk2 and works on ExplorerTreeGadget too - unfortunately everything only for Linux

Code: Select all

EnableExplicit

ImportC ""
	g_signal_connect(*instance, detailed_signal.p-utf8, *c_handler, *data, destroy= 0, flags= 0) As "g_signal_connect_data"
	gtk_tree_model_iter_parent(*tree_model, *iter.GtkTreeIter, *child.GtkTreeIter)
	gtk_tree_selection_select_path(*selection.GtkTreeSelection, *path);  neccessary for gtk2
EndImport

; Object constants
#Win_Main= 0

#TG1     = 0

Global.i gEvent, gQuit

;- {add to programm ...
#GDK_KEY_Left = $FF51
#GDK_KEY_Right= $FF53
#GDK_KEY_space= $020

Procedure.i TreeGadget_KeyControl(Gadget, Key)
	Protected *tSelection= gtk_tree_view_get_selection_(GadgetID(Gadget))
	Protected iter.GtkTreeIter, piter.GtkTreeIter
	Protected tModel, *tPath
	Protected Action= 0;                                               0= nothing, 1= collapse, 2= expand
	
	gtk_tree_selection_get_selected_(*tSelection, @tModel, @iter)
	If gtk_tree_model_iter_has_child_(tModel, iter);                   node?
		*tPath= gtk_tree_model_get_path_(tModel, iter);                  path valid?
		If *tPath
			Select Key
				Case #GDK_KEY_Left;                                          collapse expanded node?
					If gtk_tree_view_row_expanded_(GadgetID(Gadget), *tPath)
						Action= 1
					Else;                                                      collapse parent on collapsed node?
						If gtk_tree_model_iter_parent(tModel, @piter, iter);     parent iter?
							gtk_tree_path_free_(*tPath);                           freed child node
							*tPath= gtk_tree_model_get_path_(tModel, piter);       parent path valid?
							If *tPath
								gtk_tree_selection_select_path(*tSelection, *tPath); gtk2 (harmless for gtk3)
								Action = 1
							EndIf
						EndIf
					EndIf
				Case #GDK_KEY_Right;                                         expand?
					If Not gtk_tree_view_row_expanded_(GadgetID(Gadget), *tPath)
						Action= 2
					EndIf
				Case #GDK_KEY_space;                                         toggle?
					If gtk_tree_view_row_expanded_(GadgetID(Gadget), *tPath)
						Action= 1
					Else
						Action= 2
					EndIf
			EndSelect
		EndIf
	Else;                                                              no node?
		*tPath= gtk_tree_model_get_path_(tModel, iter);                  path valid?
		If *tPath
			gtk_tree_path_free_(*tPath);                                   freed
			If gtk_tree_model_iter_parent(tModel, @piter, iter);           parent iter?
				*tPath= gtk_tree_model_get_path_(tModel, piter);             path valid?
				If *tPath
					Select Key
						Case #GDK_KEY_Left;                                      collapse parent?
							gtk_tree_selection_select_path(*tSelection, *tPath);   gtk2 (harmless for gtk3)
							Action = 1
					EndSelect
				EndIf
			Else
				*tPath= #Null;                                               no parent node -> path is already freed
			EndIf
		EndIf
	EndIf
	If *tPath 
		If Action
			If Action = 1
				gtk_tree_view_collapse_row_(GadgetID(Gadget), *tPath)
			ElseIf Action = 2
				gtk_tree_view_expand_row_(GadgetID(Gadget), *tPath, #False)
			EndIf
		EndIf
		gtk_tree_path_free_(*tPath);                                   freed?
	EndIf
EndProcedure

ProcedureC Callback_GadgetGetKey(*widget.GtkWidget, *event.GdkEventKey, user_data)
	Protected.i ModKey= *event\state & $F; (Required 'modifier keys' masked with low nibble)
	Protected.i KeyVal= *event\keyval
	
	If ModKey = #Null
		Select KeyVal
			Case #GDK_KEY_Right, #GDK_KEY_Left, #GDK_KEY_space
				TreeGadget_KeyControl(user_data, KeyVal)
		EndSelect
	EndIf
	ProcedureReturn #False
EndProcedure
;- }...

;- ---
Procedure CreateWindow_Main()
	Protected.i I
	
	If OpenWindow(#Win_Main, -1, -1, 450, 340, "TreeGadget - Switch node w. keybd.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		TextGadget(#PB_Any,   5,   5, 440,  93, "Expand selected node with [right-arrow], " + #LF$ + 
		                                        "collapse selected expanded node with [left-arrow], " + #LF$ + 
		                                        "collapse parent node from sel. collapsed node w. [left-arrow] !!!, " + #LF$ +  
		                                        "collapse parent node from sel. item with [left-arrow] !!!, " + #LF$ + 
		                                        "toggle the expansion with [spacebar].")
		TreeGadget(#TG1,      5, 100, 440, 235)
		
		AddGadgetItem (#TG1, -1, "Item " + Str(0), 0, 0)
		For I = 1 To 3
			AddGadgetItem (#TG1, -1, "Node Item " + Str(I), 0, 0)
			AddGadgetItem(#TG1, -1, "Sub-Item " + Str(I) + ":0", 0, 1)
			AddGadgetItem(#TG1, -1, "Sub-Item " + Str(I) + ":1", 0, 1)
			AddGadgetItem(#TG1, -1, "Sub-Item " + Str(I) + ":2", 0, 1)
			AddGadgetItem(#TG1, -1, "Sub-node " + Str(I) + ":3", 0, 1)
			If I= 1
				AddGadgetItem(#TG1, -1, "Sub-Item 1:3:0", 0, 2)
				AddGadgetItem(#TG1, -1, "Sub-node 1:3:1", 0, 2)
				AddGadgetItem(#TG1, -1, "Sub-Item 1:3:1:0", 0, 3)
				AddGadgetItem(#TG1, -1, "Sub-Item 1:3:1:1", 0, 3)
			EndIf
		Next I
		AddGadgetItem (#TG1, -1, "Item " + Str(4), 0, 0)
		
		;- Add key event on Tree-/ExplorerTreeGadget ...
		g_signal_connect(GadgetID(#TG1), "key-press-event", @Callback_GadgetGetKey(), #TG1)
	EndIf
EndProcedure

CreateWindow_Main()

Repeat
	gEvent= WaitWindowEvent()
	
	Select gEvent
		Case #PB_Event_CloseWindow
			gQuit= #True
	EndSelect
	
Until gQuit
Regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de