some gtk2 code

Miscellaneous Forums/Linux Discussion/some gtk2 code

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

An example of using GTK2 from BlitzMax without any C/C++ glue.

It's not exactly stunning as gadgetpositions are wrong and the event loop is looking a bit broken.

Has anyone else been doing any GTK development?

Oh, and you may need a sudo apt-get install libgtk2.0-dev to build.

' gtk2.bmx

Strict

?Linux
Import "-L/usr/lib"
Import "-lgtk-x11-2.0"
Import "-lgdk-x11-2.0"
Import "-lglib-2.0"
?
	
Extern

Function gtk_init(argc Ptr,argv:Byte Ptr Ptr Ptr)
Function gtk_exit(exitcode)
Function gtk_main_iteration()
Function gtk_main_iteration_do(block)

Function gtk_widget_set_uposition(widget,x,y) 
Function gtk_widget_set_usize(widget,w,h) 
Function gtk_widget_show(widget)
Function gtk_widget_show_now(widget)
Function gtk_widget_hide(widget)
Function gtk_widget_destroy(widget)

Function gtk_widget_size_request(widget,area:TGTKRequisition)
Function gtk_widget_size_allocate(widget,area:TGTKAllocation)
Function gtk_widget_get_child_requisition(widget,area:TGTKRequisition)

' windows

Function gtk_window_new(window_type)
Function gtk_window_set_title(window,title$Z)
Function gtk_window_set_default_size(window,width,height)

Function gtk_vbox_new(homogenous,spacing)
Function gtk_box_pack_start(box,child,expand,fill,padding)
Function gtk_box_pack_end(box,child,expand,fill,padding)

Function gtk_fixed_new()

Function gtk_statusbar_new()
Function gtk_statusbar_get_context_id(statusbar,desc$z)
Function gtk_statusbar_push(statusbar,context,text$z)
Function gtk_statusbar_pop(statusbar,context)
Function gtk_statusbar_remove(statusbar,context)
Function gtk_statusbar_set_has_resize_grip(statusbar,bool)
Function gtk_statusbar_get_has_resize_grip(statusbar)

Function gtk_widget_set_sensitive(widget,bool)

'menus

Function gtk_menu_bar_new()
Function gtk_menu_shell_append(menubar,item)
Function gtk_menu_new()
Function gtk_menu_item_new_with_label(label$z)
Function gtk_menu_item_set_submenu(menu,menuitem)
Function gtk_check_menu_item_new_with_label(label$z)
Function gtk_check_menu_item_set_active(menuitem,bool)
Function gtk_menu_shell_insert(menushell,menuitem,pos)

' buttons

Function gtk_button_new()
Function gtk_button_new_with_label(name$z)

Function gtk_check_button_new() 
Function gtk_check_button_new_with_label(name$z)

Function gtk_radio_button_new(gslist) 
Function gtk_radio_button_new_with_label(gslist,name$z)

' sliders

Function gtk_vscrollbar_new(adjustor)
Function gtk_hscrollbar_new(adjustor)
Function gtk_hscale_new(adjustor)
Function gtk_vscale_new(adjustor)

Function gtk_container_add(container,widget)

' dialogs

Function gtk_font_selection_dialog_new(title$z)
Function gtk_color_selection_dialog_new(title$z)
Function gdk_cursor_new(gdk_cursor)
Function gtk_object_set_data(gobject,key$z,data)
Function gtk_object_get_data Ptr(gobject,key$z)
Function g_signal_connect_data(gtkobject,name$z,callback(),user Ptr,destroyhandler(data,user Ptr),flags)
Function gtk_connect(gtkobject,name$z,callback(widget,event Ptr,gadget:TGTKGadget),gadget:TGTKGadget,destroyhandler(data,user Ptr),flags)="g_signal_connect_data"

End Extern

Const GTK_WINDOW_TOPLEVEL=0
Const GTK_WINDOW_DIALOG=1
Const GTK_WINDOW_POPUP=2

'gtkFileRequest("~/")

Const G_CONNECT_AFTER=1
Const G_CONNECT_SWAPPED=2

Global GTKDriver:TGTKGuiDriver=New TGTKGuiDriver

Local window:TGadget=CreateWindow("my window",40,40,320,440)

' test menu stuff

