JungleGui open source gui library for Monkey

Monkey Programming Forums/User Modules/JungleGui open source gui library for Monkey

ziggy(Posted 2012) [#1]
Hello, I supose some of you have already read about this project, but I'm writting a new Gui system for Monkey with the wonderful help of Sasch Schmidt. It's an open source project, in very early status, and development is open.

Here's the project page at googlecode:
http://code.google.com/p/junglegui/

Just in case anyone is interested.


ziggy(Posted 2012) [#2]
Just made a small sample that shows how to create a small toolbar to control a tipical startfield particles implementation. Will improve the sample soon, but you can see it here:

http://www.jungleide.com/samples/junglegui02/

This is the toolbox source code:
[monkeycode]
Import particlessample
Class ToolBox extends form.Form
Field particlesCount:Label
Field explosionButton:Button

Field desiredStars:TrackBar

Field colorR:Slider
Field colorG:Slider
Field colorB:Slider

Method OnInit()
Local height:Int = 0
'SELF:
Self.Text = "Toolbox"
Self.Size.X = 200
Self.Size.Y = 400
Self.Position.X = DeviceWidth - Self.Size.X - 20
Self.TipText = "This is jsut a sample toolbar"
Self.Event_ParentResized.Add(Self, "Canvas_Resized")

'''
''' starCount
'''
particlesCount = New Label
particlesCount.Parent = self
particlesCount.Text = "Particles: ??"
particlesCount.Position.X = 10
particlesCount.Position.Y = 10
particlesCount.TipText = "This label shows the amount of used particles."
height = GetNextHeight(particlesCount)
'''
'''explosionButton
'''
explosionButton = New Button
explosionButton.Parent = self
explosionButton.Text = "Explosion!"
explosionButton.Position.SetValues(10, height)
explosionButton.Event_Click.Add(Self, "Explossion_Clicked")
explosionButton.TipText = "Click here to generate an explosion"
height = GetNextHeight(explosionButton)

'''
'''desiredStars
'''
Local tmpLabel:Label = New Label
tmpLabel.Parent = self
tmpLabel.Position.SetValues(10, height)
tmpLabel.Text = "count:"
desiredStars = New TrackBar
desiredStars.Parent = self
desiredStars.Position.SetValues(tmpLabel.Position.X + tmpLabel.Size.X, height)
desiredStars.Maximum = 500
desiredStars.Minimum = 1
height = GetNextHeight(desiredStars)
desiredStars.Event_ValueChanged.Add(Self, "Desired_Changed")
desiredStars.Value = 100
desiredStars.Tickfrequency = 50
desiredStars.Size.X = self.Size.X - desiredStars.Position.X - 10
desiredStars.TipText = "This is the amount of desired particles."
height = GetNextHeight(desiredStars)


'''
''' red
'''
colorR = New Slider
SetSliderValues(colorR, 0, "red", height)

'''
''' green
'''
colorG = New Slider
SetSliderValues(colorG, 1, "green", height)

'''
''' blue
'''
colorB = New Slider
SetSliderValues(colorB, 2, "blue", height)

height = GetNextHeight(colorB)


'''
''' Form size:
'''
Self.Size.Y = height + Padding.Top + Padding.Bottom
End


Method GetNextHeight(control:Control)
Const Margin:Int = 5
Return control.Position.Y + control.Size.Y + Margin
End


Method SetSliderValues(slider:Slider, Index:Int, name:String, height:Int)
slider.Position.SetValues(70, height + Index * 20)
slider.Parent = Self
slider.Name = name
slider.Maximum = 100
slider.Size.SetValues(Self.Size.X - 70 - 10 - Self.Padding.Left - Self.Padding.Right, 10)
slider.Maximum = 255
slider.Value = 255
slider.Event_ValueChanged.Add(Self, "Slider_Value_Changed")
Local label:= New Label
label.Parent = self
label.Text = name
label.Position.SetValues(10, height + Index * 20)

'We align the label:

label.Position.Y = slider.Position.Y - (label.Size.Y - slider.Size.Y) / 2

'label.Size.Y = 10

End

Method Explossion_Clicked(sender:Object, e:MouseEventArgs)
For Local i:Int = 0 to 200
Local particle:= New Particle(Sample.emiter)
Sample.emiter.stars.AddLast(particle)
next
End

Method Slider_Value_Changed(sender:Object, e:EventArgs)
local slider:= Slider(sender)
if slider = null Then Return
Select slider
Case colorR
Sample.emiter.particleColor.r = colorR.Value
colorR.TipText = "Red has a value of " + colorR.Value
Case colorG
Sample.emiter.particleColor.g = colorG.Value
colorG.TipText = "Green has a value of " + colorG.Value
Case colorB
Sample.emiter.particleColor.b = colorB.Value
colorB.TipText = "Blue has a value of " + colorB.Value
End

End

Method Desired_Changed(sender:Object, e:EventArgs)
if Sample <> null then Sample.emiter.desiredParticles = desiredStars.Value
End

Method Canvas_Resized(sender:Object, e:EventArgs)
if Self.Position.X > DeviceWidth - Self.Size.X - 10 Then Self.Position.X = DeviceWidth - Self.Size.X - 10
if Self.Position.Y > DeviceHeight - Self.Size.Y - 10 Then Self.Position.Y = DeviceHeight - Self.Size.Y - 10
End
End[/monkeycode]

Just a sample, sill working hard on it


CopperCircle(Posted 2012) [#3]
It's looking great, i'm thinking of creating my physics level editor in HTML5 and this looks the part for the GUI.


ziggy(Posted 2012) [#4]
Just to let you know that we have finished a ListBox component with automatic scrolling capabilities and we're now working on auto-scroll panel. It seems to be very fast even when it's running on HTML5 and we're not heavily optimizing anything yet.


ziggy(Posted 2012) [#5]
Some screenies of an App done by Sascha using Jungle Gui and his Property grid control:






Progress is slow but it's worth it


Shinkiro1(Posted 2012) [#6]
That looks really nice.
This app from that Sascha guy, do you have a link to that?
I am curious, because I have a Particle Editor nearly identical to it (well, I am more talking about the properties)


byo(Posted 2012) [#7]
Brilliant work, guys!


ziggy(Posted 2012) [#8]
I'm not working on separating the rendering area of each control to an abstract overridable renderer, so the whole GUI system will allow a very big level of customization. But I'm fighting a bottleneck on HTML5 I can't find... Anyone has any clues on how to easily profile a HTML5 build of Monkey?


Samah(Posted 2012) [#9]
Sorry for the lack of activity on this project. I was kinda waiting for an official scrollable container widget before I started work on anything. I'll work off a Google Code clone and I'll let you know when I have something concrete I can give you.

Also, you might want to enable the strip command, it's totally awesome for testing out other people's changes without having to reclone afterward. Just add this to your .hg/hgrc to enable Mercurial Queues:
format_code('[extensions]
mq =')


ziggy(Posted 2012) [#10]
@Samah: I have a brief design of the auto-scrollable control container, but I have been doing some progress on other areas. I hope it wont take too much to get something done soon.
I've never used Mercurial Queues, I'll investigate it when I have some spare time, It looks "sexy" to be able to get any revision of another clone if that's what it is suposed to do.


Samah(Posted 2012) [#11]
You can already retrieve individual revisions (including their parents) without any extensions. What I mean by strip is to delete (locally) individual changesets and their children. This means you can pull someone's changes for review, and if you decide to fail it, you can just strip it from your clone. You don't have to reclone to get rid of it. It also means you can blow away any local unpushed commits (and their children).


PaulHMason(Posted 2012) [#12]
Very nice :)

Are there any plans to make the controls skinnable or stylable (like Flex or Silverlight)?


ziggy(Posted 2012) [#13]
@PaulHMason: yes, we're working on a renderer class wich you can extend to modify as you wish in order to customize all the gui rendering


Why0Why(Posted 2012) [#14]
Ziggy,

I know this isn't exactly related but would it be possible to use the back button on the mouse to go back when reading docs in Jungle instead of having to click the back button?


Armitage1982(Posted 2012) [#15]
This is going to be very interesting Ziggy !

Do you render each control individually on screen or simply a quad for the whole parent?
I don't know if using a FBO or any render to texture routine is easy or possible with Monkey but I know it's the only way to go for rendering a GUI in HTML at high speed.

Do you plan to add text selection and a lot of component to your GUI?
Any chance to see this nicely included in the Diddy Framework?

Good work on your project :)
I'm following this with great attention.


ziggy(Posted 2012) [#16]
@Armitage1982: The rendering system is currently driver based (well not yet, but we're at it). And the Gui system does have a viewport stack class that handles all the SetScisor commands before allowing any control render its contents, so controls do not draw outside their logical limits on current renderer. That said, it perfectly possible to make the renderer override this behaviour. Haven't done anything related to optimization (preemptive optimization, you know...)

Any chance to see this nicely included in the Diddy Framework?
Why? You can use both at the same time. I think this is starting to be projected as a very complex Gui system so it may be as stand alone as possible.


Armitage1982(Posted 2012) [#17]
Why?

To avoid duplication work. Because I saw that Diddy already have some Gui element and was planning to add more (from the TODO list).

I'm really waiting for a solid GUI system before considering Monkey. So at least I could still using it for small software design.


Rushino(Posted 2012) [#18]
That really nice ziggy, i was looking at something similar for my game.


Samah(Posted 2012) [#19]
http://code.google.com/p/junglegui/source/browse/textfield.monkey (line 5)

You need to escape the ~ character. I'd paste the code here, but the forum seems to want to convert it to an email address. If i put it in monkeycode tags, it doubles up the text. (eh??)

Also, I want a tree control. :(


Samah(Posted 2012) [#20]
Ziggy, is there a way of disabling the Form border and header entirely? I essentially just want a static container as a top level control with no title bar or border.


ziggy(Posted 2012) [#21]
mmmm don't use a form, use a TopLevelControl instead.
A TopLevelControl is a control container from wich a form derives. I think it should do the trick. Not sure if you'll be able to move it, if you don't want it to be moveable you can easily avoid this.

You can also set all the Padding information of a form to 0 (0 top, left right and bottom) so it won't have space to render the borders and tey won't be shown, but it would be then like using directly a TopLevelControl but with a small additional "work"


ziggy(Posted 2012) [#22]
@Samah: I've jsut commited a version with a new control called WindowFrame that is a TopLevelControl (like a form) but does not have any borders, auto-move drag&drop or anything else. It's just like a panel you can render with controls in it. It also has a Transparent property if you want to place controls in top of a game background, all you have to do is create a transparent TopLevelControl and place the controls in there.

EDIT:
also, Sascha has added a new ListView component, wich looks very nice:



Rushino(Posted 2012) [#23]
Offcourse it look very nice.. omg... that exactly what missed! Nice job!

This GUI library is really starting to be solid! (if not already..) This library mustn't die! Lets me guess... there no editor already available ? I might consider making one if its the case cause i will need to design my windows for my game pretty soon and i dont want to hand-code them lol


Rone(Posted 2012) [#24]
I guess, ziggy is creating an forms editor for JungleIDE^^ ...like the one in Visual Studio ;)


byo(Posted 2012) [#25]
Looking very very nice, guys!


Rushino(Posted 2012) [#26]
Ziggy, It is normal that this sample is rather slow ? (The one with listview)


ziggy(Posted 2012) [#27]
@Rushino: there's a bottleneck on HTML5 we haven't found yet. Any other target works great. It's something related to rendering. We're at it.


Rushino(Posted 2012) [#28]
Umm. Its really sad that it isnt working right yet on HTML5 (Slowness). I am now ready to start the game client. I would pay (I am serious) to see this 'bottleneck' your talking being fixed since my game is mostly HTML5 only until i find a way to integrate websocket++ with monkey which i will look into soon. Look faster on chrome through.. but it use 25% of CPU.


Rushino(Posted 2012) [#29]
I made so we can support password '*' in the textfield. Since i am doing a login screen.




Rushino(Posted 2012) [#30]
Strange the link overthere http://www.jungleide.com/samples/junglegui02/ and http://www.jungleide.com/samples/junglegui01/ seem be to rather fast if you compare to localhost stuff..


Rone(Posted 2012) [#31]
Seems that html5 performance issue is caused by fontmashine
...it's easy to fix!

@Ziggy
Please have a look at:
https://groups.google.com/forum/#!topic/jungle-gui/7ipVGnBX7hU


Rushino(Posted 2012) [#32]
Is there a reason the samples on the jungleide website are faster ? Cause you didn't fixed yet the bottleneck.. when i run them local its really slow!


ziggy(Posted 2012) [#33]
I'm prety sure it's related to somo pre-rendering coloring on HTML5 text in some component. Hope to have to time to provide a fix soon


Rushino(Posted 2012) [#34]
Great to hear! Cause right now im digging in C++ stuff to try to support a windows client in case. :( and its not an easy task cause i never touched C++ doesn'T seem too hard but the hard part is the lib linking stuff.. I found a library to make a websocketclient so maybe i will be able to provide websocket support for windows platform.


Rushino(Posted 2012) [#35]
In its current state it is possible to change the color from blue to gray as an example ? Still don't get it why the sample on your website are fast and if i start from monkey they are slow is there an explanation to this ?


ziggy(Posted 2012) [#36]
@Rushino: It seems there's a bottleneck related to HTML5 "coloring" text on any part of the renderer. We haven't find where yet (I ahven't had much time latelly but will take a look tonight).
That said, you can modify the SystemColors global values to design your own color schema. And you can also extend the renderer class to make your own GUI renderer, so everything can be customized. The current renderer, however, does not render all of the GUI elements, only some of them. We'll be fixing this soon.


ziggy(Posted 2012) [#37]
HTML5 speed fix has been commit. Get it to see JungleGui go very very fast again on HTML5


Rushino(Posted 2012) [#38]
Nice one ! Thanks a lots ziggy !


ziggy(Posted 2012) [#39]
Also, I've just commit a small fix that can solve some issues when adding/removing control containers with contained controls to other control containers at runtime. Updating is recommended.


ziggy(Posted 2012) [#40]
This is just a small sample of a new skin for JungleGui. We're working on a renderer-driven system for JungleGui skining of applications, and this is ultra powerful.

This alternative skin is far from being complete, it's just being used as a WIP while we develop the whole Renderer structure.
Differences with regular skin:
1.- Different color schema
2.- Forms have a transparent border with a gradient on top
3.- Forms contents area have a volume-like brigter gradient on the upper area and a darker gradient on its bottom area, so it looks like it has some sort of "volume"
4.- Rendering of buttons and elements is mostly square instead of rounded edges
5.- Checkboxes "selected" mark is round and animated.
6.- It implements its own antialiased typography.

This is the alternate skin (WIP) in a runable sample:
http://www.jungleide.com/samples/junglegui03

the fact that you can define additional gradients, animations or any other thing on a renderer (skin) si due the internal design of this JungleGui area.

You can get an idea of what can be done. This is the source code of this alternative skin, so you can see how easy it can be to create your own look on a JungleGui application:

[monkeycode]
Class ConcreteJungle Extends renderer.GuiRenderer

Method InitRenderer()
'We modify some systemcolors when the Renderer is activated:
SystemColors.FormMargin.SetColor(255, 200, 200, 190)
SystemColors.WindowColor.SetColor(255, 220, 220, 200)
SystemColors.ButtonBorderColor.SetColor(255, 255, 255, 235)
SystemColors.ControlFace.SetColor(255, 180, 170, 160)
SystemColors.HooverBackgroundColor.SetColor(255, 235, 235, 190)
SystemColors.FocusColor.SetColor(255, 255, 255, 255)
SystemColors.FormBorder.SetColor(255, 250, 250, 230)
SystemColors.SelectedItemBackColor.SetColor(255, 200, 200, 180)
#IF TARGET="html5"
Gui.systemFont = New bitmapfont.BitmapFont("concretejunglefont_html5.txt")
#ELSE
Gui.systemFont = New bitmapfont.BitmapFont("concretejunglefont.txt")
#END
End

Method DrawFormBackground(status:Int, position:GuiVector2D, size:GuiVector2D, padding:Padding, text:String, context:Control)
'We modify the way a form is renderer.

'We render the form "main" box:
SystemColors.FormMargin.Activate() 'Select the form margin color
SetAlpha(0.4) 'Oue new skin has transparent form borders, so we set alpha to 0.2
DrawRect(position.X, position.Y, size.X, size.Y) 'We draw the form rectangle
SetAlpha(1) 'We set alpha back to 1


'We render for form caption (header):

'First a small gradient:
For Local i:Int = 0 To Gui.systemFont.GetFontHeight
SetAlpha(1 - float(i) / float(Gui.systemFont.GetFontHeight))
DrawLine(position.X, position.Y + i, position.X + size.X, position.Y + i)
Next
'Then the text:
SetAlpha 1
Gui.systemFont.DrawText(text, position.X + 1, position.Y + 1)



'Now we're rendering the form "container" area, where controls are placed:
Local backcolor:guicolor.GuiColor
If context = Null Then 'If we're just calling this to be used with systemcolors:
backcolor = SystemColors.WindowColor
Else 'If we're caling this to be used with a given real form, we use its background color instead:
backcolor = context.BackgroundColor
EndIf
backcolor.Activate
DrawRect(position.X + padding.Left, position.Y + padding.Top, size.X - padding.Left - padding.Right, size.Y - padding.Top - padding.Bottom)

'Now we're adding a small gradient at the top and at the bottom of the form container area:
For Local i:Int = 0 To 20
SetAlpha(1 - i / 20.0)
backcolor.ActivateDark(55)

DrawLine(position.X + padding.Left,
position.Y +size.Y - padding.Bottom - i,
position.X +size.X - padding.Right,
position.Y +size.Y - padding.Bottom - i)

backcolor.ActivateBright(55)
'SetColor(255, 0, 0)
DrawLine(position.X + padding.Left,
position.Y +padding.Top + i,
position.X +size.X - padding.Right,
position.Y +padding.Top + i)

Next
SetAlpha(0.5)
SystemColors.FormBorder.Activate()
DrawBox(position, size)
SetAlpha(1)
End

Method DrawButtonBackground(status:Int, position:GuiVector2D, size:GuiVector2D, context:Control)
Local backColor:GuiColor
If HasFlag(status, eControlStatus.HOOVER) Then
If context Then
backColor = context.HooverColor
Else
backColor = SystemColors.HooverBackgroundColor
EndIf
Else
If context Then
backColor = context.BackgroundColor
Else
backColor = SystemColors.ControlFace
EndIf
EndIf
backColor.Activate()
DrawRect(position.X + 1, position.Y + 1, size.X - 2, size.Y - 2)
End


Method DrawControlBorder(status:Int, position:GuiVector2D, size:GuiVector2D, context:Control)
If context Then context.BorderColor.Activate() Else SystemColors.ButtonBorderColor.Activate()
'We draw a square control border on this skin:
DrawBox(position, size)
End

Method DrawFocusRect(control:Control, round:Bool = False)
SystemColors.FocusColor.Activate()
Local pos:= control.CalculateRenderPosition()
Local size:= control.Size
DrawBox(pos, size)
End

Method DrawCheckBox(status:Int, position:GuiVector2D, size:GuiVector2D, context:Control = Null, BoxSize:Int = 16, checked:Bool = True)
SystemColors.ControlFace.Activate()
Local yOffset:Int = size.Y / 2 - BoxSize / 2
DrawRect(position.X + 1, position.Y + 1 + yOffset, BoxSize - 2, BoxSize - 2)
If HasFlag(status, eControlStatus.HOOVER) Then
SystemColors.FocusColor.Activate()
Else
SystemColors.ButtonBorderColor.Activate()
EndIf

DrawRoundBox(int(position.X), int(position.Y + yOffset), BoxSize, BoxSize)
If checked Then
SystemColors.FocusColor.Activate()
SetAlpha(Abs(Sin(Millisecs() / 10.0)))
'DrawRect(position.X + 4, position.Y + 4 + yOffset, BoxSize - 9, BoxSize - 8)
DrawOval(position.X + 4, position.Y + 4 + yOffset, BoxSize - 8, BoxSize - 7)
SetAlpha 1
EndIf

End

End

[/monkeycode]
All in all, all you have to do is override the methods you want from the base renderer, o you just modify the look and feel of your application to make it look as you wish.
You can make a renderer that extends another renderer easily, so making additional looks and feels for JungleGui will be fast and ultra powerful.



Using a new skin is as easy as importing the required skin and setting it to your Gui manager:
[monkeycode]gui.Renderer = New MySuperDupperRenderer[/monkeycode]


Why0Why(Posted 2012) [#41]
Nice!


Rushino(Posted 2012) [#42]
Yeah that nice!


ziggy(Posted 2012) [#43]
Just commit a new sample with another additional renderer. This one features rounded windows borders and a gree color scheme.

See it in action here: http://www.jungleide.com/samples/junglegui03


cageInfamous(Posted 2012) [#44]
Love it!


Skn3(Posted 2012) [#45]
Just posting to say I revisited this thread a few days ago and was impressed with the progress it has made. Good stuff :D


ziggy(Posted 2012) [#46]
Thanks! Just playing with it on my free time, and the additions made by Sascha are great!
I hope to have a sort of alpha first release on genuary or the like

We hope to have finished this for a first alpha release:
- An auto scroll control container
- A layered rendering system (so we have an approprita way to draw pop ups on combo boxes and the like
- Text selection on TextField control

I would love also to have:
-A XML + PNG based renderer, so people can make old-school skins (I still think properly coded renderers are better but you know...)
-Tutorials!
-More tutorials
-Samples
-More samples
-Even more samples

Remember this is an open source project and development is open!


Skn3(Posted 2012) [#47]
Some nice bits there! If I had lots of spare time It would be right up my street to do some contributes, alas for the moment I cant!

Have you thought about potentially utilising the new pixel commands to buffer inactive gadgets/windows to reduce render operations?


Kauffy(Posted 2012) [#48]
I hope their are plans for a tree control somewhere in this-- I have a future project that will rely pretty heavily on having a useful tree and, at this point, I think it would take me ages to write one. :)


Kauffy(Posted 2012) [#49]
Oh, and this looks amazing so far! (Sorry, in a rush and full of coffee!!)


ziggy(Posted 2012) [#50]
I was planing to convert the jungle ide treecontrol to jungle gui but I need to solve horizontal scrolling first.


Corum(Posted 2012) [#51]
[dreaming]
What about a multiplatform JungleIDE port, built around this GUI? :-)
[/dreaming]


frank(Posted 2012) [#52]
[dreaming]
What about a multiplatform JungleIDE port, built around this GUI? :-)
[/dreaming]


Another vote for that here :) Mac please.


frank(Posted 2012) [#53]
Any example of the auto scroll container/panel? :) Would you instantiate a panel, put controls on it with Parent=panel and then it works or is it more subtle than that?

I'm also writing a real portable filesystem component at the moment (I couldn't find one which does what I want on html5/ios/android) and want to make a FileOpen / FileSave dialog for that; that's no problem with junglegui I just cannot get the [x] (close) to work ; i'm missing something probably ?

And will there be minimize? Even just the mac one (making having the panel disappear but not the topbar/handle)?


julesd(Posted 2012) [#54]
is it possible to put this to github.Seem easier github


ziggy(Posted 2012) [#55]
We're not moving this from Mercurial, but we'll provide a download as soon as we get a sort of first release ready. Hopefully soon...


frank(Posted 2013) [#56]
Any reason why CheckBox Checked = True doesn't work with ConcreteJungle theme but does with RoundForms?

Code;

gridOn = New junglegui.CheckBox
gridOn.Parent = Self
gridOn.Position.X = label.Size.X + 15
gridOn.Position.Y = height
gridOn.Text = "On"
gridOn.TipText = "Grid on/off"
gridOn.Size.Y = 18
gridOn.Name = "GridOn"
gridOn.Checked(True)
gridOn.Event_Click.Add(Self, "Grid_Clicked")
gridOn.Position.X = Self.Size.X - gridOn.Size.X - 15


ziggy(Posted 2013) [#57]
@frank: I've been checking it and it works for both of them here. If you provide a complete sample (feel free to email me if you wish) I can take a proper look to see if there's anything wrong in the ConcreteJungle renderer.


wiebow(Posted 2013) [#58]
@ziggy: google code now shows a zip download link on the source tab page. Just perfect for ppl without a hg client. :) Just my tip for the day.


ziggy(Posted 2013) [#59]
Where!!? That's great but I can't find it.

EDIT: I've just seen it, it's ont the source/browse page. Here: http://code.google.com/p/junglegui/source/browse/


wiebow(Posted 2013) [#60]
yup. nice innit? It's also on the source/changes page.


frank(Posted 2013) [#61]
@ziggy; i'll make something complete to reproduce.


Goodlookinguy(Posted 2013) [#62]
@ziggy I made a canvas gadget built off of the panel gadget. It's a tad buggy when trying to obtain focus, and even though I'm trying to fix it, I'm wondering if there's going to be an official canvas type gadget.


ziggy(Posted 2013) [#63]
Feel free to share your Canvas source code, there are no plans of creating a canvas control.
May I ask why are you basing it on the Panel control? Is your canvas a control container? If it's not, it may be better to extend the Control class directly, as it will be a bit lighter


Goodlookinguy(Posted 2013) [#64]
I was basing it off the Panel control because I'm unfamiliar with Jungle GUI and I happened to be using the color changing test as my base for creating the canvas. I'll try changing it later. I'm a tad busy with other work at the moment.

This is what came out when using the panel: http://nrgs.org/files/flash/jguicanvas/


ziggy(Posted 2013) [#65]
IT looks cool! I think it would work perfectly using a simpler Control instead of Panel.


frank(Posted 2013) [#66]
Are there any examples / code snippets (is it even possible?) of using junglegui controls without the windows? I almost never have any use for those windows (which are not even resizable?); it would make more sense if you can add panels to your drawing area and add controls to that?


ziggy(Posted 2013) [#67]
there's a control called WindowFrame that is a TopLevelControl that can be used to place GuiControls in it, and it does look like a traditional panel. It is a top level control, so it is the same kind of control as a window, but without borders, caption, etc. Also, this control has a property to set it to transparent, so only controls placed on it are visible. This is designed to allow JungleGui controls to be rendered over any kind of application.

So, all you have to do is create a WindowFrame with any controls in it, placeit a 0,0, set its size to DeviceWidth and DeviceHeight, and set it Transparent = true.

It's easier as it seems.


frank(Posted 2013) [#68]
Sounds good, thank you very much Ziggy!


frank(Posted 2013) [#69]
Another one... I cannot find any example of TabControl, so I tried this;

Local tabs:TabControl = New TabControl
tabs.Position.X = 0
tabs.Position.Y = 0
tabs.Size.X = Self.Size.X
tabs.Size.Y = Self.Size.Y
tabs.Parent = Self ' Parent is GuiForm
Local listPage:= New TabPage("Images")
tabs.TabPages.AddLast(listPage)
imgList = New ImageListView(0, 0, listPage.Size.X, listPage.Size.Y, listPage)
Local drawPage:= New TabPage("Tools")
tabs.TabPages.AddLast(drawPage)
tabs.SelectedTab(listPage)

The tabs show up; Images | Tools

But the imgList doesn't show ; to make it show I have to click on Tools and then on Images, then it shows; if I click on Images first nothing happens and if I don't click on anything Images (which I try to show as default) doesn't show.

If I don't AddLast(drawPage), it shows the imgList correctly.

I'm probably doing something wrong, but what? :)

Edit:

I also notice that if I do

Local tabs:TabControl = New TabControl
tabs.Position.X = 0
tabs.Position.Y = 0
tabs.Size.X = Self.Size.X
tabs.Size.Y = Self.Size.Y
tabs.Parent = Self ' Parent is GuiForm
Local listPage:= New TabPage("Images")
imgList = New ImageListView(0, 0, listPage.Size.X, listPage.Size.Y, listPage)
tabs.TabPages.AddLast(listPage)
Local drawPage:= New TabPage("Tools")
tabs.TabPages.AddLast(drawPage)
tabs.SelectedTab(listPage)

It completely stops working (no errors, just clicking whatever doesn't work). So definitely I'm missing some crucial info here.


ziggy(Posted 2013) [#70]
TabControl is currently unfinished. It was started by sascha and there have not been any additions or improvements to it. So I would not considere it ready to be used safely.


Rone(Posted 2013) [#71]
yes,...TabControl is really pretty unfinished/untested... I will look into it tonight, gonna fix the bugs...


frank(Posted 2013) [#72]
If I can help with anything please ask. I'm now reading / understanding all superclasses so I can find out what's happening ;)


frank(Posted 2013) [#73]
I'm not sure why textfield was made the way it was? It doesn't act like what you would expect from a textfield (drawrect before the first char when you click there, making the chars part to the draw the caret); I use:
format_codebox('
if HasFocus Then
Local text1:String = Text[ .. _caretPos]
Local text2:String = Text[_caretPos ..]
ForeColor.Activate()

#IF TARGET="html5"
SetColor(255, 255, 255)
#END
Font.DrawText(text1, Position.X - _drawOffset, TextY)

Local xsize:Int = Font.GetTxtWidth(text1 + " ") - Font.GetFaceInfo(" "[0]).drawingWidth '- Font.GetFaceInfo(" "[0]).drawingOffset.x

SetAlpha(Abs(Sin(Millisecs() / 3.0)))
BorderColor.Activate()
DrawRect(Position.X + xsize - _drawOffset + 3, Position.Y, 1, Size.Y) ' caret

SetAlpha(1)
ForeColor.Activate()

#If TARGET="html5"
SetColor(255, 255, 255)
#End
Font.DrawText(text2, Position.X + xsize - _drawOffset, TextY)

GetGui.Renderer.DrawFocusRect(Self)
Else
')

And now it behaves normal. I'm missing something for sure; why was it done the way it is done?


Tibit(Posted 2013) [#74]
Your GUI Framework is looking really great!

I read you were modelling Windows Forms, so I assume your use-case aim is GUI for desktop (Mouse + Keyboard) applications and editors?

However I was curious if you had plans for portable devices such as touch-based gui that is commonly seen on phones & pads?

An example of TouchGUI would be a ListView control that you can drag/throw that accelerate and bounce when it reaches the edge.

Since I had plans on maybe doing some stuff like that myself. Or maybe if you don't have plans, maybe I could contribute that as a component in your framework if it is not outside the bounds of the project?


frank(Posted 2013) [#75]
Rone; did you get any chance to test the TabControl? I haven't been capable of doing it properly.

Edit: how do I accurately get sizes in JungleGui? It seems that .Size is not actually the size of the component; for instance if I draw a line @ Size.Y - 20 on a container it doesn't actually appear because it's outside the control. What is the way to accurately find sizes of borders etc so I can calculate where to draw stuff without introducing magic numbers?


Rone(Posted 2013) [#76]
unfortunately not. I hope I find the time tonight ...


Edit: how do I accurately get sizes in JungleGui?


I think padding is what you are looking for ...
format_code('
local position:= CalculateRenderPosition()
backcolor.ActivateDark(150)
DrawBox(position.X + padding.Left, position.Y + padding.Top, size.X -
padding.Left - padding.Right, size.Y - padding.Top - padding.Bottom)
')


ziggy(Posted 2013) [#77]
We maybe shoud add some helper functions.
EDIT: See following post:


ziggy(Posted 2013) [#78]
Commited some changes to the control class so it has the following methods:

GetClientAreaLocation:GuiVector2D()
This method returns the location of the client area (the contents) of a given control. As an example, in a window control, it will be the area inside the window where controls are located and drawn.

GetClientAreaSieze:GuiVector2D()
This method returns the size of the client area (the contents) of a given control.

GetCanvasLocation:GuiVector2D()
This method returns the location of the control in the mojo canvas. including borders and everything.

GetCanvasSize:GuiVector2D()
This method returns the size of the control in the mojo canvas coordinates.


frank(Posted 2013) [#79]
Thanks Rone and Ziggy; that looks good; going to try that now!


ziggy(Posted 2013) [#80]
Latest update includes resizable forms.
forms now have a property called BorderStyle wich can have two values:
eFormBorder.FIXED or eFormBorder.RESIZABLE
If the form is marked as resizable (default value) it can be resized by the user at runtime by stretching it.
There's also a new property called MinimumSize that ensures the form is not made too small by the user.


ziggy(Posted 2013) [#81]
I read you were modelling Windows Forms, so I assume your use-case aim is GUI for desktop (Mouse + Keyboard) applications and editors?

However I was curious if you had plans for portable devices such as touch-based gui that is commonly seen on phones & pads?

An example of TouchGUI would be a ListView control that you can drag/throw that accelerate and bounce when it reaches the edge.
I'll be using this soon in a couple of Android applications, so you can expect some development changes in order to make this much more touch friendly. Also a touch friendly skin with bigger fonts is something I'll be adding whenever I finish my current neverending project.

EDIT: Here a new sample showing the resizable windows functionality:
http://www.jungleide.com/samples/junglegui04/MonkeyGame.html
You can resize the Debug Window. Notice there are still some "scrolling getting updated" bugs on the listbox component, nothing important, but I'll fix it soon-ish --> Already fixed


ziggy(Posted 2013) [#82]
I've just commit a new update that brings virtual keyboard support to JungleGui.
Currently the control base class has a property called: RequiresVirtualKeyboard that is set to false by default (except on TextField control). When this property is set to true, the control will show automatically the virtual keyboard when it has to focus, and it will allow the entrance of text the same way you would do it on a hardware keyboard.
I'm also working (not yet commit) on a high-resolution renderer for small devices with crazy resolutions such as some iPhones or the like.


ziggy(Posted 2013) [#83]
Hello!

A new component called "Canvas" that is a graphics Mojo canvas has been added.

The component can be used mostly the same way you would use a mojo App inherited application, but you inherit Canvas and place it on a form or any other toplevel control if you don't want to have forms (only a rendering area on the device).

This is a sample showing the canvas functionality:



Sample can be viewe here:
http://www.jungleide.com/samples/junglegui05/MonkeyGame.html

This sample requires a VERY optimized browser. It works like a charm on Chrome, it has some lag on Firefox, and renders very very badly on Internet Explorer 9 (haven't tested it on IE10 yet)

Anyway, it's kind of nice to see the scalability that jungle gui is achieving.


frank(Posted 2013) [#84]
Is anyone working on multiline text? If not i'm going to work on an implementation myself (open source of course).


Shinkiro1(Posted 2013) [#85]
That's pretty impressive (also runs perfectly fine on safari 6).


ziggy(Posted 2013) [#86]
@frank: I don't thing anybody is. It would be great to have a multiline text component, of course! Not a trivial task if you ask me, I've been there before ;)


Rushino(Posted 2013) [#87]
Impressive Ziggy!


ziggy(Posted 2013) [#88]
Is this source code understandable?
format_code('Import junglegui

'Required by the events system in all files that do handle events:
#REFLECTION_FILTER+="untitled_2"

'We start the application here
Function Main()
'In order to run a event-driven Junglegui app, just call the execute app with this parameters:
ExecuteApp(New AppLauncher, "CreateForm")
'The first parameter is a instance of an App launcher, wich is a class that can be used as a
'callback to return the "main form" of the application.
'The second parameter is the name of the method in this class that will be called
'in order to create the Main form, when the MOJO canvas is done and ready for "consumption".
End

'This is the application launcher:
Class AppLauncher
Method CreateForm(sender:Object, e:InitializeAppEvent)
e.mainForm = New MyForm
End
End

'This is the application main form:
Class MyForm Extends TopLevelControl

Field button:Button
Method OnInit()
button = New Button
button.Parent = Self
button.Text = "Click me!"
button.AdjustSize()
button.Position.SetValues(50, 50)
button.Event_Click.Add(Self, "Button_Clicked")

Self.Size.SetValues(DeviceWidth, DeviceHeight)
End

Method Button_Clicked(sender:Object, e:MouseEventArgs)
Print "Button has been clicked " + Millisecs()
End
End')
What would you expect it to do?


Rushino(Posted 2013) [#89]
Yes very readable. :) Look very similar to how .NET handle windows winforms..


Tibit(Posted 2013) [#90]
I would guess ExecuteApp uses AppLauncher class as some sort of start class that are inistialized by ExecuteApp. And that after initialization is done a method by name "CreateForm" is called.

I would also assume that our game/app has some sort of root Window from which everything renders and to which thing can be attached to using relative positioning. And that in CreateForm method what you do is say we want this root (mainForm) form to be a new instance of MyForm.

This MyForm has a button in the top-left corner (relative to this form) with a width determined by the text's "Click me!"'s width and this root-form fills the whole screen, I assume that the looks for form and button is determined by a theme or something external. When touch was started inside the button and touch release ended inside it then the Button_Clicked method is invoked and it prints


ziggy(Posted 2013) [#91]
that's exactly what it does. Great!


frank(Posted 2013) [#92]
@Ziggy, how about moving to Github? :) Am I the only one who finds Google code annoying to work with ?


frank(Posted 2013) [#93]
Is there a roadmap for doing something about the resource consumption ? Because my game, with gui.Render() on:



same game without;



Both are too high for my taste, but it's quite insane with Jungle on; feels like my MBP is going into outer space with those fans kicking on at that level :)

Edit: EB? Exabyte? :)


ziggy(Posted 2013) [#94]
What performance measuing tools are you usin? Is this something buit-in into chrome? What's the difference between goodle chrome renderer and google chrome helper?


frank(Posted 2013) [#95]
No, this is just the Apple 'top' tool. I see the same under Linux though.

(I have no Windows, so cannot check there)

Edit: I'm not sure what Helper is but interesting; I have Helper and Renderer running ; Helper is 101% , Renderer is 80%; if I kill Helper the screen goes blank but renderer still runs 80%. Maybe webgl needs a plugin?


ziggy(Posted 2013) [#96]
So it's the resources being used by chrome under your Mac? I see no way to know what's resources consumption related to junglegui here. It looks also like two different processes if you ask me.
gui.Render should not be creating new objects or the like. It's just drawing them, so any performance hit has to be seen as a result of rendering limits on your hardware/navigator. then, memory usage can't be measured like this. There are some areas where some object allocation could be reduced, but other than that, no idea what else could be optimized


frank(Posted 2013) [#97]
Well, I have the same behavior when I run sample1.monkey from your samples. Not as high but Helper on 80%+ and Renderer on 40%+.

Edit: I don't care about memory, but CPU is getting seriously taxed, on all samples as well. I run OS X 10.7 on i7 with 8 gb and all samples take the cpu for 80 to above 100%.


Edit2: Just tried another macbook but with 10.8, same thing.


Tibit(Posted 2013) [#98]
Are you using texture atlases? If not that can cause a LOT of queries and add a lot of load time on web, on other platforms it usually only adds extra drawcalls.

Maybe the theme you are using is not using a texture atlas?


ziggy(Posted 2013) [#99]
Are you using texture atlases?
Not for everything but yes for most of it. That said, there's not much to be drawn using textures other than text. Most of it is just drawing primitives.
I won't be optimizing anything yet. Maybe in the future, but given it's very primitive status, it is not a good idea to start optimizing just yet.


frank(Posted 2013) [#100]
I agree with not doing premature optimization; I was just wondering if it's something you noticed. I am using the theme I'm using because on the other themes the checkboxes have strange / non working behavior for me. I'll post some code later, because I cannot find out what i'm doing wrong there. In the meanwhile I'm getting far enough in Monkey to do profiling/debugging in the HTML5 and iOS targets to find bottlenecks.

Monkey would lend itself fine for a Profiling build version next to Debug and Release which would inject profiling code in every function and which would generate a profiling file (at least on the glfw target).


ziggy(Posted 2013) [#101]
am using the theme I'm using because on the other themes the checkboxes have strange / non working behavior for me
Are you using latest version? There have been lots of bottleneck fixes in the last month on HTML5. Also, I would love to have a sample showing the checkboxes issue in order to fix it, whenever you have any time, feel free to post it here or write a post on the junglegui discussion group.


therevills(Posted 2013) [#102]
Hi Ziggy,

Whilst testing MonkeyMax we may have found a small coding error is JungleGui:

form.monkey
format_code(' 'summary:This property can be used to set/get the Form caption
Method Text:String() Property
Return _text
End

Method Text:String(value:String) property
_text = value
Return _text
End')

Do you mean to have two properties returning String for the same variable?


frank(Posted 2013) [#103]
Multilinetexteditor => Does that actually work? I can show multiline text, but the editing part is not really there yet?


ziggy(Posted 2013) [#104]
its a WIP. It does not work yet


ziggy(Posted 2013) [#105]
Do you mean to have two properties returning String for the same variable?
It is "inherited" from the first implementation of it, but I'll change it so the setter does return void. Thanks for pointing it out


CopperCircle(Posted 2013) [#106]
Is there a code example of your realtime wordwrap demo? Thanks.


ziggy(Posted 2013) [#107]
Yes, it's on the Jungle gui samples folder.
This is the code of the wordwrapp form:
format_code('Import junglegui
Import junglegui.multilinetexteditor
#REFLECTION_FILTER+="demos.textbox"

Class TextBoxForm Extends Form
Field textBox:MultilineTextbox

Method OnInit()
textBox = New MultilineTextbox
textBox.Parent = Self
textBox.Name = "MultilineTextBox"
textBox.Text = LoadString("sampletext.txt")

Self.Text = "Resize me!"
Self.Event_Resized.Add(Self, "Form_Resized")


DoLayout()
End

Method Form_Resized(sender:Object, e:EventArgs)
DoLayout()
End

Method DoLayout()
textBox.Size.SetValues(GetClientAreaSize.X, GetClientAreaSize.Y)
End
End')

EDIT: This is the sample running: (open the TextBox sample)
http://www.jungleide.com/samples/junglegui06/MonkeyGame.html


Tibit(Posted 2013) [#108]
Ziggy I realized that I can probably use junglegui if I want to use your event system or it is only for gui-stuff?

How would I make this work? (if possible)
format_code('
Class Tank
Field Ammo:Int
Field OnFireEvent:EventHandler<TankArgs??> = New EventHandler()

Method Fire:Void()
If Ammo > 0
'Ammo -= 1


OnFireEvent.RaiseEvent(Self, new TankArgs(Ammo, "SomeAdditionalEventInfo") )
Else
'Nothing happens
End
End
End
')
Do I need a class that extends from EventArgs? Do I need this for every event? How would that look like?


frank(Posted 2013) [#109]
I did some profiling in Firebug + Chrome; seems 30% of my game is spent in control.CalculateRenderPosition(), 10% in control.FocusChecks and about 15% in various functions of GUIVector2D. That's 55% spent on stuff which is by far the most static (I would say people playing click once in every few minutes on some control, while animation is going on all the time outside the controls); am I doing something wrong? I use gui.Update() and gui.Render() on standard controls and outside those controls i'm drawing my stuff; i'm not touching any junglegui besides setting up and running gui.Update in my update and gui.Render in my render?

Like I said before; I tried commenting out gui.Render() => that brings the CPU down from 100% to 20%. I tried ONLY running jungle (so switching off all my code) ; that leaves the CPU at 100%.

Anything I can do? Because jungle is killing my framerate and on anything high powered laptops it's unusable and on high powered it kills the battery in no time.

Same happens on GLFW target, but I don't know how to profile that.

Edit: I cannot imagine it's the jungle code; you would've seen/fixed it; so what more can influence it?

Edit: after some profiling on my own code only; almost 80% there is spent in mojo functions; that seems the desired behavior ?

Edit: using the useless code:

Method CalculateRenderPosition:GuiVector2D()
Local v := New GuiVector2D()
v.SetValues(0,0)
Return v

I see a CPU usage drop of 20%, so definitely some heavy lifting happening in there.

Edit: so basically it seems, if you nest only a few components;

toplevel -> tabcontrol -> listview

for instance

it spends insane amounts of time adding all it's parents in that and other calculation methods.

The 'easiest' way to fix it for me would be to simply replace everything with simple, custom for this game, GUI code again, but I really don't want to do that :( Hope you can give some insight here...

Edit: Because i'm using TopLevel and figured that means my parents don't change (in my case), I tried https://gist.github.com/tluyben/5280319 and that worked; it removed the load for that part without any sideeffects (so far, well not ones I care about at the moment). Not really a permanent solution, but my laptop is now a desktop because the battery is empty in no time because of this so I need to resolve it asap.

Edit: now it spends most of it's time in Viewport.Calculate and then in FocusChecks; around 30-40% depending on what i'm doing according to the profiler.

Edit: I notice that it also renders obscured/invisible controls? Tabpages and others; it renders everything, all the time, even though it's not needed? What's the idea behind that? I can imagine that for some things, but for basic gui containers completely overlapping eachother that makes no sense?

Edit: PropertyGrid is no longer compatible with the latest junglegui version? it renders the text the same color as the background unless selected after compiling with the latest version. => I tried a lot of different things; cannot get it to work at all; it just shows an empty rectangle; http://o7.no/YLKQ1c

=> Found the problem; the old ScrollableControl works differently from the new; the Super.Render() draws over the stuff from the PropertyGrid, so the new version did break it; if I move Super.Render() to the top of the PropertyGrid.Render() it works again, but no scrollbar (visible=>it does work) (which is probably overdrawn by PropertyGrid). At least it's workable again :)


CopperCircle(Posted 2013) [#110]
How would I scroll text in a large multiline textbox? I am looking to have a column of text but would need the swipe it to smoothly scroll through.

Thanks.


ziggy(Posted 2013) [#111]
both propertygrid and multilinetextbox are not ready yet! will get back to them soon-ish


CopperCircle(Posted 2013) [#112]
Thanks, it's all coming along nicely.


ziggy(Posted 2013) [#113]
Edit: Because i'm using TopLevel and figured that means my parents don't change (in my case), I tried https://gist.github.com/tluyben/5280319 and that worked; it removed the load for that part without any sideeffects (so far, well not ones I care about at the moment). Not really a permanent solution, but my laptop is now a desktop because the battery is empty in no time because of this so I need to resolve it asap.

This has been drastically improved in my local clone, will commit later, but it reduces a lot of calculations.

Edit: now it spends most of it's time in Viewport.Calculate and then in FocusChecks; around 30-40% depending on what i'm doing according to the profiler.
that's expected and hard to avoid, as it has to calculate the control boundaries taking into accout parent bounds. If you can find a way to make this calculation faster, go for it and share!

Edit: I notice that it also renders obscured/invisible controls? Tabpages and others; it renders everything, all the time, even though it's not needed? What's the idea behind that? I can imagine that for some things, but for basic gui containers completely overlapping eachother that makes no sense?

It does not render invisible controls or controls outside of view. However, rendering is done using Z-Order, so if you overlap completely a control, the hidden control will be rendered. That's expected behaviour as this GUI is suposed to support transparent rendering if required. It's up the the GUI user to use it with a wise design. Don't overlap controls that do not need to be shown. Set visible = falst to the ones that you don't want to render.

Edit: PropertyGrid is no longer compatible with the latest junglegui version? it renders the text the same color as the background unless selected after compiling with the latest version. => I tried a lot of different things; cannot get it to work at all; it just shows an empty rectangle; http://o7.no/YLKQ1c
Propertygrid was developed by Rone and it has no longer being maintained or update and may require some work to make it compatible with latest version. I separated it from the common controls library as I won't be maintaining it yet (I want to get the more basic controls right first).

=> Found the problem; the old ScrollableControl works differently from the new; the Super.Render() draws over the stuff from the PropertyGrid, so the new version did break it; if I move Super.Render() to the top of the PropertyGrid.Render() it works again, but no scrollbar (visible=>it does work) (which is probably overdrawn by PropertyGrid). At least it's workable again :)
Ok, if you find a permanent solution, share!


ziggy(Posted 2013) [#114]
I've just commit latest changes with a breaking change. I've modified the CalculateRenderPosition method name to UnsafeRenderPosition as it
is what it is now. Calculation is done behind the scenes only when required and this funciton returns the catched result of latest calculation.

This is "unsafe" as modifying the result of this function will result on drawing artifacts, so use at your won risk! The Gui engine will know when to recreate the calculation due to something being modified, and will do so in an efficient way. This is a breaking change.

To get the same behavior (the safe one) as older CalculateRenderPosition, you should use the LocationInDevice function. This one is safe but slower as it creates additional vector objects for the sake of safeness.

In other words, if you use UnsafeRenderPosition anywhere, be sure to leave the X and Y coordinates as they were to avoid subsequent calls to UnsafeRenderPosition getting wrong results.

EDIT: Also latest Monkey version v70 is required


ziggy(Posted 2013) [#115]
Just added scaling suport to the whole GUI system.
Use ScaleX and ScaleY on the Gui class to set the rendering scaling for the whole Gui system.
Also added the corresponding DevideToGui and GuiToDevice coordinates conversion methods.
I can't believe it was this easy...


ziggy(Posted 2013) [#116]
First android application (that I know of) that uses Jungle Gui is now available at Google Play!

https://play.google.com/store/apps/details?id=com.lemonbytes.lemonapps.idealweightcontrol

Yay, we'll see if it's as stable as it seems on my machine!

It's a veru silly application, I've done it merely for the sake of giving Jungle Gui a proper real testing.


joasia36(Posted 2013) [#117]
any news on this?


ziggy(Posted 2013) [#118]
on what?


Armitage1982(Posted 2013) [#119]
I guess he's talking about JungleGui OP.
@josia36 MyGUI Maybe ?


vmakar85(Posted 2013) [#120]
2ziggy on my android sony es work good and stable.


ziggy(Posted 2013) [#121]
Just committed a version with a new component called GuiImage that is just a component that draw an image in its center and can also produce events such as click, mouse enter, etc... Like a WindowsForm PictureBox. Currently there's no image scaling, image is always draw at 100% of current Mojo scale, at the center of the component, but I plan on adding stretching options to the component.
However for complex drawing you can always use the Canvas component that supports all mojo 2D commands in a native way.
I've also added a SetAll method for the Padding component of all controls, wher you can set all the Padding values at once.


ziggy(Posted 2014) [#122]
Hello! After several months working on my spare time on Junglegui I've managed to make it a lot faster than it was (it was fast, but now it's a lot faster).
the main changes are that all components rendering cordinates are pre-catched and only recalculated when required. Also, it makes a lot of work by preventing unneeded rendering, and by disabling the updating of controls with their invisible property to "true" (this can be changed in a per-control basis).

I've also improved the events system and mostly finished wordwrapp text viewer (not yet editable but should be a piece of cake now).

Also, now all container controls can scroll their contents. I'm working on a ScrollPanel that also renders scrollbars that automatically adapt to the contents of the contained elements.

Once this is done, I plan on making a better ComboBox and add Memus and release a first alpha version of this big Gui library, I'll be also updating the samples with latest builds and removing controls that are deprecated now (lots of them where started and never properly finished).

I haven't been working on complex controls as I've been doing tones of work in the core of the library instead. It's easier to build on a solid basis, than to correct a big framework later.

then, I've been adding a method that will eventually make it easy to create Gui editors for Jungle Gui. It's a method that generates a list of property names of the control and their return values, so a property grid can be dynamically created and used to read and modify a control status at design time by using reflection. It's a WIP but this would be great.

My idea behind this GUI designer (that's not even started) I think is a quite good idea.

I'll be separating control creation and logic, from control placement and sizing, so you will be able to define several control sizes and placement depending on resolutions and aspect ratios: Typical 16:9, 16:10, iPad weird ratio, etc... and let the library choose the right one depending on the actual screen resolution and orientation. This way, it sohuld be very easy to provide multi-device applications with a nice looking GUI. This library should take closest layout if pre-defined one does not match exactly as Jungle gui is currently scalable.

I hope it makes sense... This is just a small update of the "a lot" that has been happening with this library in the latest months.


ziggy(Posted 2014) [#123]
Hello, a new small sample:



See it in action here: http://www.jungleide.com/samples/junglegui07/MonkeyGame.html

This shows some new implementations:

1.- A Tab control (it's very basic but very solid).

2.- The auto-scrolling control container. In the second tab, a bunch of buttons and a list control is placed in a way that scrolling is required to show all the controls in the tab. The ScrollingContainer is being used to automatically handle this. If you resize the window, you'll see how scrolling addapts to a point that scrollbars can dissapear

3.- A canvas inside a TabPage with a Banana (from skn3). This is there to measure the autosuspend of canvases and controls when a control is not being shown. (this helps the whole gui perform this fast)

It's all rendered using HTML5 (no flash or anything like this).

This also shows some of the latest changes on the default gui skin.


Nobuyuki(Posted 2014) [#124]
does the scrolling container cull widget polling in any way?


ziggy(Posted 2014) [#125]
What's "cull widget polling"?
EDIT: If you mean if it stops rendering and uipdating controls that are outside the visible area, then yes, but it's default to any control in JungleGui, not only the scrolling container. If a control gets out of any visible bounds, it's discarted from rendering and updating, except timer controls.


Nobuyuki(Posted 2014) [#126]
I meant, other than hierarchical stopping of widgets updates and rendering, do 2d panels spatially partition their child controls to reduce the number of object checks needed? Or do you think that checking each one for overlap with the clip rectangle is good enough? It's a question I've been asking myself for my own gui panel.


ziggy(Posted 2014) [#127]
I meant, other than hierarchical stopping of widgets updates and rendering, do 2d panels spatially partition their child controls to reduce the number of object checks needed? Or do you think that checking each one for overlap with the clip rectangle is good enough?
Rendering is unavoidable each frame, and updating is a non issue. Most controls have empty update code, and those that haven't do really need to perform some checks on every update. Most of the control calculation that happens after a status change on anything (the control itself, it's parent, mouse enters the control area, etc) are done only when this things happens using an internal messaging system (similar to .net) for the lower level operations and, this messages are lateron converted to Events for higher level interaction with the Gui gadgets.
Not sure if this answers your question ?


ziggy(Posted 2014) [#128]
Just recompiled the second sample with latest version and it's ultra smooth!

http://www.jungleide.com/samples/junglegui02/MonkeyGame.html

Also, notice I've just added mouse pointer change support on html5. Resize the DebugForm, or use the TextField to see how the mouse cursor sets its correct pointer, using the host system mouse pointers.

I plan to add this to GLFW too whenever I have the time to do it.


nikoniko(Posted 2014) [#129]
ziggy wrote:
r use the TextField to see how the mouse cursor sets its correct pointer, using the host system mouse pointers.


Input to textfield is very slow - browser utilizes 100% cpu in.


ziggy(Posted 2014) [#130]
which browser?


nikoniko(Posted 2014) [#131]
ziggy wrote:
which browser?


Firefox 27.0.1/Windows XP


ziggy(Posted 2014) [#132]
I'll try it later. I've been using chrome and I'm not having any issue with chrome


nikoniko(Posted 2014) [#133]
ziggy wrote:
I'm not having any issue with chrome


Chromium on the same computer is ok. FF 27 on other computer is about 15-20% CPU utilization.


ziggy(Posted 2014) [#134]
Maybe your FF is not using hardware acceleration? also, this sample is using as much CPU as possible to calculate the unoptimized particles.and I'm also using UpdateRate(0) which may stress a bit the EventPolling system


nikoniko(Posted 2014) [#135]
ziggy wrote:
Maybe your FF is not using hardware acceleration?


You are right. This FF/WinXP is a virtual machine without video acceleration where html5 games are working well.


ziggy(Posted 2014) [#136]
I've been working on a potential ModMan Gui frontend. I don't know if it will ever see the light of day (I hope so) but I thought it was a good idea to share, as it'll be open source:

Here's a snapshot of it running as a Desktop App on window:



Here's a running mockup built agains html5:

http://www.jungleide.com/samples/modman/MonkeyGame.html


smilertoo(Posted 2014) [#137]
Has some recent update broken this? all i find is a d/l with a warning saying it's depreciated...and nothing in it compiles due to invalid escape character errors.


ziggy(Posted 2014) [#138]
@smilertoo: It works well here, but be sure to be using latest Monkey version. Also, can you provide any code causing compilation errors? It should work!


Samah(Posted 2014) [#139]
@ziggy:
Your last commit has a bad merge in junglegui.monkey.
Also it looks like the GetColor(Int[]) method no longer exists in Mojo? Edit: Never mind, it was looking for an old version of mojo.


ziggy(Posted 2014) [#140]
Your last commit has a bad merge in junglegui.monkey.
I'll check it later at home, I'm at work now, but thanks for letting my know!


ziggy(Posted 2014) [#141]
It should be ok now


John Galt(Posted 2014) [#142]
Some seriously impressive work here, gentlemen. I like what I'm seeing.

Thanks for sharing.


ziggy(Posted 2014) [#143]
Thanks! I plan on adding some controls now that the core part of it is starting to shape. No ETA as I'm doing it on my free time, but feel free to contribute if you wish!


retroX(Posted 2015) [#144]
Help. When I attempt to build "particlessample.monkey" a compilation error pops up for the file "propertygrid.monkey" which says, "Method ComboBox.Parent:ContainerControl(Local parentControl:ContainerControl) is private."


Samah(Posted 2015) [#145]
@apo: Help. When I attempt to build "particlessample.monkey" a compilation error pops up for the file "propertygrid.monkey" which says, "Method ComboBox.Parent:ContainerControl(Local parentControl:ContainerControl) is private."

Yeah, this is a bug in JungleGui. To fix it:
1) Open wip\combobox.monkey
2) Scroll to line 167
3) Move the two "Parent" property methods above the "Private" directive on line 142.


Manveru(Posted 2015) [#146]
Hi, can any one give me link on some kind of documentation for JUNGLEGUI?


ziggy(Posted 2015) [#147]
The module itself should contain documentation. Also, a much more sparse but lower level documentation of the internal design can be found here:
https://github.com/ziggybcn/junglegui/find/wiki

The whole module has been put on hold after reading plans of Monkey2 having a proper delegates system, as current Monkey1 reflection is a pain t work with


GarBenjamin(Posted 2015) [#148]
Hey, I bought the Jungle IDE a month or two back and really like it a lot. I was wondering if you had any plans to, or could, add the following:

1. Indentation Controllers. In MS Visual products and others I have used at the top there are indentation arrow buttons. One pointing left and one pointing right.
If the cursor is on a line, clicking the Left Indent button moves that line to the left by one tab. Clicking the Right arrow moves that line to the right by one tab.
Highlighting a section and clicking on the buttons does the same thing only it tabs the whole selection of lines left or right.
I am a nut about keeping my code well formatted and use this feature often in the other editors. Would be awesome to have it in Jungle.

2. Another thing I use often is Find All References. Typically this is located right beneath the Go (Jump) to Definition option.
Basically you right click on something then select Find All References and a list of all items that reference the item selected appear.
I was thinking that since Jungle projects maintain a list of all files inside the project this would not be terribly complex to add.
Ideally clicking on an item in the returned list pulls up that file in the editor and moves to that line.
This would be another awesome improvement.

Thanks!


ziggy(Posted 2015) [#149]
@GarBenjamin: This topic is not about ´jungle Ide, but about Jungle Gui, which is a module for Monkey X. (worst name ever maybe, they can be easily confused!)

That said:
ndentation Controllers. In MS Visual products and others I have used at the top there are indentation arrow buttons. One pointing left and one pointing right.
If the cursor is on a line, clicking the Left Indent button moves that line to the left by one tab. Clicking the Right arrow moves that line to the right by one tab.
Highlighting a section and clicking on the buttons does the same thing only it tabs the whole selection of lines left or right.
I am a nut about keeping my code well formatted and use this feature often in the other editors. Would be awesome to have it in Jungle.

While there are no speciffic buttons to indent and outdent code, if you want to tabify a block of text, you can select it and press TAB. You can also do the opposite by selecting the a block of text and clicking SHIFT+TAB
Also, making Ctrl+T on a text selection will make Jungle Ide automatically format all selected code indentation. If there is not any specific text selection, the formatting will be applied to the whole document.

2. Another thing I use often is Find All References. Typically this is located right beneath the Go (Jump) to Definition option.
Basically you right click on something then select Find All References and a list of all items that reference the item selected appear.
I was thinking that since Jungle projects maintain a list of all files inside the project this would not be terribly complex to add.
Ideally clicking on an item in the returned list pulls up that file in the editor and moves to that line.
This would be another awesome improvement.
Yes, I've got an implementation for this almost ready but some small issues with generics is holding it back! Hope to be releasing a working version soon


GarBenjamin(Posted 2015) [#150]
@ziggy hey thanks for letting me know about the Shift+Tab didn't know that! Will be awesome.

Sorry about posting in here. I looked around and didn't see any thread for the IDE although I know I found it before. Thought hmm doesn't sound like the same name but I think it is the same person so maybe this is it. lol


Paul - Taiphoz(Posted 2017) [#151]
After setting a textbox up initially setting its values, when I then set its value elsewhere in code it appears like the value is set but the new text is not being displayed in the box.

any clues?

I'm setting the form.textbox.Text=newstring

Double Checked, the values are changing internally the new value is not being drawn tho.


Paul - Taiphoz(Posted 2017) [#152]
So pressing F2 has no visible effect.

format_codebox('
Import junglegui
Import junglegui.renderers.concretejungle
Import junglegui.renderers.roundforms

'It's important to add this file to the reflection filter if we want it to be able to process event handlers
#REFLECTION_FILTER+="${MODPATH}"

#GLFW_WINDOW_RESIZABLE=True
#GLFW_WINDOW_TITTLE="Jungle Gui Sample"
Global jgui:Gui

'Start the application
Function Main()
New Sample
End


Global OptionsForm:cOptionsGUI

Class Sample Extends App
Field jgui:Gui

Method OnCreate()
SetUpdateRate(60)
jgui = New Gui 'We create the Gui manager.
OptionsForm = New cOptionsGUI
try
OptionsForm.InitForm(jgui)
Catch jge:JungleGuiException
Print "Form could not be initialized becouse of an exception:"
Print jge.ToString()
End
End

Method OnUpdate()
Try
jgui.Update()
Catch jge:JungleGuiException
Print "Error updating the Gui component:"
Print jge.ToString()
Error(jge.ToString())
End

If KeyHit(KEY_F1)
Select OptionsForm.Visible
Case True
OptionsForm.Visible(False)
Case False
OptionsForm.Visible(True)
End Select
EndIf

If KeyHit(KEY_F2)
OptionsForm.homeSystemsBox.Text="This"
Endif
End

Method OnLoading()
End

Method OnRender()
Cls

Try
jgui.Render()
Catch jge:JungleGuiException
Print "Error rendering the Gui component:"
Print jge.ToString()
Error(jge.ToString())
end
End
End







Class cOptionsGUI Extends Form

'Field panel:junglegui.Panel

Field Volume_Status_Current:junglegui.Slider
Field Volume_Status_Other:junglegui.Slider
Field Volume_Home:junglegui.Slider
Field Volume_Watch:junglegui.Slider
Field Volume_Ping:junglegui.Slider
Field Volume_Current:junglegui.Slider

Field volumePanel:junglegui.Panel
Field toonPanel:junglegui.Panel
Field apiPanel:junglegui.Panel

'character input
Field characterBox:TextField
Field intelChanBox:TextField
Field homeSystemsBox:TextField
Field watchSystemsBox:TextField
Field regionBox:TextField
Field themeBox:TextField

Field FirstRun:Bool
Field Changed:Bool

Method OnInit()
'''
''' MyForm
'''
Self.FirstRun = True
Self.Changed = False

Self.Name = "Options"
Self.Text = "Options"
Self.Size.SetValues(520, 380)
Self.Position.SetValues(20, 20)
Self.BackgroundColor.SetColor(.5, 204, 204, 204)
'Self.Visible = False



'
'Volume
'

Local vol_label:= New junglegui.Label
vol_label.Parent = Self
vol_label.Text = "Sound Options"
vol_label.Position.SetValues(5, 10)

Self.volumePanel = New junglegui.Panel
volumePanel.Parent = Self
volumePanel.Position.SetValues(5, 30)
volumePanel.Size.SetValues(240, 245)
volumePanel.BorderColor = SystemColors.FormBorder.Clone()
volumePanel.BackgroundColor.SetColor(1, 214, 214, 214)

Volume_Status_Current = New junglegui.Slider
SetSliderValues(Volume_Status_Current, 0, "Status Current", 1 * 100)
Volume_Status_Other = New junglegui.Slider
SetSliderValues(Volume_Status_Other, 1, "Status Other", 1 * 100)
Volume_Current = New junglegui.Slider
SetSliderValues(Volume_Current, 2, "Current", 1 * 100)
Volume_Home = New junglegui.Slider
SetSliderValues(Volume_Home, 3, "Home", 1 * 100)
Volume_Watch = New junglegui.Slider
SetSliderValues(Volume_Watch, 4, "Watch", 1 * 100)
Volume_Ping = New junglegui.Slider
SetSliderValues(Volume_Ping, 5, "Ping", 1 * 100)


'
' Character and stuff.
'


Local tempBoxLabel:= New junglegui.Label
tempBoxLabel.Parent = Self
tempBoxLabel.Position.SetValues(260, 10)
tempBoxLabel.Text = "Intel options"
tempBoxLabel.Name = "inteloptions"

Local IntelPanel:= New junglegui.Panel
IntelPanel.Parent = Self
IntelPanel.Position.SetValues(260, 30)
IntelPanel.Size.SetValues(240, 245)
IntelPanel.BorderColor = SystemColors.FormBorder.Clone()
IntelPanel.BackgroundColor.SetColor(1, 214, 214, 214)


characterBox = New junglegui.TextField
SetBoxValues(characterBox, 0, "Character", "Player", 265)

intelChanBox = New junglegui.TextField
SetBoxValues(intelChanBox, 1, "Intel", "chan1,chan2", 265)

homeSystemsBox = New junglegui.TextField
SetBoxValues(homeSystemsBox, 2, "Home", "", 265)

watchSystemsBox = New junglegui.TextField
SetBoxValues(watchSystemsBox, 3, "Watch", "", 265)

regionBox = New junglegui.TextField
SetBoxValues(regionBox, 4, "Region", "TestRegion", 265)

themeBox = New junglegui.TextField
SetBoxValues(themeBox, 5, "Theme", "TestTheme", 265)

FirstRun = False

End

Method SetTextFieldText:Void(box:junglegui.TextField,txt:String)
box.Text=txt
End Method

Method GetNextHeight(control:Control)
Const Margin:Int = 5
Return control.Position.Y + control.Size.Y + Margin
End

Method GetVisible:Bool()
'If Self.Position.GetValue
Return Self.Visible
End Method

Method Hide:Void()
Self.Visible(False)
If Self.Changed = True
'Note: Options GUI changed, save to Options Object and Update the readers.
'Account.UpdateOptionsFromGUI()
Self.Changed = False
EndIf
End Method

Method Show:Void()
Self.Changed = False
Self.Visible(True)
'Account.FillOptionsGUI()

End Method

Method SetBoxValues(box:junglegui.TextField, Index:Int, name:String, value:String[], _x:Int = 10, _y:Int = 10)

box = New junglegui.TextField
box.Parent = Self
box.Position.SetValues(_x, _y + 28 + Index * 30)
box.Size.SetValues(220, 15)
box.AutoAdjustSize = False
box.Name = name
box.Event_TextModified.Add(Self, "Box_Value_Changed")

Local st:String
For Local i:Int = 0 To value.Length - 1
st += value[i] + ","
Next
box.Text = st

Local label:= New junglegui.Label
label.Parent = self
label.Text = name
label.Position.SetValues(_x, _y + Index * 25)
label.Position.Y = box.Position.Y - (label.Size.Y - box.Size.Y) / 2 - 13

End Method

Method SetBoxText:Void(box:junglegui.TextField, value:String[])
Local st:String
For Local i:Int = 0 To value.Length - 1
st += value[i] + ","
Next

Select box
Case Self.homeSystemsBox
Print "Changing " + Self.homeSystemsBox.Name + " Value From " + Self.homeSystemsBox.Text + " to " + st
Self.homeSystemsBox.Text = st
Self.homeSystemsBox.Event_TextModified.Add(Self, "Box_Value_Changed")
Case Self.watchSystemsBox
Print "watch"
Self.watchSystemsBox.Text = st
Self.watchSystemsBox.Event_TextModified.Add(Self, "Box_Value_Changed")
Case Self.characterBox
Print "char"
Self.watchSystemsBox.Text = st
Self.watchSystemsBox.Event_TextModified.Add(Self, "Box_Value_Changed")
Case Self.intelChanBox
Print "intel"
Self.watchSystemsBox.Text = st
Self.watchSystemsBox.Event_TextModified.Add(Self, "Box_Value_Changed")
End Select



End Method

Method SetBoxText:Void(box:junglegui.TextField, value:String)
Select box
Case Self.themeBox
Print "theme"
Self.themeBox.Text = value
Self.themeBox.Event_TextModified.Add(Self, "Box_Value_Changed")
Case Self.regionBox
Print "Region"
Self.regionBox.Text = value
Self.regionBox.Event_TextModified.Add(Self, "Box_Value_Changed")
End Select
End Method


Method SetBoxValues(box:junglegui.TextField, Index:Int, name:String, value:String, _x:Int = 10, _y:Int = 10)

box = New junglegui.TextField
box.Parent = Self
box.Position.SetValues(_x, _y + 40 + Index * 40)
box.Size.SetValues(220, 19)
box.AutoAdjustSize = False
box.Name = name
box.Text = value
'box.Event_TextModified.Add(Self, "Box_Value_Changed")

Local label:= New junglegui.Label
label.Parent = self
label.Text = name
label.Position.SetValues(_x, _y + Index * 20)
label.Position.Y = box.Position.Y-5 - (label.Size.Y - box.Size.Y) / 2 - 13

End Method

Method SetSliderValues(slider:junglegui.Slider, Index:Int, name:String, initValue:Int = 100, _x:Int = 10, _y:Int = 10)

slider.Position.SetValues(_x, _y + 40 + Index * 40)
slider.Parent = Self
slider.Name = name
slider.Maximum = 100.0
slider.Size.SetValues(230, 19)
slider.Maximum = 100.0
slider.Value = initValue
slider.Event_ValueChanged.Add(Self, "Slider_Value_Changed")
slider.BackgroundColor.SetColor(1, 214, 214, 214)

Local label:= New junglegui.Label
label.Parent = self
label.Text = name
label.Position.SetValues(_x, _y + Index * 20)
label.Position.Y = slider.Position.Y-5 - (label.Size.Y - slider.Size.Y) / 2 - 13

End

Method Box_Value_Changed(sender:Object, e:EventArgs)
Print "Box Value Changed"
Local box:= junglegui.TextField(sender)
If box = Null Then Return
If FirstRun Then Return
'Print "Performing Edit"
Select box.Name
Case "Character"
'Print "On Character Box"
Self.Changed = True
Case "Intel"
Self.Changed = True
Case "Home"
Print "Home Got Changed"
Self.Changed = True
Case "Watch"
Self.Changed = True
Case "Region"
Self.Changed = True
Case "Theme"
Self.Changed = True
End Select
End Method

Method Slider_Value_Changed(sender:Object, e:EventArgs)
Local slider:= junglegui.Slider(sender)
if slider = null Then Return
If Self.FirstRun Then Return

Select slider
Case Volume_Status_Current
'Print "volume " + Self.Volume_Status_Current.Value
'Print "ass float" + Float(Self.Volume_Status_Current.Value)
'Print "by 100 " + Float(Self.Volume_Status_Current.Value / 100)
'This works. 'Print "by 100 as float " + Float(Float(Self.Volume_Status_Current.Value) / 100)
'Options.Volume_Status_Current = Float(Float(Self.Volume_Status_Current.Value) / 100)
Case Volume_Status_Other
'Options.Volume_Status_Other = Float(Float(Self.Volume_Status_Other.Value) / 100)
Case Volume_Home
'Options.Volume_Home = Float(Float(Self.Volume_Home.Value) / 100)
Case Volume_Watch
'Options.Volume_Watch = Float(Float(Self.Volume_Watch.Value) / 100)
Case Volume_Ping
'Options.Volume_Ping = Float(Float(Self.Volume_Ping.Value) / 100)
Case Volume_Current
'Options.Volume_Current = Float(Float(Self.Volume_Current.Value) / 100)
End
end

End
')