ClientWidth help from other OS's

BlitzMax Forums/BlitzMax GUI Programming/ClientWidth help from other OS's

I am working on a ProxyGadget and I need something from each platform. Could you post what this code returns for me?

Strict

Import MaxGUI.Drivers

Global window:TGadget=CreateWindow(AppTitle,0,0,640,480,Desktop(),1+2+WINDOW_CLIENTCOORDS+WINDOW_CENTER)
Global panel:TGadget=CreatePanel(5,5,150,ClientHeight(window)-10,window,PANEL_BORDER)

SetGadgetColor panel,128,128,128
Notify ClientWidth(panel)

Repeat
	WaitEvent()
	Select EventID()
		Case event_windowclose
			Select EventSource()
				Case window
					End
			EndSelect
	EndSelect
	Delay 5
Forever


I get 146 and I'm on a Win32 system.

150 on Mac OS X Leopard.

I get 146 too on Windows Vista with Aero enabled.

Just looking at your code, I thought that I best mention that you should use the bitwise OR '|' operator instead of '+' to combine flags. Using '+' can sometimes give undesirable results.

Strict

Import MaxGUI.Drivers

Global window:TGadget=CreateWindow(AppTitle,0,0,640,480,Desktop(),WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CLIENTCOORDS|WINDOW_CENTER)
Global panel:TGadget=CreatePanel(5,5,150,ClientHeight(window)-10,window,PANEL_BORDER)

SetGadgetColor panel,128,128,128
Notify ClientWidth(panel)

Repeat
	WaitEvent()
	Select EventID()
		Case event_windowclose
			Select EventSource()
				Case window
					End
			EndSelect
	EndSelect
	Delay 5
Forever


On Ubuntu 7.04 (running on VMPlayer) I've got 150.
On MacOS X 10.3.p (PPC) 150

Topic moved to here.

Man, I've been getting really bad about that. :P

Just looking at your code, I thought that I best mention that you should use the bitwise OR '|' operator instead of '+' to combine flags. Using '+' can sometimes give undesirable results.

Oh, OK. Thanks.

150 on Mac OS X Leopard.
I get 146 too on Windows Vista with Aero enabled.
On Ubuntu 7.04 (running on VMPlayer) I've got 150.
On MacOS X 10.3.p (PPC) 150.

Thanks, everyone!

Can I just ask why you are needing to hard-code the values into your proxy gadget? Is there a reason why you aren't simply calling ClientWidth() within your TProxyGadget?

It's always best to steer clear of hard-coded values if you can help it, as even within one platform, the values can be different depending upon the theme uses etc.

Can I just ask why you are needing to hard-code the values into your proxy gadget? Is there a reason why you aren't simply calling ClientWidth() within your TProxyGadget?

It's always best to steer clear of hard-coded values if you can help it, as even within one platform, the values can be different depending upon the theme uses etc.

I was wanting to know the above information because I wanted the pixmaps to fit perfectly inside the panel. :) To make everything more clear, I just e-mailed you the completed proxy gadget. I would've posted it here, but it's kinda big. Let me know what you think and if I should add/remove anything.

Seb,
I just realized that I slacked off on a bunch of crap in the proxy gadget I sent you. I forgot to add a vertical scrollbar, tooltips, and an option so that you don't have to use pixmaps for the pane headers (I'm thinking like a default color depending on each platform). Let me know if you want this new one when I finish it.

Hi Ked,

Sorry, just got your e-mail now - I don't check that account too often...

Had a look at the proxy gadget, and was intrigued looking at the name about what a collapse pane might be, but as soon as I ran the example, I saw and instantly realised it's potential usefulness. :-P

Although it behaves well "as is", if you are serious about wanting to add it to the official MaxGUI.ProxyGadget it perhaps needs those few tweaks first.

Firstly, if you could find a way to perhaps have collapsible panes that don't require a pixmap to be made for each state, and that allow horizontal resizes. I think people would use this a lot more if all they had to do was set the text. Perhaps this can be done by generating a tile pixmap automatically using a function similar to that in my TSplitter.MakeColourHandlePixmap() (see splitter.bmx).

Secondly, vertical scrollbar would definitely improve the functionality and make it much more versatile when panes go off the screen.