Local file:TGadget=CreateMenu("File",0,WindowMenu(window))
Local open:TGadget=CreateMenu("Open",1001,file)
Local recent:TGadget=CreateMenu("Recent",0,file)
For Local i=1 To 5;CreateMenu("file"+i,0,recent);Next
Local quit:TGadget=CreateMenu("Quit",1002,file)
Local options:TGadget=CreateMenu("Options",0,WindowMenu(window))
Local enable:TGadget=CreateMenu("Enable",1003,options)
CheckMenu enable
DisableMenu open

' test button

Local button:TGadget=CreateButton("Button",4,14,100,24,window)
Local checkbutton:TGadget=CreateButton("CheckButton",4,42,100,24,window,BUTTON_CHECKBOX)
Local radiobutton:TGadget=CreateButton("RadioButton",4,70,100,24,window,BUTTON_RADIO)
Local okbutton:TGadget=CreateButton("OK",4,98,100,24,window,BUTTON_OK)
Local cancelbutton:TGadget=CreateButton("Cancel",4,126,100,24,window,BUTTON_CANCEL)

' test sliders

Local hscroll:TGadget=CreateSlider(150,14,100,24,window,SLIDER_HORIZONTAL)
Local vscroll:TGadget=CreateSlider(120,14,24,100,window,SLIDER_VERTICAL)
Local hslide:TGadget=CreateSlider(170,44,100,34,window,SLIDER_TRACKBAR|SLIDER_HORIZONTAL)
Local vslide:TGadget=CreateSlider(150,34,34,100,window,SLIDER_TRACKBAR|SLIDER_VERTICAL)

UpdateWindowMenu window

'RequestColor 255,0,0
'RequestFont

Local ticker

While True
	GTKDriver.GTKWaitEvent -1
	Select EventID()
		Case 0
			ticker:+1
			If ticker>1000 Print "tick";ticker=0
		Case EVENT_WINDOWMOVE
			Print "WINDOWMOVE"
		Case EVENT_WINDOWSIZE
			Print "WINDOWSIZE"
		Case EVENT_WINDOWCLOSE
			Print "WINDOWCLOSE"
			End
		Case EVENT_WINDOWACTIVATE
			Print "WINDOWACTIVATE"
		Default
			Print "eventid()="+EventID()
	End Select
Wend


Rem
Const GADGET_DESKTOP=0
Const GADGET_WINDOW=1
Const GADGET_BUTTON=2
Const GADGET_PANEL=3
Const GADGET_TEXTFIELD=4
Const GADGET_TEXTAREA=5
Const GADGET_COMBOBOX=6
Const GADGET_LISTBOX=7
Const GADGET_TOOLBAR=8
Const GADGET_TABBER=9
Const GADGET_TREEVIEW=10
Const GADGET_HTMLVIEW=11
Const GADGET_LABEL=12
Const GADGET_SLIDER=13
Const GADGET_PROGBAR=14
Const GADGET_MENUITEM=15
Const GADGET_NODE=16
EndRem


