BlitzMax Forums/BlitzMax Programming/FryGUI

Fry Crayola(Posted 2006) [#1]
FryGUI is a new, entirely free GUI system for ALL platforms, based on a system of screens, not windows.

Well, rather than have your GUI consist of a number of windows, each containing various gadgets, FryGUI replaces that with the concept of Screens, made up of Panels, in which sit your gadgets.

Individual panels can be used in any number of screens, allowing you to have a single title bar at the top of every screen. Or you can have menu panel allowing quick navigation to any other screen.

The GUI system will only concern itself with the current screen, so the program's speed is maintained regardless of how many screens you create.

Perfect for the menu system for an arcade shooter, and perfect for the entire interface for a complex management title.

Each of FryGUI's gadgets generates an event inside the GUI system. In your game's main loop you can poll the event list and react to the events accordingly, rather than checking each individual gadget for a response.

The button gadgets in FryGUI have an optional Link field. By adding a link to the button, FryGUI will automatically change to the required screen when you click the button.

FryGUI's gadgets are fully skinnable by altering the graphics stored in a Skins folder. You can use mutliple skins, and even change on the fly.

OPTIONAL XML generated interface
By using Brucey's libXML module, you can develop your interface without having to get bogged down with code. This provides a quicker way of throwing together the screens, and it also gives the opportunity for any players to tweak the game's skin, or even develop an entirely new one.

You can develop new gadgets to suit your individual purposes simply by extending the existing base gadget and adding the features you require.

Gadgets currently supported
FryGUI currently uses a selection of GUI essentials, as follows:

Combo Boxes
Text Fields
Progress Bars
Tables (or listboxes if you prefer)
Date selectors
Search boxes
Changing cursors

I will be expanding upon the existing gadgets to provide more features.

FryGUI can be downloaded from Here

Due to my own shortsightedness, you'll need to put these executable files in the same directory as the source, because I forgot to include the skin data. That'll be rectified in the coming days.

Note - if you do not have Brucey's LibXML module, remove the xmlfrygui.mod folder if you are having difficulties building the module.

This release is still beta, so let me know if there are any errors.

Thanks also go to Diablo. Whilst trying to adapt his GUI to support a screen system, I learned a lot about half-decent code structure, as anyone who's seen my other projects can testify!

siread(Posted 2006) [#2]
Nice one, Fry! Checking it out now.

BTW, I can upload it to my webspace if you need a mirror. Just say the word. :)

siread(Posted 2006) [#3]
It doesn't build in Debug mode. I put Brucey's LibXML in the mod folder then rebuilt modules but get this error:

C:/Program Files/BlitzMax/mod/fry.mod/frygui.mod/frygui.debug.win32.x86.a(frygui.bmx.debug.win32.x86.o.b)(code+0x63): undefined reference to `__bb_libxml_libxml'

However, in release mode it works a treat! Well done, mate. I'm off to get my mitts dirty.

Fry Crayola(Posted 2006) [#4]
Very odd. I'll get a look at that tomorrow evening, I've never noticed any errors. Thanks.

Edit: It may be something to do with libXML. I'm not getting any error on any of my machines here, all of which are using the same version of libXML: 1.03. Which isn't the latest (that's 1.07).

I'll update tomorrow and see what's going on.

Gabriel(Posted 2006) [#5]
Looks nice. What is it using for drawing? Max2D?

Fry Crayola(Posted 2006) [#6]
Yeah, it's using Max2D for all the drawing.

Brendane(Posted 2006) [#7]
Great series of popups - thanks.

Fry Crayola(Posted 2006) [#8]
Great series of popups - thanks.

Was that from clicking the image link (pesky imageshack) or the download link?

LarsG(Posted 2006) [#9]
nice work.. :)

the only thing that I noticed, is that I couldn't mark the text in the textbox with the mouse(button)..

Fry Crayola(Posted 2006) [#10]
Yes that's on my list of things to do. You can position the cursor, you can slide it around, but as yet you can only highlight stuff by drawing on the screen with a pen. And you don't want to do that.

siread(Posted 2006) [#11]
How do you go about setting alpha on the gadgets when using the XML mode?

Fry Crayola(Posted 2006) [#12]
Use the alpha attribute.

For example:

<button name="button" caption="Click here" x="5" y="5" w="100" h="24" alpha="0.7"/>

I do need to document the xml system properly, listing all the attributes available. For now, if you look in the xmlfrygui.bmx file you should be able to work them out in the ParseGadgets() function. Not ideal, I know.

I've also just noticed that the formatting of the xml files isn't great. They should be fine under OSX but not on Windows. I'll touch them up too.

siread(Posted 2006) [#13]

Feature request: 'Mouse over' for the buttons. :)

siread(Posted 2006) [#14]
Here's something i put together this morning...

Fry Crayola(Posted 2006) [#15]
I'm in love!

I know I wrote the thing but as I've got the design ability of a sleeping wristwatch (and we all know they're terrible at design) I don't really do anything good.

I notice I need better text centering on the buttons. I forgot the y-axis.

Well, that's version 0.8 for you, or whatever I arbitrarily labelled it.

siread(Posted 2006) [#16]
Glad you like it. I need a Listbox for those panels, so i'm looking forward to an update. :P

BTW, how do i catch a button press manually? I tried this:

Global btnRefresh:fry_TButton = fry_TButton(fry_GetGadget("matchbuttons/btnrefresh"))
Global btnJoin:fry_TButton = fry_TButton(fry_GetGadget("matchbuttons/btnjoin"))
Global btnHost:fry_TButton = fry_TButton(fry_GetGadget("matchbuttons/btnhost"))
Global btnPractice:fry_TButton = fry_TButton(fry_GetGadget("matchbuttons/btnpractice"))

Select fry_EventSource()
Case btnPractice
Host = 1
Case btnHost
Host = 1
Ready = True
Case btnJoin
Host = 0
Ready = True
Case btnRefresh
lastrefresh = MilliSecs()
End If

But it doesn't work. What am I doing wrong?

Fry Crayola(Posted 2006) [#17]
You need to make sure you have fry_PollEvent() in your loop. That command will get the next event from the queue, so ideally you want to use something like

While fry_PollEvent()
handle your events here

fry_PollEvent returns 0 if the queue is empty, otherwise it updates a CurrentEvent variable which you can query with the fry_Event... functions, pretty much like the MaxGUI event handling but without the hooks.

Assuming you do have the polling somewhere else, the only thing left is to check your variables aren't null (i.e. that fry_GetGadget is returning the right gadgets).

Failing all that, it's my fault I guess.

siread(Posted 2006) [#18]
Ah, yes. I forgot the fry_PollEvent(). Cheers.

Sean Doherty(Posted 2006) [#19]
Is this based on Max GUI? Does it work in full screen? Can I use it for a screen such as the following:

Fry Crayola(Posted 2006) [#20]
It's not based on MaxGUI, it does work in full screen, and that screen is entirely possible from what I can tell. The list box on the right hand side would need to be a custom gadget (for your own sake - if the functionality was standard on a normal list box, it'd just negatively affect that list box when used normally).

Custom gadgets ought to be fairly simple to knock up, and when I've got a bit more free time I'll look into creating a tutorial for doing so.

Anyway, I'll upload a new version later in the week, as soon as I've got some nice scrollable areas working and implemented. List boxes are on the way, Si!

siread(Posted 2006) [#21]
Great news Fry. I know that you're developing this for your football game (yes, i'm an avid reader of your blog :P ) so would you have any issue with me using it for NSS4? I mean, it seems a bit cheeky on my part to do so when you've put in all the hard work, but it's absolutely perfect for the job. I'd be happy to make a donation or pay royalties once the game goes live.

Fry Crayola(Posted 2006) [#22]
Honestly, I have no problems whatsoever with you using it.

A game's about more than just an interface, it's about what you do with it underneath. Otherwise Football Manager would be just a spreadsheet.

Scienthsine(Posted 2006) [#23]
Just wanted to say that I plan to use this in a project of mine. One thing I can't find is text alignment. Would be nice ;)

Fry Crayola(Posted 2006) [#24]
I've done text alignment and it'll be in the new update, which ought to be this weekend, along with lists, mouseover, scrollboxes, a few random things, and some tweaks.

Scienthsine(Posted 2006) [#25]
Cool, cool. I can't stand not having a blinking cursor... a simple way to get one would be to change
DrawLine gCX + rX + gTX + 2, rY + 2, gCX + rX + gTX + 2, rY + (gH - 4) in TextField.bmx under 'Draw cursor' to something like
if (millisecs() / 500)&1 then DrawLine gCX + rX + gTX + 2, rY + 2, gCX + rX + gTX + 2, rY + (gH - 4)
Where 500 is the blinking interval in milliseconds.

deps(Posted 2006) [#26]
This looks sweet! Must try it out. :)

siread(Posted 2006) [#27]
How's this coming along Fry? I want to mess about with it some more but I need a listbox to go any further. Not nagging, just eager. :)

Fry Crayola(Posted 2006) [#28]
It's essentially done, just an untidy mess that wouldn't be great for releasing right now. All weird functions and undocumented source code. I'm a man of organisation, me.

There's a few small features I need here and there, and a bug in the lists that makes them crash if you click too low.

ninjarat(Posted 2006) [#29]
wow! i just downloaded it, and this is REALLY COOL!

Fry Crayola(Posted 2006) [#30]
OK, FryGUI version 0.9 is up!

Get it Here.

This download doesn't come with any precompiled example code, but you can grab those here:

Intel Mac

What's new?


Tables, or listboxes if you prefer (but I don't), are the major new gadget in this release. Each table can have any number of columns for each item in the table, allowing you to present a lot of detail in a single list.

Clicking on any item will generate an event which also contains the column number as well as item number.

As with any other gadget, the colours of the header and the items can be changed, though as yet you can't have differently coloured columns (one for the future).


Scrollboxes allow you to define an area of the screen that will scroll on two axes. Gadgets can be placed inside the scrollbox simply by defining the box as a gadget's parent.

Mouse Over event

As requested, gadgets now generate a MouseOver event which can be processed as you like.


Comboboxes now scroll their contents and have a defined maximum size they can reach before scrolling is required. They also have a lovely little arrow thing in the bottom right corner that indicates that the box might not be a button after all.

Any references to Captions are gone, which may irk anyone who's done extensive work with version 0.8 but it was a change that needed to be made. Methods such as SetCaption, SelectedCaption etc. are now referred to as SetText, SelectedText etc. to bring them in line with other gadgets.

Sorry about any inconvenience but it's for the best.

And a few minor updates have been made to buttons, which now centre their labels properly, and labels themselves which can be left, right or centrally aligned in either axes. Well, only on the horizontal axis. It'd be up, down and centre on the vertical. But you knew that.

Scienthsine - you'll have to put up with a non-blinking cursor a little while longer.

As before, let me know any problems.

dooz(Posted 2006) [#31]
I tried Fry 0.9, I can't seem to get it to compile. You say to rebuild the modules - how do you do that? The option is greyed-out in my IDE.

tonyg(Posted 2006) [#32]
Have you followed this ?

Booticus(Posted 2006) [#33]
TABLES!!!! Thats soo hot! Awesome job! Thanks a ton!

siread(Posted 2006) [#34]
Can't wait to get stuck into this. However, today i await a wii...

doswelk(Posted 2006) [#35]
Very useful mod!

Noticed some fun with the text field.....

It doesn't support multi-line yet...

Also holding down the delete key or space or backspace does not repeat i.e. holding down space adds one space only.

Other than that wonderful would not have got as far as I have with my project without it!

doswelk(Posted 2006) [#36]
I think this works:

Type fry_TImageButton Extends fry_TImage

Field gLink:fry_TScreen 'clicking button will switch to this screen

Update when the mouse is over
End Rem
Method UpdateMouseOver(x:Int, y:Int)

super.UpdateMouseOver(x, y)

End Method

Update when the mouse is pressed
End Rem
Method UpdateMouseDown(x:Int, y:Int)

super.UpdateMouseDown(x, y)

fry_CreateEvent(fry_EVENT_GADGETACTION, Self, 0, 0, 0, Null)

End Method

Update when the mouse is released
End Rem
Method UpdateMouseRelease(x:Int, y:Int)

super.UpdateMouseRelease(x, y)

fry_CreateEvent(fry_EVENT_GADGETSELECT, Self, 0, 0, 0, Null)

If gLink <> Null Then
fry_CreateEvent(fry_EVENT_SETSCREEN, Self, 0, 0, 0, gLink)
End If

End Method

bbdoc: Set the link
about: When clicked, the GUI will change to the specified screen. Set to $Null to disable.
End Rem
Method SetLink(screen:fry_TScreen)

gLink = screen

End Method

bbdoc: Set the link using the screen's name
about: Sets the link, specifying the name of the screen instead of the screen gadget.
End Rem
Method SetNameLink(screen:String)

Local scr:fry_TScreen = fry_GUI.GetScreen(screen)
If scr <> Null Then SetLink(scr)

End Method

Create an Image gadget
End Rem
Function Create:fry_TImageButton(name:String, URL:String, x:Int, y:Int, w:Int, h:Int, parent:fry_TGadget)

Local this:fry_TImageButton = New fry_TImageButton

this.gImage = LoadImage(URL, FILTEREDIMAGE)
If this.gImage = Null Then DebugLog "Image: "+URL+" not loaded."
this.gURL = URL

If this.gImage = Null Then Return Null

this.PopulateGadget(name, x, y, w, h, parent)

this.SetDimensions(w, h)

Return this

End Function

End Type

bbdoc: Create an image
returns: a #fry_TImage gadget
about: Creates an image, loaded from the given @url, with the specified @name and dimensions.
The @parent will usually be a panel, but can be another gadget.
End Rem
Function fry_CreateImageButton:fry_TImageButton(name:String, URL:String, x:Int, y:Int, w:Int, h:Int, parent:fry_TGadget = Null)

If name = "" Then Return Null

Local image:fry_TImageButton = fry_TImageButton.Create(name, URL, x, y, w, h, parent)

Return image

End Function

It should create an image button.

I'm sure Fry you can tidy it up...

Rook Zimbabwe(Posted 2006) [#37]
Fry you have done convinced me to go ahead and code my new POS system in BMax... I think I can adapt this to do what I need... Will hollar if stuck.

Sean Doherty(Posted 2006) [#38]

Download your GUI and the windows bin examples, but nothing seems to work? Whe I run the sample, the cmd window pompts up from a second and then exits? I moved the mod directory to under the mod directory for Max?

I'm not running the latest Max; does that mater?


Fry Crayola(Posted 2006) [#39]
The only thing I can think of off the top of my head is that I've been an idiot with these binary files (which I have) - they won't work at all on their own, they need to have a Skin folder to work with, which I've stupidly only included in the source download.

Make sure that the Skin folder from the source download is at the same path as the exe. I'm 99% sure that's the problem - it's looking for ./Skin/Graphics/button.png for example, not finding it and crashing as soon as it tries to display it.

siread(Posted 2006) [#40]
Hi Fry. Can you give us some info on how to add rows to tables?


Fry Crayola(Posted 2006) [#41]
You can add a row using AddItem(content, data, extra).

The content is an array of strings, one string for each column in the table. These are what are displayed when the table is rendered to the screen. The data is an integer, and can be used to store a numerical value for the item. You might not find any use for it but it can be good if the table was a list of nations, for example, and you needed an ID number for them. The extra object works the same way as MaxGUI - you can store any object here.

So in the screenshot in the first post, I might have AddItem(["Item 16", "16", "85", "1360"], 0, null) for one of the items.

Adding a column is simpler, using AddColumn(heading, width) where heading is the text used in the header, and then the width in pixels.

siread(Posted 2006) [#42]
What am i doing wrong here...

Global table_league:fry_TTable = fry_TTable(fry_GetGadget("league/table_league"))
' Name,P,W,D,L,F,A,Pts
table_league.AddItem(["Spurs","1","1","0","0","3","1","3"], 0, Null)
table_league.AddItem(["Arsenal","1","0","0","1","1","3","0"], 0, Null)

It adds a bit of scrollbar to the end of the first row (which was set up in XML).

Fry Crayola(Posted 2006) [#43]
From the looks of things, I'd say the table hasn't been set up properly in the XML. Have you set the height of the table (h="") to the right value? A scroll bar will appear if there are too many items to fit inside the area you define. Generally, if this area is an unsuitably small value (such as 0) the scrollbar will end up clearly dodgy looking.

Which leads me to the second thing - you appear to have set up two scroll boxes, or maybe just two scroll bars, to scroll any league table or fixture list. You won't need them - in defining the area that a table can take up, the system will automatically add the scroll bar if one is needed. This is all part of the Table, all automatically handled.

Keep the panel, then add the table, and define the height accordingly when doing so (it looks like the panels are about 400 pixels high, so a table height of 390 ought to do the trick). Then when adding the items they should appear fine.

siread(Posted 2006) [#44]
Ahh, beautiful! Cheers. :)

siread(Posted 2006) [#45]
A slight problem. When using D3D7Max2DDriver() there are issues with the table scrolling:

However, with GLMax2DDriver() everything looks fine:

Could be my laptop gfx card I guess.

Fry Crayola(Posted 2006) [#46]
Interesting. The scrolling is handled just by using a viewport, so it appears that on your card the viewport's not working properly. Then again, that's only a guess. Might be worth looking at that though.

I'm using DirectX on my PC with no ill effects. Haven't tried the laptop. Using OpenGL on the Mac is fine.

On my to-do list for the GUI is a drawing handler that will outright ignore any items that won't be seen on-screen. The main focus there is speed (things do seem to slow down if you've a large list, even with viewports) but it would also half-solve your problem. I might include a flag that can be set so that it won't draw anything unless it's fully visible, to avoid ugly overlapping. If I can also find some way to test if the viewports are working automatically, I can set that flag in code as well.

And finally, can anyone explain why I now have a huge craving for Fox's Glacier Fruits?

SpaceAce(Posted 2006) [#47]
I like the looks of this and I like the concept explanation in the original post; sounds very flexible and useful. Are there any plans to continue developing FryGUI?


Fry Crayola(Posted 2006) [#48]
FryGUI is being built for my current game, so I'll always be working on it to improve it, add new features that I might need etc. At the minute I think it's fairly powerful but it's missing a lot of "feedback", so to speak.

Everything's very static - the buttons don't press in, the cursor never changes. I'm currently focussing what it can do and then jazzing up how it does it, so the GUI ought to be in development for quite some time.

siread(Posted 2007) [#49]
Hey fry, how do i change the width of the drop-down on a combobox? The combobox itself is set ok (250) but the dropdown list hasn't changed.

Also, I'm drawing my own mouse pointer so it would be really useful if I could select the gadget type when the fry_EVENT_MOUSEOVER is triggered. Something like:

Select fry_EventSourceType()
Case fry_TButton
cursorimage = 2

Case fry_TLabel
cursorimage = 3
End Select

Is that possible at the moment? Of course, if you're going to implement your own cursor images then I won't worry about it for now. :)

Fry Crayola(Posted 2007) [#50]
At the minute, you can't set the width of the drop down. I plan to have it automatic if it goes over your own pre-set limit so that'll be in the next version.

Mouse pointers are also planned, eventually. I can't say for sure when as I'm still adding features over presentation, but I definitely want to do it. I may fudge something in as a placeholder though if there's demand.

I quit work in a week, so after that I've got much more time for everything.

doswelk(Posted 2007) [#51]
I know this sounds like a strange question, but does this work with multiple canvases?

I am thinking of using both your GUI and MaxGui in the same window, made up of three canvases...

Fry Crayola(Posted 2007) [#52]
I'm not quite sure what you mean, can you elaborate on that?

doswelk(Posted 2007) [#53]
Below is some code I created using Logic GUI, It should show you what I mean:

format_codebox(''Source Code created on 12 Jan 2007 23:53:33 with Logic Gui Version 1.1 Build 155
'Start of external Header File

'End Of external Header File

Local MainScreen:TGadget = CreateWindow:TGadget("Blitz Bowl",108,132,1024,780,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_MENU |WINDOW_CLIENTCOORDS )
Local Display2:TGadget = CreateCanvas:TGadget(642,515,320,195,MainScreen:TGadget,Null)
Local Display1:TGadget = CreateCanvas:TGadget(58,515,320,195,MainScreen:TGadget,Null)
Local Pitch:TGadget = CreateCanvas:TGadget(52,15,920,460,MainScreen:TGadget,Null)
Local Move:TGadget = CreatePanel:TGadget(406,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"Move")
Local TextBox:TGadget = CreateTextField:TGadget(392,515,236,194,MainScreen:TGadget,Null)
SetGadgetText( TextBox:TGadget,".")
Local btnEndTurn:TGadget = CreateButton:TGadget("Finshed Setup",431,721,162,29,MainScreen:TGadget,BUTTON_PUSH)
Local GFI:TGadget = CreatePanel:TGadget(436,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"GFI")
Local Block:TGadget = CreatePanel:TGadget(466,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"Block")
Local Blitz:TGadget = CreatePanel:TGadget(496,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"Blitz")
Local Foul:TGadget = CreatePanel:TGadget(526,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"Foul")
Local HandOff:TGadget = CreatePanel:TGadget(556,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"HandOff")
Local Pass:TGadget = CreatePanel:TGadget(586,480,30,30,MainScreen:TGadget,PANEL_BORDER|PANEL_ACTIVE,"Pass")

Select EventID()
Select EventSource()
Case MainScreen MainScreen_WC( MainScreen:TGadget )
End Select
Select EventSource()
Case MainScreen MainScreen_WS( MainScreen:TGadget )
End Select
Select EventSource()
Case btnEndTurn btnEndTurn_GA( btnEndTurn:TGadget )
End Select
Select EventSource()
Case Move Move_MD( Move:TGadget , EventData() , MainScreen:TGadget )
Case GFI GFI_MD( GFI:TGadget , EventData() , MainScreen:TGadget )
Case Block Block_MD( Block:TGadget , EventData() , MainScreen:TGadget )
Case Blitz Blitz_MD( Blitz:TGadget , EventData() , MainScreen:TGadget )
Case Foul Foul_MD( Foul:TGadget , EventData() , MainScreen:TGadget )
Case HandOff HandOff_MD( HandOff:TGadget , EventData() , MainScreen:TGadget )
Case Pass Pass_MD( Pass:TGadget , EventData() , MainScreen:TGadget )
End Select
Select EventSource()
Case Move Move_ME( Move:TGadget )
Case GFI GFI_ME( GFI:TGadget )
Case Block Block_ME( Block:TGadget )
Case Blitz Blitz_ME( Blitz:TGadget )
Case Foul Foul_ME( Foul:TGadget )
Case HandOff HandOff_ME( HandOff:TGadget )
Case Pass Pass_ME( Pass:TGadget )
End Select
Select EventSource()
Case Move Move_ML( Move:TGadget )
Case GFI GFI_ML( GFI:TGadget )
Case Block Block_ML( Block:TGadget )
Case Blitz Blitz_ML( Blitz:TGadget )
Case Foul Foul_ML( Foul:TGadget )
Case HandOff HandOff_ML( HandOff:TGadget )
Case Pass Pass_ML( Pass:TGadget )
End Select
Select EventSource()
Case Display2 Display2_GP( Display2:TGadget )
Case Display1 Display1_GP( Display1:TGadget )
Case Pitch Pitch_GP( Pitch:TGadget )
End Select
End Select

Function MainScreen_WC( Window:TGadget )
DebugLog "Window MainScreen wants to be closed"
' HideGadget( Window:TGadget )

'Start source added by Function File
'End of source added by Function File
End Function

Function MainScreen_WS( Window:TGadget )
DebugLog "Window MainScreen was sized to "+GadgetWidth( Window:TGadget )+" , "+GadgetHeight( Window:TGadget )
'Start source added by Function File
'End of source added by Function File
Local x:Int =GadgetX(window)
Local y:Int =GadgetY(window)
Local w:Int =1024
Local h:Int =768
End Function

Function btnEndTurn_GA( Button:TGadget )
DebugLog "Button btnEndTurn was pressed"
'Start source added by Function File
'End of source added by Function File

End Function

Function Move_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel Move detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function GFI_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel GFI detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function Block_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel Block detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function Blitz_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel Blitz detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function Foul_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel Foul detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function HandOff_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel HandOff detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function Pass_MD( Panel:TGadget , MouseButton:Int , Window:TGadget=Null , PopUpMenu:TGadget=Null )
DebugLog "Panel Pass detected Mouse Button "+ MouseButton +" pressed down"
'Start source added by Function File
'End of source added by Function File

End Function

Function Move_ME( Panel:TGadget )
DebugLog "Panel Move detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function GFI_ME( Panel:TGadget )
DebugLog "Panel GFI detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Block_ME( Panel:TGadget )
DebugLog "Panel Block detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Blitz_ME( Panel:TGadget )
DebugLog "Panel Blitz detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Foul_ME( Panel:TGadget )
DebugLog "Panel Foul detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function HandOff_ME( Panel:TGadget )
DebugLog "Panel HandOff detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Pass_ME( Panel:TGadget )
DebugLog "Panel Pass detected Mouse entered panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Move_ML( Panel:TGadget )
DebugLog "Panel Move detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function GFI_ML( Panel:TGadget )
DebugLog "Panel GFI detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Block_ML( Panel:TGadget )
DebugLog "Panel Block detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Blitz_ML( Panel:TGadget )
DebugLog "Panel Blitz detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Foul_ML( Panel:TGadget )
DebugLog "Panel Foul detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function HandOff_ML( Panel:TGadget )
DebugLog "Panel HandOff detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Pass_ML( Panel:TGadget )
DebugLog "Panel Pass detected Mouse left panel"
'Start source added by Function File
'End of source added by Function File

End Function

Function Display2_GP( Canvas:TGadget )
DebugLog "Canvas Display2 needs to be redrawn"
SetGraphics CanvasGraphics ( Canvas )
SetViewport 0,0,GadgetWidth( Canvas ),GadgetHeight( Canvas )
SetClsColor( 80,0,0 )
SetColor( 0,0,0 )
DrawText( "LogicZone" ,1,1 )
'Start source added by Function File
'End of source added by Function File

End Function

Function Display1_GP( Canvas:TGadget )
DebugLog "Canvas Display1 needs to be redrawn"
SetGraphics CanvasGraphics ( Canvas )
SetViewport 0,0,GadgetWidth( Canvas ),GadgetHeight( Canvas )
SetClsColor( 80,80,128 )
SetColor( 0,0,0 )
DrawText( "LogicZone" ,1,1 )
'Start source added by Function File
'End of source added by Function File

End Function

Function Pitch_GP( Canvas:TGadget )
DebugLog "Canvas Pitch needs to be redrawn"
SetGraphics CanvasGraphics ( Canvas )
SetViewport 0,0,GadgetWidth( Canvas ),GadgetHeight( Canvas )
'Start source added by Function File
'End of source added by Function File

End Function

'Start of external Append File
'Your additional code should be here!

'End Of external Append File

Here is a piccy of waht I am trying to achieve (this was written purely with FryGui)

Basically in the two Canvas Display1 and Display2 I want to be able to create two of you Gui tables like I have in the picture above...

Failing all that a way to make the text field in the middle of the screen multi line with a scrollbar!

Fry Crayola(Posted 2007) [#54]
I'm afraid it's unlikely that you'll be able to run two or more instances of the GUI at the same time. However, multiline text fields are on the great big To Do list.

siread(Posted 2007) [#55]
Hi Fry. I was wondering if you are considering implementing localisation in your gui. I don't know much about XML but I imagine it would be possible to have your text fields refer to a seperate string file. So instead of having text="Hello" you would use something like text=$Hello. That would then check a localised string file and pull up "Bonjour" or whatever. Just an idea. :)

Fry Crayola(Posted 2007) [#56]
Well worth thinking about, yeah. I'll have a play around and see what I can come up with.

siread(Posted 2007) [#57]
I've noticed a slight problem with the combos. If you open the dropdown menu and choose something so that it appears in the text field, then open the dropdown again but select outside of the dropdown, the previously selected text stays in the text field but the actual selected item is -1.

This can be confusing if you're validating the selection because to the user it looks as if something has been selected but the program thinks it's empty.

siread(Posted 2007) [#58]
BTW Fry, you might be interested to know that your gui works very nicely with miniB3D (using Klepto's module version.) :D

Fry Crayola(Posted 2007) [#59]
I fixed the combo box problem last week, I had noticed it myself. The problem was that every time it opened, it changed the selected item to -1 so that it wouldn't highlight the actual item (the open combo box is just a table gadget inside a box, so it highlights the selected item).

I just added another field to the table item that allowed you to stop highlighting the selected item, and all is good.

Elsewhere, I've also added a working canvas gadget which will call a function of your choice when it's time to be drawn, allowing you to have graphics in the GUI that sit in their correct place, rather than be drawn on top of everything.

Si - with that MiniB3D, have you changed FryGUI's draw commands to use those in MiniB3D, are they Max2D commands still, or does MiniB3D implement its own draw functions using the same command set?

siread(Posted 2007) [#60]
Klepto's module version of miniB3D allows you to use Max2D commands. The only requisite is that you use the 2D commands after Renderworld . You also need to use ALPHABLEND for the 2D.

This should make match options and stat screens a doddle. :)

Check klepto's thread in the MiniB3D forum:

Chris C(Posted 2007) [#61]
The only requisite is that you use the 2D commands after Renderworld

You can use cameraclsmode and render 2d before and after render world, using ALPHABLEND is a valid technique but is not mandatory

siread(Posted 2007) [#62]
Hey Fry, I just updated my blog with some new screenies. This episode is all about the gui. :)

Fry Crayola(Posted 2007) [#63]
Looking good, Si. Kinda makes me wish it was sitting in front of me, playable.

I must say, though, you don't look a day over 1996.

siread(Posted 2007) [#64]
Hi Fry. I've come across a bug, but i'm not sure if it's a problem with the gui or my code. Basically when switching between certain screens all of the controls (buttons, check boxes etc) stop responding. What's weird is my code does the same thing for every screen (checks the screen name then then does a While fry_PollEvent() specific to that screen and then acts on the event ids.) This works fine unless i switch between certain creens. Moving from my Player View screen and the Option screen for instance. It also occurs when quitting a game and going back to the main start screen. To change screen i'm simply using fry_SetScreen("homescreen").

I've run the program in debug mode to check that the correct fry_PollEvent() function is being called and it is. It just never picks up an event. It's probably my fault, but i'm stumped. Have you noticed anything like this yourself?

siread(Posted 2007) [#65]
I've fixed it by calling fry_Refresh() before manually changing screens. It seems that the gui was catching a click on the panel behind my button, then when switching screens the event was somehow stuck in the queue and no new events on the next screen could be caught.

Fry Crayola(Posted 2007) [#66]
Interesting... I've not come across that one before, but I tend to handle my events differently by having one single While fry_PollEvent() loop, which then calls various functions to catch events on different screens.

What I'm not sure about here is how any event would get stuck - surely the While loop would loop around again and pick the next one? Might well be code specific.

siread(Posted 2007) [#67]
Is it possible to reload the gui graphics during runtime so that you can change the style of the gui on the fly?

Fry Crayola(Posted 2007) [#68]
Not yet ;)

Actually.... maybe it is but I've never tried it. You can use LoadSkin() to reload the graphics (this is all it does, after all) and it should just work. But as I've said, I've not actually tried it so there's always a chance it won't.

One thing I want to add in a later version is the ability to load an entirely new skin in, panels and all, much like FM - although exactly how much the layout can change will really depend on your own code (as you'll need gadgets to remain on specific panels).

siread(Posted 2007) [#69]
Yep, it works. :) Only thing is, you need seperate Skin folders which means if you want to just change the graphics you need to include all the fonts, screens and panels in the folder. Unless there's a way around that.

Fry Crayola(Posted 2007) [#70]
The GUI panels, screens and fonts are only generated at the moment by calling fry_ParseGUI(). fry_LoadSkin() just loads in the graphics.

So you'd only really need a Skin/Graphics folder, without the fonts, screens and panels. That's if you want to reload a new skin during the game.

Perhaps I'll see about including separate Graphics folders to choose from when building the GUI.

doswelk(Posted 2007) [#71]

I currently playing with tables....

I have a table that sometimes the text for a column is too long, so the text spills over the following columns.

If I adjust the column to be the right width, then the table becomes too wide for the panel and no horizontal scroll bar is displayed.

Is there way to add a horizontal scroll bar? Would I need to put the table inside a scroll box?

Is there a way to limit the text to the column width?

doswelk(Posted 2007) [#72]
I've been playing some more and by placing a table inside a scollbox I can almost get what I wanted.

But I am getting a strange effect.

The text for the rows is visible outside of the panel but the headings display correctly.

Fry Crayola(Posted 2007) [#73]
Interesting. I'll have a look at the tables and see if I've missed a viewport command somewhere. I'm aware the text spills over into other columns so I'll be looking to fix that too for the next update.

doswelk(Posted 2007) [#74]
What I found interesting, was if the table is one column long the text does not spill over, until a second column is added.

I'll plug on regardless because I still find FryGUI very good....

Any idea when an update would be forthcoming?

Fry Crayola(Posted 2007) [#75]
If it's one column long, it won't spill over because the viewport is set for the entire table, which is exactly the length of that one column.

An update should be on the way soon, all being well. As soon as I get it tidied up, really.

H1z(Posted 2007) [#76]
I think the download is down. Can you please upload it again?


Fry Crayola(Posted 2007) [#77]
Hmm, online storage seems to be down, so I've nowhere to host it at the moment.

doswelk(Posted 2007) [#78]
Is there a way to get the length of a label before you create it?

I notice that that in the refresh method gW is set to the TextWidth of the label, but is there anyway to get hold of that?

I'm trying to create a messagebox function, so I need to create a panel big enough to display the labels.

Fry Crayola(Posted 2007) [#79]
The only way to get the width that any label might be before you create it is to set the font (SetFont fry_GetFont("font name")) and then do a textwidth.

If the label already exists, you can just use label.gW for now I guess.

doswelk(Posted 2007) [#80]
I'll give that a try...

At the moment I have been creating the label at -x and -y co-ords and then changes the values using gXOrig and gYOrig, and a refresh() after....

Buttons have been the main problem, I've been looking at creating a label to get the width and height, and then creating a label, but I'll try you above suggestion.


popcade(Posted 2007) [#81]
Whta's the current build number BTW?

This is pretty cool and nice, but I don't know if it's updated recently?

Fry Crayola(Posted 2007) [#82]
The available build is 0.9, and it's been quite a while since that was released.

0.9135321245 (these build numbers are really just for show, to make me feel important) ought to be released whenever I can get around to it, it's just a matter of finding the time to clean up the loose ends. It does have canvases, image buttons and cursors though, and also two extra gadgets that exist purely because I really needed them so maybe other people do too.

doswelk(Posted 2007) [#83]
Well nearly finished the message box code, I'll post it here if someone wants it, I just to need to add support for an icon, and I'll be there...

It won't be the neatest of code, but it seems to do the job...

now all I have to do is write the actual game!

siread(Posted 2007) [#84]
Mmm, message box. I'm looking forward to that. Will come in very handy. :)

doswelk(Posted 2007) [#85]
Well here is my Messagebox....


Import fry.frygui

Global Width:Int = 800
Global Height:Int = 600

Graphics Width,Height,0
' Set up screens For GUI

' Load a skin

' Add fonts
fry_AddFont("Default" , "vinque.ttf" , 16)
fry_AddFont("Large" , "vinque.ttf" , 16 * 1.5)

' Create the screen
Local MainScreen:fry_TScreen = fry_CreateScreen("MainScreen")

fry_SetScreen ("MainScreen")

Local icon:String = "Images/buttons/Apoth.png"

If icon = Null Then DebugLog "Error loading image"

Local message:TList = CreateList()
'message.AddLast("This is an error message:")
'message.AddLast("An error has occurred!")
'message.AddLast("What a shame that this has happened!")
'message.AddLast("I mean what are the chances of that occuring?")
'message.Addlast("Do you want to continue ?")

Local buttons:TList = CreateList()

Local error:String = Messagebox(Mainscreen, icon, 128, "Testing", message, buttons,"0000BB","EEEEEE","DDDDDD","000000","Large","Default")

DebugLog "Result was: " + error


Until KeyHit(key_escape)

Function Messagebox:String(screen:fry_TScreen, icon:String, iconsize:Int, title:String, message:TList, buttons:TList, tHexColour:String, tHexTextColour:String,mHexColour:String,mHexTextColour:String, titleFont:String="", msgFont:String="")
screen - The screen to add the panels to
icon - The url path to the icon to display
iconsize - Size of the icon
title - Message box title
message - the Tlist containing the message
buttons - the Tlist containing the button text (limited to a maximum of 3)
tHexColour - Title Panel Colour
tHexTextColour - Title Panel text Colour
mHexColour - Message panel colour
mHexTextColour - Message panel text colour
titleFont - The font to display in the title with.
msgFont - the font to display the message with.

Local result:String

Local x:Int ' X value of messagebox
Local y:Int ' Y values of messagebox
Local w:Int ' width of messagebox
Local h:Int ' height of messagebox
Local bx:Int ' X value of button
Local by:Int ' Y value of button
Local bw:Int ' button width
Local bh:Int ' button height
Local mx:Int ' X value of message text
Local my:Int ' Y value of message text
Local mw:Int ' message width
Local mh:Int ' message height
Local msgIcon:fry_Timage

' Create a panel
Local msgBox:fry_TPanel = fry_CreatePanel ("msgBox",x,y,w,h,Null)

' create a panel for the title
Local titleBox:fry_TPanel = fry_CreatePanel ("titleBox",x,y,w,h,Null)

' Create a label for the title
Local lblTitle:fry_TLabel = fry_CreateLabel ("lblTitle",title,x,y,w,h,0,0,titleBox)

If TitleFont

' Set the width to the width of the title
w = lblTitle.gW
h = lblTitle.gH

' Create the labels for the message

Local msgLine:fry_TLabel[CountList(message)]

Local count:Int
For Local text:String = EachIn message
Local lx:Int

msgLine[count] = fry_CreateLabel ("msgLine" + count , text , x , y , w , h , 0 , 0 , msgBox)
If msgFont
'my = msgLine[count].gY + msgLine[count].gH

' find the longest line and set it to mw
If mw < msgLine[count].gW Then mw = msgLine[count].gW
DebugLog mw
count:+ 1

' Create the buttons

' create a label "offscreen" and use it to get the widths and heights for the buttons
Local btnlabel:fry_TLabel = fry_CreateLabel ("btnlabel" , "" , -30 , -30 , 0 , 0 , 0 , 0 , msgBox)
If TitleFont

' Loop through all the buttons to find the widest
For Local btn:String = EachIn buttons
If bw < btnlabel.gW Then bw = btnlabel.gW
If bh < btnlabel.gH Then bh = btnlabel.gH

' Dispose of btnLabel
btnlabel = Null

' Create the buttons
Local btnMSG:fry_TButton[CountList(buttons)]

count = 0
For Local btn:String = EachIn buttons
btnMsg[count] = fry_CreateButton ("btnMSG" + count, btn, bx, by, bw, bh, msgBox)

' Messagebox created now create x,y,w,h settings
w = lblTitle.gW

For Local count:Int = 0 To msgLine.length -1
If w < msgLine[count].gW Then
w = msgLine[count].gW

' Ensure that msgBox is wider then bw * # of buttons
If w < bw * CountList(buttons) Then w = bw * CountList(buttons)

' Create a space either size to centralize the text
Local oldwidth:Int = w
w:+ (w /8)
DebugLog "W:" + w + ", MW:" + mw + ", oldWidth:" + oldwidth
mx = (w - oldwidth) /2 '((oldwidth - mw) /2)

' Set a height for the messagebox
h = msgLine[0].gH * (CountList(message) )' +1)

' If there is an icon leave room for an icon and add it
If icon Then
w:+ (iconsize * 1.5)
mx:+ iconsize + (iconsize / 4)

' Check that the height is big enough for the icon
If h < iconsize Then h = iconsize

msgIcon = fry_CreateImage ("msgIcon", icon, 0, 0, iconsize, iconsize, msgBox)

' Change the x , y , w amd h settings for message boxes and refresh them

msgBox.gW = w
msgBox.gH = h
msgBox.gX = (width - msgBox.gW ) /2
msgbox.gY = (height - msgBox.gH ) /2

titleBox.gX = (width - w) /2
titlebox.gY = msgbox.gY - (lblTitle.gH /2)
titleBox.gW = w
titleBox.gH = lblTitle.gH

' Adjust the title
lblTitle.gOrigX = w /2
lblTitle.gW = w

' Adjust the message
For Local count:Int = 0 To msgLine.length - 1
msgline[count].gOrigX = mx
msgLine[count].gOrigY = (count +1) * msgLine[count].gH

' Adjust the icon (if it exists)
If icon Then
msgIcon.gX = iconsize / 4
msgIcon.gY = msgLine[0].gY

' Adjust the buttons

' first make some room

Local oldheight:Int = msgBox.gH
h = oldheight + (bh * 2.5)
by = oldheight + bh
msgBox.gH = h

Select btnMSG.Length
Case 1
bx = (w - bw) /2
btnMsg[0].gX = bx
btnMsg[0].gY = by
Case 2
bx = bw /8
btnMsg[0].gX = bx
btnMsg[0].gY = by
bx = w - bw - (bw /8)
btnMsg[1].gX = bx
btnMsg[1].gY = by
Case 3
bx = bw /8
btnMsg[0].gX = bx
btnMsg[0].gY = by
bx = (w - bw) /2
btnMsg[1].gX = bx
btnMsg[1].gY = by
bx = w - bw - (bw /8)
btnMsg[2].gX = bx
btnMsg[2].gY = by



While fry_PollEvent()
Select fry_EventSourceName()
Case "btnMSG0"
result = btnMSG[0].gText
Case "btnMSG1"
result = btnMSG[1].gText
Case "btnMSG2"
result = btnMSG[2].gText
End Select
Until result <> Null 'KeyHit(key_escape) Or AppTerminate()



Return result
End Function

This code works but I'm sure it could be made neater....

Please play with and let me know of issues, the thing to note is that you are limited to a maximum of three buttons, you can add more to the list but none will be displayed.

The parameters for Messagebox are numerous, but this was to allow maximum customization...

siread(Posted 2007) [#86]
Hey Fry. Does the gui register Right mouse clicks?

Fry Crayola(Posted 2007) [#87]
Nope. Not yet, at any rate.

siread(Posted 2007) [#88]
Great news!!! I stumbled across Brucey's Localisation module today and with a couple of tweaks FryGUI can make full use of it!

Install the bah.Locale mod.
Add "Import bah.Locale" to frygui.bmx.
Then for each gadget change "DrawText gText,x,y" to "DrawText GetLocaleText(gText),x,y"

Then if as long as your text field equals a Tag Name it will display the text in your chosen language. :)

Fry Crayola(Posted 2007) [#89]
Interesting... I'll have a look at that.

siread(Posted 2007) [#90]
Actually, it's easier and makes more sense to just change xmlfrygui so that it does the translation when it parses the xml file.

If gText Then gText = GetLocaleText(gText)
If gHeading Then gHeading = GetLocaleText(gHeading)

That way, if you populate gadgets at run-time with text that isn't in your language file (team names for example) they won't get translated when displayed. (Text without a translation returns with an @ in front of it.)

Fry Crayola(Posted 2007) [#91]
I'll have to take a good look at Brucey's module. Localisation's still only in the back of my mind though, for various other reasons (which I'm sure you can guess).

siread(Posted 2007) [#92]
Sure. The good thing is it's a cinch to include even at a late stage of development.

Fry Crayola(Posted 2007) [#93]
At long last, I've finally updated this, and it can be downloaded via the link in the sig.

The new gadgets are as follows:

Canvases: actual real, live canvases that work and everything. By declaring the function you want to be called whenever the canvas is due to be redrawn, you can have dynamic graphics integrated right into the GUI.

In addition to being able to alter the graphics, the canvas also registers button presses and cursor location like any other gadget, which makes it ideal for use in any game as the main game display.

Image buttons: Wahey! Icon city! Buttons can now be formed using images, with or without their standard background. The hitboxes for these buttons can be rectangles or circles, depending on your needs.

Date panels: Seeing as I needed date panels for my own use, I figured others might too. They work like a combo box that displays a date, and when clicked a mini-calendar will drop down to allow you to choose a different date.

Dates are stored in the system as Julian Days, with January 1st 1900 (rather than the standard 4713BC, to save on memory usage, though this can be easily altered) as the zero date. Please refer to the fry.frydate module for further information and functions to manipulate and use these dates.

Searchbox: Another gadget similar to a combo box, except this time it comes with a text field built into the drop down menu. Search boxes will call the function of your choice when text is entered, and can be used where you want the ability to narrow down the options in a combo box. Refer to the example contained in the zip file for more information... hopefully it'll be clear.

Cursors: The GUI now supports varying cursors. Nothing too extensive as yet, there are cursors for hovering a mouse over a clickable gadget and pressing down that gadget. Text carets have still to be included.

This GUI should be stable but let me know if you've encountered any errors. The system comes with a number of extra modules which may provide some extra use, but only a few functions are used by the GUI (for example, in fry.frydraw, only fry_SetViewport is used, with the rest being effective WIPs for other projects).

The modules have been pre-built for Mac OS X and Windows.

Hopefully I can get things together over the next while and clean up the loose ends.

Mr. Write Errors Man(Posted 2007) [#94]
I just downloaded it, but included examples do not work properly. I guess only three panels get drawn. I do get debug prints for events if I click around the screen.



Fry Crayola(Posted 2007) [#95]
Thanks, fox, I'll take a look at this. I've probably missed something, my files are a bit of a mess this last while.

Fry Crayola(Posted 2007) [#96]
Hmm, I'm getting no problem here from the fresh download, everything's working correctly.

From the looks of things, that's an 800x600 screen you have there. The included example source code in the download is a 1024x768 application, while the extra download is 800x600 but should still work.

That you're getting graphics and events at all is very strange. You're definitely running the included source code?

Mr. Write Errors Man(Posted 2007) [#97]
Yes, I am running the included example code. The XML version gives the same result (though I guess it displays more panels).

I actually downloaded the previous version just before you posted the update. Then I downloaded the updated version but it gave the same result. I also downloaded the compiled example exe and it worked the same. I also rebuilt the modules. :\

I'll remove everything and do a fresh install a bit later today as I get home and let you know how it works.


Mr. Write Errors Man(Posted 2007) [#98]
You are right, I was running old version. Must have been some kind of browser cache issue.

However, end result is still the same. Only panels (I suppose) get drawn and I do get events (though getting them is harder this time, because I don't have a mouse cursor :> ).

Weird stuff. I guess I could try to debug it...


Fry Crayola(Posted 2007) [#99]
Certainly most odd. Now that you're running the new version, is it in 1024x768 this time out? I presume so.

Mr. Write Errors Man(Posted 2007) [#100]
Yes, it's 1024x768.

Any ideas on what I could check?


siread(Posted 2007) [#101]
New version is working fine for me. Just converting all my old "manual" image buttons into FryImageButtons. :)

AF, have you tried changing the graphics driver to...

SetGraphicsDriver GLMax2DDriver()

I get problems on my laptop with DirectX.

Mr. Write Errors Man(Posted 2007) [#102]
Ah! You are right siread, it works if I use a GL driver!

Any idea why it doesn't work with DX driver? I have old GeForce 4 MX 440 card, but I haven't experienced any DX problems before.


Fry Crayola(Posted 2007) [#103]
Best guess at this time is that it's a viewport problem, judging from a problem Si had in the past. See, you're getting the panels drawn, but I'm thinking that whenever it changes the viewport to draw only within each panel, it's not working 100% correctly.

It may be down to the fry_Viewport function that I've used (which will take into account existing settings, and not exceed them), or it may be something else.

Mr. Write Errors Man(Posted 2007) [#104]
Yes, seems it's viewport stuff. It works as expected if I comment out the SetViewport line.


doswelk(Posted 2007) [#105]

Has the fry_refresh() code changed in the new version?

I get "Unhandled Exception:Attempt to access field or method of Null object" at that line every time?

Fry Crayola(Posted 2007) [#106]
fry_Refresh() is pretty much the entire GUI. You'll have to open several of the GUI files to work out exactly where it's failing, as the MaxEdit debugger doesn't seem to open these files for me, instead just failing at that fry_Refresh() line.

Is this with the included example or your own code? If it's the latter, if you can post some that would help.

siread(Posted 2007) [#107]
Hi fry.

If i select a table item like so:


How do I ensure that the table is scrolled so that the selected item is visible?

Fry Crayola(Posted 2007) [#108], create a pop-up message telling the user to scroll.

I'll add that to the list of things to do. If you need a quick fix, you can get the scrollbar gadget in question by using fry_GetGadget(<tablename>:Scroll) and then set that appropriately using the height of an individual item as a guide.

siread(Posted 2007) [#109]
I tried that but it didn't update until I moved the mouse over the table. Even after forcing a refresh to the panel, table and scrollbar.

Fry Crayola(Posted 2007) [#110]
Ah, I was just guessing. Seems I don't update that until specific points, as it was coded just for when you scroll manually.

I'll have a look into it, it'd certainly be useful.

doswelk(Posted 2007) [#111]
@Fry It was the message box code I'd posted above....

Fry Crayola(Posted 2007) [#112]
Hmm. I'm getting the "attempting to access field or method of null object" on this bit:

format_code(' ' Adjust the icon (if it exists)
If icon Then
msgIcon.gX = iconsize / 4
msgIcon.gY = msgLine[0].gY
EndIf ')

When I comment that out, it displays fine but leaves cursor trails (it's not clearing the screen properly by the looks of things) and the message box doesn't really do anything.

siread(Posted 2007) [#113]
Hi fry. I had an idea, whereby you create a Skin than is neutral (greyscale) then by simple changing the colour of all the gadgets you can change the colour of the entire gui without loading a new skin.

I created this function in frygui.bmx:
Function fry_SetGuiColour(col:String="FFFFFF", txtcol:String="000000")

For Local g:fry_TGadget = EachIn fry_GUI.gPanels

For Local e:fry_TGadget = EachIn fry_GUI.gExtras

End Function

Now when I set a new colour scheme with fry_SetGuiColour("00FFFF", "FF00FF") it changes the panel colours as expected but the text and the other gadgets (buttons, combos etc) stay the same...

Any idea why only the panels change?

Fry Crayola(Posted 2007) [#114]
Yep, you're only changing the colours of the panels. You've got your loop running through the fry_GUI.gPanels list.

All the other gadgets are children of those panels, so you'd need to get another loop going.

format_code('For Local g:fry_TGadget = EachIn fry_GUI.gPanels

For Local child:fry_TGadget = EachIn g.Children

That should do it in a simple way. However, some gadgets may have children of their own so you'd be better off doing it recursively.

I had similar plans myself to get the GUI system to support colour schemes. I put it on hold while I worked on other aspects but I do plan to return to it, and hopefully create one that doesn't need to be a single colour.

siread(Posted 2007) [#115]
Ahh, stupid me. I thought the extras where the buttons and stuff. Thanks.

siread(Posted 2007) [#116]
This now creates multiple colour scheme:

Function fry_SetGuiColour(pancol:String="FFFFFF", butcol:String="FFFFFF", txtcol:String="000000")
For Local g:fry_TGadget = EachIn fry_GUI.gPanels

If g.gChildren Then fry_ColourGadgets(g, butcol, txtcol)

For Local e:fry_TGadget = EachIn fry_GUI.gExtras

If e.gChildren Then fry_ColourGadgets(e, butcol, txtcol)
End Function

Function fry_ColourGadgets(g:fry_TGadget, col:String, txtcol:String)
For Local child:fry_TGadget = EachIn g.gChildren

If child.gChildren Then fry_ColourGadgets(child, col, txtcol)
End Function


Fry Crayola(Posted 2007) [#117]
Ahh, stupid me. I thought the extras where the buttons and stuff. Thanks.

The "extras" are anything that doesn't belong to a panel - mainly when you open a combo box. The reason is that this open combo box needs to be displayed over the top of anything on that screen, so needs to be drawn last instead of whenever its panel is displayed.

Not the most descriptive of names, I know.

siread(Posted 2007) [#118]
Hi Fry. Can I put in a request for disabling gadgets? This would make buttons and combos appear transparent and clicking on them would have no effect.

Sometimes it's nicer to see a button and know it's inactive rather using Hide() to hide it altogether. I know that I could set the alpha myself and just ignore commands but with combos you are still able to open the dropdown list.


Fry Crayola(Posted 2007) [#119]
I thought they could be disabled. It appears I was very, very wrong. I must have forgotten to put it in.

TaskMaster(Posted 2007) [#120]
I am playing with this right now, and am wondering why you would make something public with an error message that print "What the F..k?" :O

I have edited it out, but hope that I don't find any more "Easter Eggs"... ;)

Fry Crayola(Posted 2007) [#121]
Ah, yes. The messages. I think that's the only bit of swearing that's in there. There's probably other messages that don't make any sense (I've been doing that all my life, I used to hand in exam papers that had little exclamations of joy dotted around complex mathematical working).

I'll have to clean it up a bit more for the next release, that last one I was more concerned with getting an update out for a few people that were waiting on a feature or two I had already done.

TaskMaster(Posted 2007) [#122]
Hi Fry. I really like your GUI mod. I have changed the ImageButtons to allow for a mouse over image. I am also considering making the Events a bit more detailed. I would like a MouseOver, MouseDown, MouseUp, Click, Changed, etc.

Correct me if I am wrong, but right now, your controls will respond to a mouse up, no matter where the mousedown happened. That is fine, but I would like a Click Event or something that only happens if the mousedown and the mouseup both happened while the mouse is hovering over the gadget. If a player is dragging some cards in my game and they happen to reales the mouse while hover over a button, the mouse button responds.

So, I am making some changes, would you like to see any of the changes I make?

Thanks for releasing this to the public, it is very good.

Fry Crayola(Posted 2007) [#123]
You're right, MouseUp does seem to always get a response. Odd, I was certain it didn't. Oh well, something more for me to work on. Ta for that!

siread(Posted 2007) [#124]
Fry, I'm having a problem displaying unicode characters. If I load names like these from my database:

Juho Mäkelä or José Gonçalves

They display all messed up like this...

If I write them to the debuglog they appear fine, so I know they are loading ok. Any idea what's happening?

Fry Crayola(Posted 2007) [#125]
Yes, you need to use a unicode input stream I noticed the same problem when reading in CSV files last week.

Replace a general ReadFile command in your database loading code with something like the following:

OpenStream("utf8::"+filename, True, False)

This will specify unicode. Works perfectly fine for me. The GUI should display anything that your chosen font have characters for, unless there's something about BlitzMax I don't know.

Edit: Whoa, just noticed you said they're fine in the debuglog. Weird.

Can I see the specific code, if possible?

siread(Posted 2007) [#126]
Well, after a bit more investigation it appears to be a problem with TeaMonkey's SQLite module.

I tried a simple DrawText and it writes the same corrupt characters to the screen. (Strange how the debuglog shows it fine though.)

I then experimented with Brucey's database module and it draws text from the same database just fine.

Question now is, do I try to fix the current SQLite module or convert everything to Brucey's module. *Pulls out hair*

Fry Crayola(Posted 2007) [#127]
Well, that would depend on how complex a fix it is. There's nothing more annoying to me than finding an issue with a module and needing to convert to a new one.

Mind you, that's pretty much why I wrote FryGUI in the first place, to avoid those issues. Or at least have someone to blame :)

siread(Posted 2007) [#128]
Hey Fry, I notice that ClearItems() (in a combo) creates a fry_EVENT_GADGETSELECT. Is it supposed to?

It took me ages to work out why I was getting duplicate calls of the same event when I was simply clearing the combo items, populating the combo, then selecting an item with SelectItem(n).

Fry Crayola(Posted 2007) [#129]
It creates that event because in clearing the items, you're then selecting a new item (a null item).

I'm not sure I've ever needed that though. If it's causing problems with your code, I might just create a different event type for it.

siread(Posted 2007) [#130]
I've just put a "While fry_PollEvent() Wend" after each ClearItems to flush the queue. (Is there a better way?) Anyway, it solves my problem.

Fry Crayola(Posted 2007) [#131]
There's no queue flush at the moment. I'll add that one in. But I reckon I'll probably include a fry_EVENT_GADGETCLEAR to replace the GADGET_SELECT, especially as lots of gadgets are being used to store lots of data. I'll have specific clear functions for text fields, dates etc. that will set the fields to blanks or default values.

.rIKmAN.(Posted 2007) [#132]
Just been enlightened to your GUI bu Siread (Thanks again Si!) and it seems so perfect for my project that I am actually going to ditch B3D and learn BMax just so I can use it!

I`ve been fiddling with BCF in B3D for a while but your GUI just has more features suited to what I need - great job you should be proud of what you created!

So, my first question (of many I`m sure)....

It`s been a month since the last post, is this still being updated?

I know you say it spawned from you needing it for your own game - does this mean once the game is done development on the GUI will be done too?
I just don`t want to take time learning BMax and the syntax etc only to find it is no longer updated, I`m sure you understand!

The fact Siread is using it for NSS4 gives me great confidence tho :)

Keep up the great work, I should be getting down and dirty with it by the weekend, gonna get my teeth into some BMax syntax til then :)

TaskMaster(Posted 2007) [#133]
The last version he posted has a few simple bugs. But the source is there and it did not take me long to understand it, as it is written pretty well and organized.

I made quite a few changes to it while I was working on a project that used it. But I only fixed the controls I was using and probably broke the others and have not taken the time to go make them all work with the changes I made to the core.

But, as I was saying, it is easy to make changes and fix the small things you find wrong with it. It is a very good framework and could be great if someone took the time to fix the little issues and make some improvements.

Fry Crayola(Posted 2007) [#134]
I know you say it spawned from you needing it for your own game - does this mean once the game is done development on the GUI will be done too?

Not at all. First up, my own game is taking ages anyway so there's probably another good twenty years before that's done.

But secondly, even when that mythical game gets finished, I'll be still working on the GUI. There'll always be new uses for it.

It is a very good framework and could be great if someone took the time to fix the little issues and make some improvements.

Thanks. Yeah, I need to tidy quite a bit up, whenever I get the chance. I guess at the minute I'm stuck between trying to reach an acceptable milestone in my own game, and tweaking the GUI.

.rIKmAN.(Posted 2007) [#135]
Great stuff guys!

I haven`t actually looked at the source yet, cos as I say I need to migrate my thinking to BMax now, then I`ll have a look at the GUI stuff.

I`ll keep a list of anything I find so you can add it to your always growing "todo" list - I`m sure you`ll love me for it :)

Keep it up, best GUI I`ve seen for games (well going off what Si has done withit in his blog)

Fry Crayola(Posted 2007) [#136]
Keep it up, best GUI I`ve seen for games (well going off what Si has done withit in his blog)

Si's done some lovely stuff with it. Which is excellent, because our games are pretty similar.

.rIKmAN.(Posted 2007) [#137]
Ah you working on a football management style game too then?......and I make 3 :)

K@li(Posted 2007) [#138]
no very stable

i use yet higgui, mich more stable and faster and faster to code...

popcade(Posted 2007) [#139]

If you have time, mail me and I can provide a space around 200M, with no restriction/ad, you can have it as downloading space.

Fry Crayola(Posted 2007) [#140]
i use yet higgui, mich more stable and faster and faster to code...

HighGUI's good, but my issue with it (and indeed, every other GUI I'd used) was that they were all still based on a system of windows. It just didn't suit what I was after. I tried writing a wrapper for it that would encase it in a panel system but with the amount of work involved, I realised I'd be better writing my own.

Anyhow, the stability issues will get ironed out. I'm aware of quite a few problems here and there but if you can point more out, that'd be great. Don't want to miss anything!

siread(Posted 2007) [#141]
HighGui doesn't do tables either. Essential in a footy game, which is why we are congregating here. :D

Fry Crayola(Posted 2007) [#142]
Tables and XML. Well, the XML is Bruceys but I like using it to build screens. It's quicker.

Tachyon(Posted 2007) [#143]
Fry: I have not yet tried your GUI, but I have certainly followed it's development and I am looking forward to incorporating it with an upcoming project.

This may be a dumb question, but is FryGUI compatible with miniB3D? Could I create a 3D graphics screen/window inside your GUI?

[edit] Sorry! I just was looking through the posts above and saw that some people are using miniB3D with FryGUI. Thanks!

[edit again] Oops- Fry, the link to download FryGUI (in your sig) is dead.

Fry Crayola(Posted 2007) [#144]
Yeah, the link's dead because the temporary web storage I was using expired. Literally. The domain ran out. Fun!

I'll have that sorted shortly.

According to siread, FryGUI works with miniB3D. I haven't used it myself, so I couldn't comment fully on it.

Procedure(Posted 2007) [#145]
Heya Fry,

I was wondering if you had cleared up the hosting issue yet? Or if you could email me the FryGUI files? It looks like exactly what I need for my new project.

Many thanks.
-- Procedure --

siread(Posted 2007) [#146]
Fry, I can host the files if you like. :)

jamesmintram(Posted 2007) [#147]
I could host them as well if you would like? Could you email me the files as well? They would be incredibly handy by the sounds of them!


siread(Posted 2007) [#148]
Feature request: Can we have the option of changing the colour of individual rows in a table? Would be perfect for highlighting promotion/relegation zones. :D

Also, how about embedding images in the row? So you could put national flags or club logos for instance.

And, sorry, text alignment in table cells. I'll stop now. :)

Fry Crayola(Posted 2007) [#149]
Hi James, if you give me your email address I can send you the files.

Si, I'll also send you the zip for hosting.

Fry Crayola(Posted 2007) [#150]
Ok Si, I've emailed you at your NSS account with the files.

Fry Crayola(Posted 2007) [#151]
Ok, FryGUI is available for download again. It's still the same version as before, I've more to do before I have another release.

Thanks to siread for hosting. And thanks to the others who offered but, well, Si asked first. 8 months ago. Nothing like getting in early :)

MikeHart(Posted 2007) [#152]
Thank you!!

MikeHart(Posted 2007) [#153]
Did I understand this correctly? I have to use the extended version of MiniB3D to use 3D with FryGUI?

siread(Posted 2007) [#154]
I think the last version of ExtendedMiniB3D messed things up, but if you include the code in this thread:
you can simply place TGlobal.EndMax2D before renderworld and TGlobal.BeginMax2D after it. That means all your 2d stuff in between gets rendered on to of the 3D. :)

siread(Posted 2007) [#155]
Fry, is there any way to check which table column has been clicked? I see table.SelectedItem() but not table.SelectedColumn().

I'd like to be able to sort a table based on the heading that is clicked. Cheers.

Fry Crayola(Posted 2007) [#156]
There's a way of doing it with the events, using fry_EventX()

With tables, fry_EventY() and fry_EventSelected() will return the row, fry_EventX() the column, and fry_EventData() any data value contained in that item.

At the moment the selected column isn't stored, just the row, mainly for the purposes of highlighting the selected item. It'll be pretty easy to add row storage as well.

siread(Posted 2007) [#157]
Hi Fry. I've noticed a strange memory leak. If I put the cursor over a button (so the mouse over cursor appears) the Memory Usage (in Task Manager) continually rises. Take the cursor off the button and it stops.

It's strange because at first everything is fine, it's only after clicking on a few things, buttons tables, that it starts happening.

Or is it just me?

Fry Crayola(Posted 2007) [#158]
It's not just you, happens on my side too and under OS X no less.

Which at least means in theory it'll be easier to fix (maybe... hopefully)

Edit: Ok, I'm pretty sure it's to do with the ChildEvent system I introduced in the very latest version you have. When I comment out the line that generates one, the leak seems fixed.

Fry Crayola(Posted 2007) [#159]
Job done, I've emailed you the fix. The problem was that the system was generating internal events and sending them to a gadget's parent, as normal, but if that parent was a Panel, the queue would never be cleared as panels have a completely separate Update function owing to them not being interactive.

If anyone else is wondering, the problem won't apply to the currently available version, as it doesn't have the internal events system (it's a way of getting gadgets to communicate with their parent gadgets without hardcoding it, which didn't allow for much extensibility).

About time I released an update anyway so I'll get that out this week after a tidy up.

siread(Posted 2007) [#160]
Cheers mate. Gonna be updating the blog anytime soon?

I know, I'm a fine one to talk. :P

Fry Crayola(Posted 2007) [#161]
Some day...

siread(Posted 2007) [#162]
Hi fry. Can you give me some pointers on using a Slider bar?

I assumed that if I set the start and end values to something like 150,250 and the position to 200 then the slider would be in the middle of the bar. However, the bar appears but the slider doesn't.

It works fine if I do SetRange(1,100) and SetPosition(50), but I need other ranges. :)

Fry Crayola(Posted 2007) [#163]
That would be a bug.

In the fry_TSlider type there's a method UpdateBarPos().

Change that to

Method UpdateBarPos()

Select gAlign
Case VERT_ALIGN gStart = ((gSY + gSLen) - (gUnit * Float(gValue - gStartVal)) ) - (gLength / 2)
Case HORIZ_ALIGN gStart = (gSX + (gUnit * Float(gValue - gStartVal))) - (gLength / 2)
End Select

End Method')

The problem was there where it says Float(gValue - gStartVal). Before, it wasn't subtracting the starting value, hence it was drawing the slider outside the viewport for the gadget. All sorted now, it seems.

Now, my blog's updated....

siread(Posted 2007) [#164]
Hi Fry. I was wondering if you planned on adding some kind of multiple resolution support that adjusts panel and gadget sizes if the res changes, or would it be up to me to create seperate skins?

BTW, I think Setposition on sliders still isn't working. It always sets at 0.

Fry Crayola(Posted 2007) [#165]
I'm planning to implement a system that will set the GUI's internal resolution to a set value, and everything else changes along with it. It'll use the projection matrix code that's floating around in the archives somewhere.

Of course, separate skins could be created but I'd only go with it if you wanted to use the benefits of higher resolutions - storing more data on screen, for example, like in Football Manager. My main motivation for having multiple resolutions is to ensure that the games look as good as they can on native resolutions.

I'll have a look at those sliders tomorrow, should be a simple fix I reckon.

Fry Crayola(Posted 2007) [#166]
Si, what are you using SetPosition for, exactly?

SetPosition is an internal method of the gadget, used to calculate the value of the gadget based on the x or y location of the slider itself, using the right or bottom of the slighter as 0 and then working from there, pixel by pixel. It's so named because it locks the slider to the nearest allowed value, hence setting its position. Might be a tad confusing, I admit. It isn't documented though.

If what you're wanting to do is set the slider, with a range from 50 to 150, to a value of 103, then use gadget.SetValue(103).

siread(Posted 2007) [#167]
Ah, ok. I actually realised that I was doing a setIncrement after SetPosition anyways, so that was messing it up. Sorry buddy.

I'll Use SetValue from now on. :)

siread(Posted 2007) [#168]
Right, every seems to be fine with sliders except one thing. I create one with a range of -5 to 5, increment 1. When I drag the slider the mouse pointer isn't actually touching it.

Here I am actually dragging the slider.

It works fine if I use range 1 to 10.

Fry Crayola(Posted 2007) [#169]
You can tell I've barely used sliders, eh?

If you go to the SetPosition function in Slider.bmx and change SetValue(val) to SetValue(val + gStartVal) all is good.

siread(Posted 2007) [#170]

Another question. How do you change the FillColour of a progress bar at run time?

Fry Crayola(Posted 2007) [#171]
gadget.SetColour(r, g, b, 1)

The final parameter is 1 for fill colour, or 0 for the gadget itself.

siread(Posted 2007) [#172]
How's things going fry? Are we nearing an update? :D

I'm just wondering if you intend to implement a pop-up message box?

siread(Posted 2007) [#173]
Ooh, ooh! And what about button sounds?! We need sounds. :P

Fry Crayola(Posted 2007) [#174]
I've never done any work with sound in Blitz before (never got far enough along that I needed it) but I guess it shouldn't be too difficult to allow a sound to be attached to a gadget.

I've got one of those job things starting on the 15th, so I'll push to get a proper update out before that. Need to tidy up a lot of the documentation, basically, and whip together a better example.

siread(Posted 2007) [#175]
Cool. I guess a special type for a message box isn't needed really needed. You could just design a normal panel and assign it to every screen, then just hide it when it's not needed. The only thing it needs is a text box with word-wrapping. Does that exist already? What's the scrollbox?

Fry Crayola(Posted 2007) [#176]
Assigning a normal panel to every screen is a bit of overkill. A message box is pretty useful, almost every game would probably want one at some time so it's definitely worth adding.

(Actually, there is provision for this sort of thing in my latest code, which allows me to create a panel that isn't attached to any screen and can be displayed at will).

The scrollbox is basically just a scrolling viewport - you define the bit of the panel you want it to take up, and then how wide/high it is (and thus the scrolling), and everything inside it can be scrolled.

I have now got word wrapping text that can be justified on either axis (or both, if that's your bag). So that'll be in the next code. It's all pretty automatic too.

MGE(Posted 2007) [#177]
"just a scrolling viewport"

Are you implementing that in code or using a Bmax command? Viewports do not work on every gpu combination.

Fry Crayola(Posted 2007) [#178]
It's all BlitzMax commands at the moment. Viewports used all over the shop.

Implementing it in code is quite tough, I'd need to be able to only draw the portions of graphics you could actually see.

Still, I did mention earlier in the thread that it's something I'll be looking at.

Actually, thinking more, the only part where viewports are currently required are with scrolling tables and combo boxes, both of which can be made to scroll in defined increments if required. The scrollbox gadget, I'm not sure what I can do with, but it was created while I was experimenting with getting scrollable viewports. I've never actually used it myself for anything. It might not really be necessary.

Hotshot2005(Posted 2007) [#179]
It is very good FRYGUI Program :)

Mikael(Posted 2008) [#180]
Hey there! I was just wondering if you were planning to release newer versions of your excellent gui? :)

Rene Albrecht(Posted 2008) [#181]
Are there any examples / tutorials / docs out there for FryGUI?

plash(Posted 2008) [#182]
Did you download FryGUI? It has an example with it, in the first folder of the unzipped package.

siread(Posted 2008) [#183]
Here's a vid of it in action. :)

Rene Albrecht(Posted 2008) [#184]
The example is looking great. Are there any possibilities to create a sample, where the skin is included (e.g. via "incbin")? I'd like to release my game in one file, so that the player is not able to modify/destroy any content...

plash(Posted 2008) [#185]
You could do it like this: go through the skin folder (the only two you need to include for the example code to work is the Skin\Fonts\ and Skin\Graphics\ folders) and incbin the files in each of the folders, keeping the folder tree intact.

format_code('Incbin "Skin\Fonts\<filehere>"
Incbin "Skin\Graphics\<filehere>"')

After all that just change the loadskin line to this

Note: Don't forget to include the cursors folder inside the Graphics folder, that is if your going to use custom cursors and not the system cursor.

Fry Crayola(Posted 2008) [#186]
Mikael - aye, I'll be sorting out a newer release eventually, had a few personal things to deal with for the last while (nothing serious mind) so I've not had much chance to work.

FryGUI kinda evolves along with the progress on my own game, adding features as I need them, so when one goes limp for a while the other tends to suffer. Basically why it's free :D

Any problems though and I'll always see about getting them sorted.

Rene Albrecht(Posted 2008) [#187]
I get an error message "Unhandled Exception: Attempt to access field or method of Null object" if I format_code('fry_LoadSkin("incbin::Skin")') :(

plash(Posted 2008) [#188]
I was just assuming that was going to work, ill take a look at it later today and post a working version.

Rene Albrecht(Posted 2008) [#189]
Any ideas? Did you get it working?

plash(Posted 2008) [#190]
Here you go

format_code(''case sensitive
Incbin "Skin/graphics/button.png"
Incbin "Skin/graphics/checkbox.png"
Incbin "Skin/graphics/combobox arrow.png"
Incbin "Skin/graphics/combobox.png"
Incbin "Skin/graphics/hscrollbar.png"
Incbin "Skin/graphics/menu.png"
Incbin "Skin/graphics/panel.png"
Incbin "Skin/graphics/progress.png"
Incbin "Skin/graphics/scrollback.png"
Incbin "Skin/graphics/scrolldown.png"
Incbin "Skin/graphics/scrollleft.png"
Incbin "Skin/graphics/scrollright.png"
Incbin "Skin/graphics/scrollup.png"
Incbin "Skin/graphics/search.png"
Incbin "Skin/graphics/textfield.png"
Incbin "Skin/graphics/vscrollbar.png"
Incbin "Skin/graphics/cursors/mousedown.png"
Incbin "Skin/graphics/cursors/mouseover.png"
Incbin "Skin/graphics/cursors/normal.png"
Incbin "Skin/Fonts/fonts.xml"
Incbin "Skin/Fonts/trebucbd.ttf"

'load in a skin for the GUI

Rene Albrecht(Posted 2008) [#191]
Why does it have to be case sensitive? If I change Incbin "Skin/graphics..." to "Skin/Graphics..." I get the error while trying to execute the debug.exe! But my Path is "Skin/Graphics"

*(Posted 2008) [#192]
it depends on what OS your running on some are case sensitive (the ones based on UNIX) so 'graphics', 'Graphics' and 'gRaPhIcS' are all different files.

plash(Posted 2008) [#193]
As far as I can tell its because the refreshskin() function in frygui uses lowercase when it loads in the images, so you have to define it lowercase.

Rene Albrecht(Posted 2008) [#194]
@EdzUp: I got the problems under Windows...

@Plash: Thank you for this important information!

PeterOnhere(Posted 2008) [#195]
Hi, many thanks for making this excellent module available.

The close window icon appears in the top right hand of the window. However it doesn't seem to generate an event when pressed (I'm going on your example). Is this true? Can the button be hidden? Thanks.

Scaremonger(Posted 2009) [#196]
I know this is an old post, but I'm updating a program that uses FryGUI by giving it a minimise button from MAXGUI, so for those who wish to do something similar, here are some tips:

Your Game loop should look something like this:
Global application:TApplet = New TApplet.Create()
While fry_PollEvent()
If fry_EventID() <> fry_EVENT_MOUSEOVER Then Print fry_EventText()
'if the screen has changed, change the title
If fry_EventID() = fry_EVENT_SETSCREEN Then application.onSetScreen()
'Change the background colour according to the combo box's selected item
If fry_EventID() = fry_EVENT_GADGETSELECT Then application.onGadgetSelect()
After you create your Canvas in MaxGUI, and before you create your frygui objects you need to set an event hook, set a timer for your refresh loop and set the canvas to receive the Max2D graphics (Used by FryGUI).
window = CreateWindow(name , 30 , 20 , 600 , 440 , , WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CLIENTCOORDS )
Local w% = ClientWidth(window)
Local h% = ClientHeight(window)
canvas = CreateCanvas(0,0,w,h,window)
canvas.SetLayout( 1 , 1 , 1 , 1 )
AddHook EmitEventHook, _eventHook
CreateTimer 120
SetGraphics CanvasGraphics(canvas)
Now add your event handler
Function _EventHook:Object(ID:Int , Data:Object , Context:Object)
Local event:TEvent
event = TEvent(data)
If event=Null Then Return Null 'Dont interpret if null
SetGraphics CanvasGraphics(canvas)
Local w#=GraphicsWidth(),h#=GraphicsHeight()
SetViewport 0,0,w,h
Return Null
SetGraphics CanvasGraphics(canvas)
Flip 0
Return null
If <> EVENT_MOUSEMOVE Then Print event.tostring()
End Select
'# Unhook all un-processed events.
Return data
End Function
FryGui uses Polled input, but if you switch it on FryGUI crashes (I don't know why). So instead I remodelled it slightly. Edit events.bmx (in frygui.mod folder) and add the following to the top. Then recompile.

Global fry_MouseX:Int = 0
Global fry_MouseY:Int = 0
Global fry_MouseButton:Int[] = [False , False , False] ;
Global fry_KeyCache:Int[0] ;
Global fry_KeyHits:Int[255];

AddHook EmitEventHook , fry_eventhook

' Event handler
Function fry_eventhook:Object( id:Int, data:Object, context:Object )
Local event:TEvent = TEvent( data )
If event=Null Then Return Null 'Ignore null
fry_MouseX = event.x
fry_MouseY = event.y
fry_MouseButton[] = False
fry_MouseButton[] = True
fry_KeyHits[ ] = fry_KeyHits[ ] +1
End select
Local count:Int = Len(fry_Keycache) + 1
fry_KeyCache = fry_KeyCache[..count]
fry_KeyCache[count-1] =
End Select
'# Unhook all events.
Return data
End Function

' Over-ride Blitzmax functions
Function MouseX:Int() ; Return fry_MouseX ; End Function
Function MouseY:Int() ; Return fry_MouseY ; End Function
Function MouseDown:Int( button:Int ) ; Return fry_MouseButton[ button ] ; End Function
Function GetChar:Int()
If Len(fry_Keycache) = 0 Then Return 0
Local key:Int = fry_KeyCache[0]
fry_KeyCache = fry_KeyCache[1..]
Return key
End Function
Function FlushKeys() ; fry_KeyCache = Null ; End Function
Function KeyHit:Int( key:Int )
Local count:Int = fry_KeyHits[ key ]
fry_KeyHits[ key ] = 0
Return count
End function


And you should have FryGUI working inside a MaxGUI window (Which can be resized, minimised, maximised etc...

Rene Albrecht(Posted 2009) [#197]
The download link is dead. :(

Fry Crayola(Posted 2009) [#198]
Here it is.

Be sure to rebuild modules when you grab it. Any problems, just ask!

_Skully(Posted 2009) [#199]


Can you invite me to google wave? I've been wanting to try that but no-one I know has it (hide_email(''))

Spacechimp(Posted 2009) [#200]
Are the samples still included? If not, can you put them somewhere?

Pax(Posted 2010) [#201]
hello, just bumping up, as I would also be interested in getting the samples. Regards.

nrasool(Posted 2010) [#202]
Hi there

Does anyone have the samples so we can learn from this, or could the owner put this on googlecode instead

Many thanks

Perturbatio(Posted 2010) [#203]
you could download it from the link a few posts up...

nrasool(Posted 2010) [#204]
Hey Perturbatio,

I did :-), that has the mod only, the samples are not included in that zip file

Kind Regards

Fry Crayola(Posted 2010) [#205]
Hey guys, examples here.

Sorry they're not terribly great, but there should be enough there to work with.

Also, they're just source code at the moment, so you'll need the module.

Any troubles, just shout. :)

nrasool(Posted 2010) [#206]
Hi Fry,

Nice one, many thanks for uploading this for us :-)

nrasool(Posted 2010) [#207]
Hi Fry,

Just to double check, i put in frydraw.mod, frygui.mod and frymisc.mod in C:\BlitzMax\mod

I can't run the examples, I tried rebuilding the modules, but when I use gui.bmx, it just has a problem with Import Fry.FryGUI

It says can't find interface for module 'fry.frygui'

I'm using blitz max 1.39

Fry Crayola(Posted 2010) [#208]
Hi nrasool,

Have you tried rebuilding all modules, as opposed to just modules that have changed? I've had difficulties in the past with modules that BlitzMax thinks are built, but haven't been properly linked in so it can't find the interfacces.

Also, I think you're going to need FryDate.mod which is missing from the package for some reason. I ought to be better organised!

Everything is re-uploaded here.

Sorry for the confusion!

nrasool(Posted 2010) [#209]
Hi Fry,

This is wierd, I have t to rebuild all modules, twice in MaxIDE and twice in Blide, but I still get the same issue.

Is it working for you?

Jesse(Posted 2010) [#210]
you need to create a folder name "Fry.mod" and put all of fry mods in there.

nrasool(Posted 2010) [#211]
Hey Jesse

Nice one, many thanks, now the examples work :-)

Czar Flavius(Posted 2010) [#212]
Where can I download it?

Czar Flavius(Posted 2010) [#213]

Czar Flavius(Posted 2010) [#214]
Compile Error: Can't find interface for module 'fry.frydraw'
Build Error: failed to compile C:/BlitzMax/mod/fry.mod/Examples/GUI Example.bmx


Czar Flavius(Posted 2010) [#215]

Both contain missing files. Combine the two downloads together and you get a complete FryGUI.

How ridiculous!

GNS(Posted 2010) [#216]
Hmm. Anyone have a complete backup of FryGUI? The link no longer works.

GaryV(Posted 2010) [#217]
GNS: Read post #213 & #215

GNS(Posted 2010) [#218]
I did. "The link no longer works." was referring to the link in post #213.

nrasool(Posted 2010) [#219]

It has everything you need for FryGUI as Czar mentioned

xlsior(Posted 2010) [#220]
Not everything, that archive is still missing frydate.mod

When trying to rebuild, it tells me the following:
Compile Error: Can't find interface for module 'fry.frydate'

does anyone have a copy of those missing files as well?

nrasool(Posted 2010) [#221]
Ahh I see.

I have everything at home, if you give me until tonight, I will upload it on my webpage and provide a link here and just keep it up there without having to naff around with mediafile, etc :-)

I will upload it tonight if no one else does

Kind Regards

xlsior(Posted 2010) [#222]

GaryV(Posted 2010) [#223]
I did. "The link no longer works." was referring to the link in post #213.
FWIW, the url works and downloads just fine for me, as I tried it before my previous post.

GNS(Posted 2010) [#224]
FWIW, the url works and downloads just fine for me, as I tried it before my previous post.

Hmm. Strange. I either get a popup saying something about no servers with the file being available or it just times out.

GaryV(Posted 2010) [#225]
I just tried again and it worked for me. :/

nrasool(Posted 2010) [#226]
Uploaded to:

Extract and put it in your mod folder

I have put a mirror for this on

Any issue please let me know.

Hope that is cool by the way Fry, it too good a plugin to disappear ;-)

GNS(Posted 2010) [#227]
Excellent. Much appreciated!

xlsior(Posted 2010) [#228]
FWIW, the url works and downloads just fine for me, as I tried it before my previous post.

I wonder if it's one of those akamai-style regionalized services, since it's still failing for me, telling me that the file doesn't exist.

Anyway, nrasool's upload does work -- thanks again!

Czar Flavius(Posted 2010) [#229]
I posted two links, both of which need to be downloaded to get all the files you need. It looks like nrasool has combined them together in one easy download - good job.

For those coming to this thread and scrolling straight to the bottom, this is the download link from nrasool:

For reference, here are my two original links (not checked if they still work):

If required, I can upload my own copy of FryGui somewhere for people to use.

Last edited show_time('2010-10-10 08:06:57')

nrasool(Posted 2010) [#230]
Thanks, I didn't want this to go, so added it to my personal site :-)