Thirdly, it occured to me that a few of the functions (e.g. SetCollapsePaneState() and RemoveCollapsePane()) closely follow the gadget item functions, so perhaps there is a way that it could be tweaked to make use of the functions already there such as AddGadgetItem(), SetGadgetItem(), SelectedGadgetItems() etc. This would make it feel a lot more like a standard MaxGUI control, but I've never attempted making a proxy gadget that behaves like list based gadgets so this might not be feasible.

Still, very nice work - keep me posted here with any updates.

Seb,

Hey, I have a slight problem when creating the text for the pane. I'm thinking that I'm going to have to switch to canvases to make everything look and work nice. Or, maybe there's a multiplatform GDI module laying around? I could probably use that. Let me know of your thoughts. :)

Hi,

I'm thinking that I'm going to have to switch to canvases to make everything look and work nice

It may just be a personal thing, but I really don't like using canvases for platform controls because of their dependence on hardware accelerated graphics drivers (such as OpenGL or DirectX). To my knowledge, there isn't a *cross-platform* GDI module (that can be easily used with MaxGUI), so I really don't recommend it.

Try to work around canvases at all costs.

I have a slight problem when creating the text for the pane.

What exactly is the problem? Maybe I could suggest a solution?

Cheers

What exactly is the problem? Maybe I could suggest a solution?

I'm having trouble putting text and a pixmap into the same panel. If I use a label, the background is the same as the window/panel color.

I really don't like using canvases for platform controls

It's not a very good idea at all.


To my knowledge, there isn't a *cross-platform* GDI module

It's called wxMax :-p


that can be easily used with MaxGUI

Ah... well... no.

But with wxMax you can create all kinds of interesting looking controls with the GDI, which work the same on all platforms.

Maybe someone can write one for MaxGUI?

But with wxMax you can create all kinds of interesting looking controls with the GDI, which work the same on all platforms.

I would use wxMax, but I find it a waste of time. Code is longer, too much to import, and OOP is mandatory. I prefer MaxGUI.

Maybe someone can write one for MaxGUI?

Something tells me it's not that easy, or BlitzMax would already have a module for it.

Code is longer, too much to import, and OOP is mandatory.


You are right, those are very good reasons to keep using MaxGUI!

You are right, those are very good reasons to keep using MaxGUI!

Good enough for me to dislike wxMax.

Ok, Ok. Break it up you two! :P

@ Ked: Does this not work for you?

'Paste into a brand new unsaved file, in MaxIDE.

SuperStrict

Import MaxGUI.Drivers

AppTitle = "Label Background Test"

Global wndMain:TGadget = CreateWindow(AppTitle,100,100,400,300,Null,WINDOW_TITLEBAR|WINDOW_STATUS|WINDOW_CLIENTCOORDS|WINDOW_RESIZABLE)
	
	'Load panel and set a tiled pixmap
	Global pnlBackground:TGadget = CreatePanel(0,0,ClientWidth(wndMain),ClientHeight(wndMain),wndMain)
	SetGadgetLayout pnlBackground,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
	Global pixBackground:TPixmap = LoadPixmap("../docs/src/bmax120.png")
	SetPanelPixmap(pnlBackground,pixBackground,PANELPIXMAP_TILE)
	
	'Then add a label to the panel to see if the background shows through.
	Global lblText:TGadget = CreateLabel("The quick brown fox jumped over the lazy dogs.",10,10,ClientWidth(pnlBackground)-20,ClientHeight(pnlBackground)-20,pnlBackground, LABEL_CENTER)
	SetGadgetLayout lblText,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_CENTERED
	SetGadgetTextColor(lblText,255,0,0)
	SetGadgetFont(lblText, LookupGuiFont(GUIFONT_SYSTEM, 36, FONT_BOLD))

AddHook EmitEventHook, eventHook

Repeat;WaitSystem();Forever

Function eventHook:Object( pID%, pData:Object, pContext:Object )
	
	Local pEvent:TEvent = TEvent(pData)
	If Not pEvent Then Return pData
	
	SetStatusText wndMain, pEvent.ToString()
	
	Select pEvent.id
		Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE;End
	EndSelect
	
EndFunction


I know it's not a pretty example, but the background is definitely visible through the label text:



What about the people who can only use the Win32MaxGUI module?

What about the people who can only use the Win32MaxGUI module

Ahhh, now that is a different issue. The short story is that it took absolutely ages to get MaxGUI.Win32MaxGUIEx to handle this kind of thing properly, as most Windows controls are not transparent as standard. The most stable way to achieve the effect is to use some of the new theme API functions that first shipped with Windows XP (such as DrawThemeParentBackground()), and as such I can't really add it to the old legacy driver designed for people who need it to run on Windows 9X.