Type TGTKGuiDriver Extends TMaxGUIDriver

	Method New()
		gtk_init(Null,Null)
		maxgui_driver=Self
	End Method
	
	Method Delete()
		gtk_exit(0)
	End Method

	Method GTKWaitEvent(timeout)
		Select timeout
		Case -1
			gtk_main_iteration
		Case 0
			gtk_main_iteration_do True
		Default
		'set watchdog timer...
			gtk_main_iteration_do True
		End Select		
	End Method

	Method GTKPeekEvent()
		GTKWaitEvent -1
	End Method	
	
	Method HotKey(key,state,kind,data=0,x=0,y=0,z=0,src:TGadget=Null)
	End Method
	
	Method CreateGadget:TGadget(gadgetclass,name$,x,y,w,h,group:TGadget,style)
		Local	window:TGTKWindow
		Local	menu:TGTKMenu
		Local	button:TGTKButton
		Local	slider:TGTKSlider
		
		Select gadgetclass
			Case GADGET_WINDOW
				window=New TGTKWindow
				window.init name,x,y,w,h,group,style							
				Return window				
			Case GADGET_MENUITEM
				menu=New TGTKMenu
				menu.init name,x,TGTKMenu(group)
				Return menu
			Case GADGET_BUTTON
				button=New TGTKButton
				button.init name,x,y,w,h,TGTKGadget(group),style
				Return button
			Case GADGET_SLIDER
				slider=New TGTKSlider
				slider.init x,y,w,h,TGTKGadget(group),style
				Return slider
		End Select		
	End Method
		
	Method CreateTimer:TGadget(hz#)
	End Method
	
	Method CreateFont:TGuiFont(handle)
	End Method

	Method LoadFont:TGuiFont(name$,size,flags)
	End Method
		
	Method RequestColor( red,green,blue )
		Local colorreq
		colorreq=gtk_color_selection_dialog_new("Select Color");
		gtk_widget_show colorreq
		While True
			GTKWaitEvent -1
			Print "fontrequester event"
		Wend
	End Method
	
	Method RequestFont:TGuiFont(font:TGuiFont)
		Local fontreq
		fontreq=gtk_font_selection_dialog_new("Select Font");
'		gtk_signal_connect (GTK_OBJECT (fontw), "destroy",(GtkSignalFunc)font_destroy, &fontw);
'		gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (fontw)->ok_button),"clicked", (GtkSignalFunc) font_ok, fontw );
'		gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG(fontw)->cancel_button),"clicked", (GtkSignalFunc) gtk_widget_destroy,GTK_OBJECT (fontw));
'		gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG(fontw),FontName);
		gtk_widget_show fontreq
		While True
			GTKWaitEvent -1
			Print "fontrequester event"
		Wend
	End Method

	Method SetPointer(shape)
	End Method
	
	Method ActiveGadget:TGadget()
	End Method
	
	Method LoadIconStrip:TIconStrip(source:Object)
	End Method
End Type

Type TGTKWindow Extends TGTKGadget
	Field	vbox,statusbar
	Field	menubar:TGTKMenu

	Method SetText(text$)
		gtk_window_set_title instance,text
	End Method
				
	Method Init(name$,x,y,w,h,group:TGadget,style)
		Local	show
			
		class=GADGET_WINDOW
		instance=gtk_window_new(GTK_WINDOW_TOPLEVEL)
		
		show=True

		gtk_window_set_default_size(instance,w,h)		
		If style&WINDOW_HIDDEN show=False

		gtk_connect instance,"set_focus",FocusWindow,Self,Destroy,0
		gtk_connect instance,"destroy",DestroyWindow,Self,Destroy,0
		gtk_connect instance,"configure_event",MoveWindow,Self,Destroy,0
		gtk_connect instance,"size_request",SizeWindow,Self,Destroy,0
		
		vbox=gtk_vbox_new(False,0)
		gtk_container_add instance,vbox				
		gtk_widget_show vbox
				
		If style & WINDOW_MENU
			menubar=TGTKMenu.CreateMenuBar()
			gtk_box_pack_start vbox,menubar.instance,False,False,2
		EndIf
			
		client=gtk_fixed_new()
		If style & WINDOW_STATUS
			gtk_box_pack_start vbox,client,True,True,2
			statusbar=gtk_statusbar_new()
'			If style & WINDOW_RESIZABLE
			gtk_box_pack_end vbox,statusbar,False,False,2				
			gtk_widget_show statusbar
		Else
			gtk_box_pack_end vbox,client,True,True,2
		EndIf
		gtk_widget_show client
		
		SetShape x,y,w,h
		SetText name

		If group _SetParent group
		SetShow show
		
'		WaitEvent
		
'		Input "wait"
		Print "clientwidth()="+ClientWidth()
	
	End Method

	Method GetMenu:TGadget()
		Return menubar
	End Method

	Function MoveWindow(widget,event Ptr,sender:TGTKGadget)
		PostGuiEvent(EVENT_WINDOWMOVE,sender)
	End Function
	Function SizeWindow(widget,event Ptr,sender:TGTKGadget)
		PostGuiEvent(EVENT_WINDOWSIZE,sender)
	End Function
	Function DestroyWindow(widget,event Ptr,sender:TGTKGadget)
		PostGuiEvent(EVENT_WINDOWCLOSE,sender)
	End Function
	Function FocusWindow(widget,event Ptr,sender:TGTKGadget)
		PostGuiEvent(EVENT_WINDOWACTIVATE,sender)
	End Function
	
End Type

Type TGTKMenu Extends TGTKGadget
	Field	tag
	Field	shell
	Field	label$
	Field	ischeckitem
	Field	pos
	
	Function CreateMenuBar:TGTKMenu()
		Local	menu:TGTKMenu
		menu=New TGTKMenu
		menu.class=GADGET_MENUITEM
		menu.instance=gtk_menu_bar_new()
		menu.shell=menu.instance
		gtk_widget_show menu.instance
		Return menu
	End Function

	Method Init(name$,tagvalue,dad:TGTKMenu)
		instance=gtk_menu_item_new_with_label(name)
		class=GADGET_MENUITEM
		tag=tagvalue
		label=name
		If dad
			If Not dad.shell 
				dad.shell=gtk_menu_new()
				gtk_menu_item_set_submenu dad.instance,dad.shell
			EndIf
			gtk_menu_shell_append dad.shell,instance
			_SetParent dad
			pos=dad.kids.count()
		EndIf
		gtk_widget_show(instance)
	End Method		
	
	Method SetChecked(bool)
		Local	dad:TGTKMenu
		Local	item,pos
		
		If Not ischeckitem
			gtk_widget_destroy instance
			item=gtk_check_menu_item_new_with_label(label)
			dad=TGTKMenu(parent)
			If dad
				gtk_menu_shell_insert dad.shell,item,pos
				gtk_widget_show item
			EndIf
			instance=item
			ischeckitem=True
		EndIf	
		gtk_check_menu_item_set_active instance,bool
	End Method
		
End Type

Type TGTKButton Extends TGTKGadget

	Method init(name$,x,y,w,h,group:TGTKGadget,style)
		Select style
		Case BUTTON_RADIO
			instance=gtk_radio_button_new_with_label(0,name)
		Case BUTTON_CHECKBOX
			instance=gtk_check_button_new_with_label(name)
		Default
			instance=gtk_button_new_with_label(name)
'			If style=BUTTON_OK
'			If style=BUTTON_CANCEL
		End Select
		If group gtk_container_add group.client,instance
		_SetParent group
		SetShape x,y,w,h
		SetShow True
	End Method
End Type

Type TGTKSlider Extends TGTKGadget

	Method init(x,y,w,h,group:TGTKGadget,style)
		Local	adjustor
		If style&SLIDER_TRACKBAR
			If style&SLIDER_HORIZONTAL
				instance=gtk_hscale_new(adjustor)
			Else
				instance=gtk_vscale_new(adjustor)
			EndIf
		Else
			If style&SLIDER_HORIZONTAL	
				instance=gtk_hscrollbar_new(adjustor)
			Else
				instance=gtk_vscrollbar_new(adjustor)
			EndIf
		EndIf		
		If group gtk_container_add group.client,instance
		_SetParent group
		SetShape x,y,w,h
		SetShow True		
	End Method
End Type

Type TGTKRequisition
	Field	width,height
End Type

Type TGTKAllocation
	Field	x:Short,y:Short,width:Short,height:Short
End Type

Type TGTKGadget Extends TGadget

	Field	class,instance,client

	Function Destroy(data,closure Ptr)
		Print "Destroy Handler"
	End Function
			
' interface

	Method Free()
	End Method
	
	Method Rethink()		'resize
		gtk_widget_set_uposition instance,xpos,ypos'+height
		gtk_widget_set_usize instance,width,height
	End Method
	
	Method Redraw()
	End Method
	
	Method ClientWidth()
		Local	handle
		Local	rect:TGTKRequisition=New TGTKRequisition
'		Local	rect:TGTKAllocation=New TGTKAllocation
		handle=instance
		If client handle=client
'		gtk_widget_size_request handle,rect	
'		gtk_widget_size_allocate handle,rect
'		gtk_widget_get_child_requisition handle,rect

'		Local	data:Short Ptr
'		data=Short Ptr(handle)
'		For Local i=48 To 63
'			Print ""+i+":"+data[i]
'		Next

		Local	data:Short Ptr
		
		gtk_object_get_data(client,"width-request")
		If data Print "data[0]="+data[0]
'		Print "handle="+handle
'		Print "clientwidth="+rect.width			
'		Print "clientheight="+rect.height			
'		Return rect.width
	End Method
	
	Method ClientHeight()
	End Method
	
	Method Activate(cmd)
	End Method
	
	Method State()
	End Method
	
	Method SetText(text$)
	End Method
	
	Method GetText$()
	End Method
	
	Method SetFont(font:TGuiFont)
	End Method
	
	Method SetColor(r,g,b)
	End Method
	
	Method SetTextColor(r,g,b)
	End Method
	
	Method SetShow(bool)
		If bool
			gtk_widget_show_now instance
		Else
			gtk_widget_hide instance		
		EndIf
	End Method
	
	Method SetChecked(bool)
	End Method
	
	Method SetEnabled(bool)
		gtk_widget_set_sensitive(instance,bool)
	End Method
	
' window commands

	Method SetStatus(text$)
	End Method
	
	Method GetMenu:TGadget()
	End Method
	
	Method PopupMenu(menu:TGadget)
	End Method
	
	Method UpdateMenu()
	End Method
	
	Method SetMinimumSize(w,h)
	End Method
		
End Type