I consider this less of a problem more recently though, as it is now possible to run MaxGUI.Win32MaxGUIEx on Windows 9X/Me, so long as you add...

Import "-lunicows"
...before the MaxGUI.Drivers import.

Ked, is there a specific reason why you are using the old driver as opposed to the brand new (and more stable) one?

Ked, is there a specific reason why you are using the old driver as opposed to the brand new (and more stable) one?

I'm not. I just want this to work the same on all drivers. Which brings me to my next question: Does your example look the same on Mac and Linux?

Does your example look the same on Mac and Linux?

Although I haven't tested it on Mac, I think labels are properly transparent with CocoaMaxGUI, so it should do.

As for Linux, I've just fired up my Ubuntu PC for you now, and the background shines through with FLTKMaxGUI.

As such, I think you are pretty safe with using it.

Alright. Let the updating begin.

Just checked on Mac OS X for you now and, as I expected, the panel pixmap is visible behind the label text.

I'm having a crap-load of trouble with the scrollbar. Do you have an example of setting the range of it? Everything I've tried is all messed up. :P

Any ideas from anyone?

Here is a short example of a scrollbar. Normally you want to have a hook function for the movement to have an immediate effect.

SuperStrict
Import MaxGui.Drivers


Global PanelAsWindow:TGadget
Global PanelToScroll:TGadget
'End of Header File


Local Window1:TGadget = CreateWindow:TGadget("Window1",87,108,335,262,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS )
	' a panel used as window we look through to to see a part of the bigger scroll-area
	PanelAsWindow:TGadget = CreatePanel:TGadget(0,0,299,167,Window1:TGadget,Null,"Panel1")
		SetGadgetLayout( PanelAsWindow:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )

	'the panel we want to scroll
	PanelToScroll:TGadget = CreatePanel:TGadget(0,0,299,278,PanelAsWindow:TGadget,Null,"Panel2")
		SetGadgetLayout( PanelToScroll:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )

	'some gagdets on top to scroll, not important
	Local TextField1:TGadget = CreateTextField:TGadget(93,36,80,18,PanelToScroll:TGadget,Null)
		SetGadgetText( TextField1:TGadget,"TextField1")
	Local TextArea1:TGadget = CreateTextArea:TGadget(12,173,275,95,PanelToScroll:TGadget,Null)
		SetTextAreaText( TextArea1:TGadget , "TextArea1" )
	Local Label1:TGadget = CreateLabel:TGadget("Label1",12,95,80,16,PanelToScroll:TGadget,LABEL_SUNKENFRAME)
	Local ProgBar1:TGadget = CreateProgBar:TGadget(207,88,80,23,PanelToScroll:TGadget,Null)
		UpdateProgBar( ProgBar1:TGadget,0.200000003 )
	'a button outside the scrollarea		
	Local Ok1:TGadget = CreateButton:TGadget("Ok1",224,178,75,23,Window1:TGadget,BUTTON_OK)
	


	'set the scrollbar
	Local SB1:TGadget = CreateSlider:TGadget(303,0,23,167,Window1:TGadget,SLIDER_VERTICAL | SLIDER_SCROLLBAR )
				SetSliderRange( SB1:TGadget,1 ,100 )
				SetSliderRange( SB1:TGadget,GadgetHeight(PanelAsWindow),GadgetHeight(PanelToScroll))


Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			Select EventSource()
				Case Window1	Window1_WC( Window1:TGadget )
			End Select

		Case EVENT_GADGETACTION
			Select EventSource()
				Case SB1	SB1_GA( SB1:TGadget , EventData() )
				Case Ok1	Ok1_GA( Ok1:TGadget )
			End Select

	End Select
Forever

Function Window1_WC( Window:TGadget )
	DebugLog "Window Window1 wants to be closed"
'	HideGadget( Window:TGadget )

	End
End Function

Function SB1_GA( Slider:TGadget , Number:Int )
	DebugLog "Slider SB1 changed to " + Number
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)-Number,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
	
End Function

Function Ok1_GA( Button:TGadget )
	DebugLog "Button Ok1 was pressed"
	
End Function


That's great, but when you use the arrows it only moves one pixel at a time. Is there a way to move it maybe 20 or 30 pixels at a time, or something?

Just set the number of pixels to move when the event occurs.

Use up and down key or the mousewheel.
Here is the idea:

SuperStrict
Import MaxGui.Drivers


Global PanelAsWindow:TGadget
Global PanelToScroll:TGadget
Global SB1:TGadget
Global Offset:Int
'End of Header File


Local Window1:TGadget = CreateWindow:TGadget("Window1",87,108,335,262,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS )
	' a panel used as window we look through to to see a part of the bigger scroll-area
	PanelAsWindow:TGadget = CreatePanel:TGadget(0,0,299,167,Window1:TGadget,Null,"Panel1")
		SetGadgetLayout( PanelAsWindow:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )

	'the panel we want to scroll
	PanelToScroll:TGadget = CreatePanel:TGadget(0,0,299,278,PanelAsWindow:TGadget,PANEL_ACTIVE,"Panel2")
		SetGadgetLayout( PanelToScroll:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )
		ActivateGadget(PanelToScroll)
	'some gagdets on top to scroll, not important
	Local TextField1:TGadget = CreateTextField:TGadget(93,36,80,18,PanelToScroll:TGadget,Null)
		SetGadgetText( TextField1:TGadget,"TextField1")
	Local TextArea1:TGadget = CreateTextArea:TGadget(12,173,275,95,PanelToScroll:TGadget,Null)
		SetTextAreaText( TextArea1:TGadget , "TextArea1" )
	Local Label1:TGadget = CreateLabel:TGadget("Label1",12,95,80,16,PanelToScroll:TGadget,LABEL_SUNKENFRAME)
	Local ProgBar1:TGadget = CreateProgBar:TGadget(207,88,80,23,PanelToScroll:TGadget,Null)
		UpdateProgBar( ProgBar1:TGadget,0.200000003 )
	'a button outside the scrollarea		
	Local Ok1:TGadget = CreateButton:TGadget("Ok1",224,178,75,23,Window1:TGadget,BUTTON_OK)
	


	'set the scrollbar
	SB1:TGadget = CreateSlider:TGadget(303,0,23,167,Window1:TGadget,SLIDER_VERTICAL | SLIDER_SCROLLBAR )
				SetSliderRange( SB1:TGadget,1 ,100 )
				SetSliderRange( SB1:TGadget,GadgetHeight(PanelAsWindow),GadgetHeight(PanelToScroll))


Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			Select EventSource()
				Case Window1	Window1_WC( Window1:TGadget )
			End Select

		Case EVENT_GADGETACTION
			Select EventSource()
				Case SB1	SB1_GA( SB1:TGadget , EventData() )
				Case Ok1	Ok1_GA( Ok1:TGadget )
			End Select

		Case EVENT_MOUSEWHEEL
			Select EventSource()
				Case PanelToScroll	PanelToScroll_MW( PanelToScroll:TGadget , EventData() )
			End Select

		Case EVENT_KEYDOWN
			Select EventSource()
				Case PanelToScroll	PanelToScroll_KD( PanelToScroll:TGadget , EventData() )
			End Select

	End Select
Forever

Function Window1_WC( Window:TGadget )
	DebugLog "Window Window1 wants to be closed"
'	HideGadget( Window:TGadget )

	End
End Function

Function SB1_GA( Slider:TGadget , Number:Int )
	DebugLog "Slider SB1 changed to " + Number
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)-Number,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
	
End Function

Function Ok1_GA( Button:TGadget )
	DebugLog "Button Ok1 was pressed"
	
End Function


Function PanelToScroll_MW( Panel:TGadget , MouseWheel:Int )
	DebugLog "Panel PanelToScroll detected "+ MouseWheel +" Mouse Wheel clicks"
	Offset:+Mousewheel*10
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)+Offset,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
End Function

Function PanelToScroll_KD( Panel:TGadget , Key:Int )
	DebugLog "Panel PanelToScroll detected Key "+ Key +" pressed"
	Select Key
		Case KEY_DOWN	Offset:+10
		Case KEY_UP	Offset:-10
	End Select
	
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)+Offset,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
End Function





No, I mean the arrows on the scrollbar.

Your code also doesn't stop scrolling, so you can scroll as far as you want.

No, I mean the arrows on the scrollbar.


Ah, ok. Those arrows don't produce an own event, so you can't act directly on it. But you can check the slider value and set it to whatever you like when you recognize a 1 pixel shift...

Your code also doesn't stop scrolling, so you can scroll as far as you want.


That's right. It just shows an idea how you could catch some events and move the panel as you had problems setting the range of the scrollbar. I leave it up to you to create a working type :)

SuperStrict
Import MaxGui.Drivers


Global PanelAsWindow:TGadget
Global PanelToScroll:TGadget
Global SB1:TGadget
Global Offset:Int


Local Window1:TGadget = CreateWindow:TGadget("Window1",87,108,335,262,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS )
	' a panel used as window we look through to to see a part of the bigger scroll-area
	PanelAsWindow:TGadget = CreatePanel:TGadget(0,0,299,167,Window1:TGadget,Null,"Panel1")
		SetGadgetLayout( PanelAsWindow:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )

	'the panel we want to scroll
	PanelToScroll:TGadget = CreatePanel:TGadget(0,0,299,278,PanelAsWindow:TGadget,PANEL_ACTIVE,"Panel2")
		SetGadgetLayout( PanelToScroll:TGadget,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED )
		ActivateGadget(PanelToScroll)
	'some gagdets on top to scroll, not important
	Local TextField1:TGadget = CreateTextField:TGadget(93,36,80,18,PanelToScroll:TGadget,Null)
		SetGadgetText( TextField1:TGadget,"TextField1")
	Local TextArea1:TGadget = CreateTextArea:TGadget(12,173,275,95,PanelToScroll:TGadget,Null)
		SetTextAreaText( TextArea1:TGadget , "TextArea1" )
	Local Label1:TGadget = CreateLabel:TGadget("Label1",12,95,80,16,PanelToScroll:TGadget,LABEL_SUNKENFRAME)
	Local ProgBar1:TGadget = CreateProgBar:TGadget(207,88,80,23,PanelToScroll:TGadget,Null)
		UpdateProgBar( ProgBar1:TGadget,0.200000003 )
	'a button outside the scrollarea		
	Local Ok1:TGadget = CreateButton:TGadget("Ok1",224,178,75,23,Window1:TGadget,BUTTON_OK)
	


	'set the scrollbar
	SB1:TGadget = CreateSlider:TGadget(303,0,23,167,Window1:TGadget,SLIDER_VERTICAL | SLIDER_SCROLLBAR )
				SetSliderRange( SB1:TGadget,1 ,100 )
				SetSliderRange( SB1:TGadget,GadgetHeight(PanelAsWindow),GadgetHeight(PanelToScroll))


Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			Select EventSource()
				Case Window1	Window1_WC( Window1:TGadget )
			End Select

		Case EVENT_GADGETACTION
			Select EventSource()
				Case SB1	SB1_GA( SB1:TGadget , EventData() )
				Case Ok1	Ok1_GA( Ok1:TGadget )
			End Select

		Case EVENT_MOUSEWHEEL
			Select EventSource()
				Case PanelToScroll	PanelToScroll_MW( PanelToScroll:TGadget , EventData() )
			End Select

		Case EVENT_KEYDOWN
			Select EventSource()
				Case PanelToScroll	PanelToScroll_KD( PanelToScroll:TGadget , EventData() )
			End Select

	End Select
Forever

Function Window1_WC( Window:TGadget )
	DebugLog "Window Window1 wants to be closed"
'	HideGadget( Window:TGadget )

	End
End Function

Function SB1_GA( Slider:TGadget , Number:Int )
	DebugLog "Slider SB1 changed to " + Number
	Global LastNumber:Int
	Local Offset:Int
	If Abs(LastNumber-Number)=1 Then
		Offset=Number-(Sgn(LastNumber-Number)*20 )
		SetSliderValue(Slider,Offset)
		Number = Offset
	EndIf
	SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)-Number,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
	LastNumber=Number
End Function

Function Ok1_GA( Button:TGadget )
	DebugLog "Button Ok1 was pressed"
	
End Function


Function PanelToScroll_MW( Panel:TGadget , MouseWheel:Int )
	DebugLog "Panel PanelToScroll detected "+ MouseWheel +" Mouse Wheel clicks"
	Offset:+Mousewheel*10
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)+Offset,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
End Function

Function PanelToScroll_KD( Panel:TGadget , Key:Int )
	DebugLog "Panel PanelToScroll detected Key "+ Key +" pressed"
	Select Key
		Case KEY_DOWN	Offset:+10
		Case KEY_UP	Offset:-10
	End Select
	
		SetGadgetShape( PanelToScroll:TGadget,GadgetX(PanelToScroll),GadgetY(PanelAsWindow)+Offset,GadgetWidth(PanelToScroll),GadgetHeight(PanelToScroll) )
End Function