Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: EEGUI - DOTNET GUI system for TV3D  (Read 2610 times)
EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« on: December 09, 2009, 06:11:27 PM »

This thread is to introduce you to, and keep you updated with the development of, EagleEye's GUI system for Truevision3D: EEGUI.

EEGUI was developed for personal use, and originally sold as a for-profit GUI library.  It is now free to use, with the source code available to everyone for the purposes of learning as well as the ability to further develop your own custom GUI solutions.  It is released under the LGPL license.

EEGUI FEATURES

Pre-written Controls
  • STANDARD controls: Label, Button, Text Box (with text selection), Check Box
  • ADVANCED controls: Combo Box, List Box, Multi Line Label (with text wrapping), Progress Bar, Value Selector/slider, Scrolling Windows
  • COMPLEX controls: Enhanced multi-line multi-color wrapping text window (WIP), Tab Control (WIP)
  • Additionally, there are a few "attachable" controls that work like "siblings" to the control they're attached to, meaning they're both children of the same parent, but are attached to each other.  This was done to facilitate scroll bars.  Other attachable controls may be added via inheritance.

Object-Oriented Design
The OOP design of EEGUI gives you great flexibility!

  • Many of the base class functions are overridable, so you can do your own custom coding/rendering on top of the base.
  • Due to polymorphism, all controls can be children of any other control! (All controls must inherit from guiControlBase, not only for this reason, but to enable the base functionality of all controls anyway).
  • Using the inheritance structure, development of your own customized "looks" for various controls are easy to implement.  (See http://www.youtube.com/watch?v=xndUrEBvZzE and http://www.youtube.com/watch?v=PHQB5Yw2s3g to learn how it works).
  • OOP, by its very nature, makes any code revisions more stable and easier to implement, as well as making the DLL smaller and "tighter".  EEGUI is only ~4400 lines of code!

Effects Over Time BUILT IN!

"Effects" in EEGUI are defined as "transitions over time".

If you think about it, there are only 3 effects you really need in a GUI system:
  • Resize - Grow or shrink your controls over however long a time frame you want.  Cause windows to "pop up", or animate your menus by having them grow out of menu bars and shrink back in over small periods of time.
  • Slide - A simple "change position over time" effect, causing a window to slide around the screen from wherever it is, to wherever you want it to go.
  • Fade - Alpha fading over time is a powerful yet subtle and effective way to add flare and professionalism to your GUI!

Skilled GUI developers will use these effects heavily, often using all three at the same time.

The EEGUI "framework" allows for almost unlimited extensibility!

Due to the inheritance framework, you can extend any of the built-in controls, or create your own custom control that does exactly what you want it to do!  In reality, 95% of EEGUI's functionality is built in to the GUICore and guiControlBase classes.  The rest of the package is almost completely optional!

For information on how to use EEGUI, please see the readme file included in the package.

Also, subscribe to the EEGUI mailing list: http://groups.google.com/group/eegui
The mailing list serves as a help community for EEGUI users.

I am also often on IRC (whether I'm at the computer or not).  Feel free to come and ask me questions there if you need any help! :)

Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« Reply #1 on: December 11, 2009, 11:57:34 PM »

I have a few irons in the fire as far as EEGUI is concerned.

I have never been quite happy with hard-coding "look and feel" stuff, so I am putting in a text initialization file reader type of thing...

Basically, it's a pretty standard implementation of what you'd see normally for this sort of thing.  guiControlBase now has the function "LoadControlDefinition(String)" that accepts a file path/name as the parameter... that file is read, and parsed line by line.

There is an overridable function "ParseLine", so derived classes should override it and set up a select/case statement like the one in guiControlBase to properly parse lines var/val pairs for the derived class.  Your overridden ParseLine function should also call the base.ParseLine in the "case else" situation that the line could not be parsed in the derived class.

I have written a few helper functions to parse certain types of lines:
ParseBool(String)
ParsePoint(String)
ParseRect(String)
ParseColor(String)

Each of these functions should be used when parsing the VALUE of a line, for any of these particular data types.

  • Standard commenting applies... meaning "// this is a comment" will get parsed out, whether it's on its own line, or at the end of any other line.
  • Variables are on the left, then an equals sign, then the value.
  • Whitespace is trimmed, so a line can be "width=100" or "width = 100"
  • One line, one var=val pair.
  • Boolean values can be {"y" or "n", "yes" or "no", "1" or "0", "true" or "false"}
  • Points, sizes, and rectangles are colon separated.  "x:y", "width:height", (rectangle) "left:top:width:height"
  • All string comparisons are done using ".tolower" on both sides, so caps doesn't matter.
  • Colors are all formatted: "r,g,b,a", and are converted to Singles
  • All Enum value strings are the same as the internal Enums (eg: ToolTipDirection=BelowRight)

guiControlBase has, so far...
STRINGS
"name"
"tagstring"
"tooltip"
"texture_base"
"texture_mouseover"
"texture_mousedown"
"texture_selected"
"texture_disabled"

BOOLEANS:
"enabled"
"allowfocus"
"allowmouseover"
"ismodal"
"suppressmodalinput"
"iscircular"
"canbedragged" (Array of 4, comma delineated)
"allowdroppedobjects"
"visible"
"texture_base_enabled"
"texture_mouseover_enabled"
"texture_mousedown_enabled"
"texture_selected_enabled"
"texture_disabled_enabled"
"alwaysontop"
"bringtofrontonfocus"

SIZES/POINTS
"snaptolocation"
"size"
"maxsize"
"minsize"
"position"
"rectangle"

NUMERICAL (single number)
"tagid"
"taborder"
"tooltipdelay"
"movedistancebeforedrag"
"delaybeforedrag"
"clickdelay"
"dblclickdelay"
"alpha"
"height"
"width"
"top"
"left"

ENUMS
"tooltipdirection"
"dragbehavior"
"dropbehavior"

COLORS
"texture_base_overlaycolor"
"texture_mouseover_overlaycolor"
"texture_mousedown_overlaycolor"
"texture_selected_overlaycolor"
"texture_disabled_overlaycolor"
« Last Edit: December 12, 2009, 12:29:41 AM by EagleEye » Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« Reply #2 on: December 12, 2009, 12:10:54 AM »

Here is the actual loader code, for those interested in seeing how I'm setting it up.

Code:
#Region "Loader"
    ''' <summary>
    ''' Loads a control definition file where you can specify all of the parameters that define the look and feel of a control type.
    ''' </summary>
    ''' <param name="FileName"></param>
    ''' <remarks></remarks>
    Public Sub LoadControlDefinition(ByVal FileName As String)
        Try
            Dim TempText As String = FileIO.FileSystem.OpenTextFileReader(FileName).ReadToEnd
            Dim Reader As New IO.StringReader(TempText)
            Dim Line As String = ""
            While Line = Reader.ReadLine
                If Not Line.StartsWith("//") Then
                    While Line.Contains("//")
                        Line = Line.Substring(0, Line.LastIndexOf("//"))
                    End While
                    ParseLine(Line)
                End If
            End While
        Catch ex As Exception
            LogError("Error in " & System.Reflection.MethodInfo.GetCurrentMethod.DeclaringType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & ": " & ex.Message, DebugLevel.Severe)
        End Try
    End Sub

    Protected Overridable Function ParseLine(ByVal DefLine As String) As Boolean
        Try
            Dim Parts() As String = DefLine.Split("=")
            Dim S As String = Parts(1)
            Select Case Parts(0).Trim.ToLower
                Case "name"
                    Name = S
                Case "tagid"
                    TagID = Convert.ToInt64(S)
                Case "tagstring"
                    TagString = S
                Case "taborder"
                    TabOrder = Convert.ToInt64(S)
                Case "tooltip"
                    ToolTip = S
                Case "tooltipdelay"
                    TooltipDelay = Convert.ToInt16(S)
                Case "tooltipdirection"
                    Select Case S.ToLower
                        Case "abovecentered"
                            TooltipDirection = TooltipDirections.AboveCentered
                        Case "aboveleft"
                            TooltipDirection = TooltipDirections.AboveLeft
                        Case "aboveright"
                            TooltipDirection = TooltipDirections.AboveRight
                        Case "belowcentered"
                            TooltipDirection = TooltipDirections.BelowCentered
                        Case "belowleft"
                            TooltipDirection = TooltipDirections.BelowLeft
                        Case "belowright"
                            TooltipDirection = TooltipDirections.BelowRight
                        Case "left"
                            TooltipDirection = TooltipDirections.Left
                        Case "right"
                            TooltipDirection = TooltipDirections.Right
                    End Select
                Case "enabled"
                    Enabled = ParseBool(S)
                Case "allowfocus"
                    AllowFocus = ParseBool(S)
                Case "allowmouseover"
                    AllowMouseOver = ParseBool(S)
                Case "ismodal"
                    isModal = ParseBool(S)
                Case "suppressmodalinput"
                    SuppressInputWhileModal = ParseBool(S)
                Case "iscircular"
                    isCircular = ParseBool(S)
                Case "canbedragged"
                    Dim SubParts() = {}
                    SubParts = S.Split(",")
                    For i As Byte = 0 To SubParts.Length - 1
                        If i <= 3 Then CanBeDragged(i) = ParseBool(SubParts(i))
                    Next
                Case "dragbehavior"
                    Select Case S.ToLower
                        Case "donotallow"
                            DragBehavior = DragBehaviors.DoNotAllow
                        Case "dragwithinparent"
                            DragBehavior = DragBehaviors.DragWithinParent
                        Case "pluckfromparent"
                            DragBehavior = DragBehaviors.PluckFromParent
                    End Select
                    DragBehavior = ParseBool(S)
                Case "movedistancebeforedrag"
                    MoveDistanceBeforeDrag = ParseBool(S)
                Case "delaybeforedrag"
                    DelayBeforeDrag = Convert.ToInt16(S)
                Case "allowdroppedobjects"
                    AllowDroppedObjects = ParseBool(S)
                Case "dropbehavior"
                    Select Case S.ToLower
                        Case "constrainwithinparent"
                            DropBehavior = DropBehaviors.ConstrainWithinParent
                        Case "dropinplace"
                            DropBehavior = DropBehaviors.DropInPlace
                        Case "returntopositionbeforedrag"
                            DropBehavior = DropBehaviors.ReturnToPositionBeforeDrag
                        Case "snaptospecificlocation"
                            DropBehavior = DropBehaviors.SnapToSpecificLocation
                        Case "snaptotopleft"
                            DropBehavior = DropBehaviors.SnapToTopLeft
                    End Select
                Case "snaptolocation"
                    SnapToLocation = ParsePoint(S)
                Case "clickdelay"
                    ClickDelay = Convert.ToInt16(S)
                Case "dblclickdelay"
                    dblClickDelay = Convert.ToInt16(S)
                Case "size"
                    Size = ParsePoint(S)
                Case "maxsize"
                    MaxSize = ParsePoint(S)
                Case "minsize"
                    MinSize = ParsePoint(S)
                Case "position"
                    Position = ParsePoint(S)
                Case "alpha"
                    Alpha = Convert.ToSingle(S)
                Case "visible"
                    Visible = ParseBool(S)
                Case "texture_base"
                    Background.Base.Texture = S
                Case "texture_mouseover"
                    Background.MouseOver.Texture = S
                Case "texture_mousedown"
                    Background.MouseDown.Texture = S
                Case "texture_selected"
                    Background.Selected.Texture = S
                Case "texture_disabled"
                    Background.Disabled.Texture = S
                Case "texture_base_enabled"
                    Background.Base.Enabled = ParseBool(S)
                Case "texture_mouseover_enabled"
                    Background.MouseOver.Enabled = ParseBool(S)
                Case "texture_mousedown_enabled"
                    Background.MouseDown.Enabled = ParseBool(S)
                Case "texture_selected_enabled"
                    Background.Selected.Enabled = ParseBool(S)
                Case "texture_disabled_enabled"
                    Background.Disabled.Enabled = ParseBool(S)
                Case "texture_base_overlaycolor"
                    Background.Base.OverlayColor = ParseColor(S)
                Case "texture_mouseover_overlaycolor"
                    Background.MouseOver.OverlayColor = ParseColor(S)
                Case "texture_mousedown_overlaycolor"
                    Background.MouseDown.OverlayColor = ParseColor(S)
                Case "texture_selected_overlaycolor"
                    Background.Selected.OverlayColor = ParseColor(S)
                Case "texture_disabled_overlaycolor"
                    Background.Disabled.OverlayColor = ParseColor(S)
                Case "alwaysontop"
                    AlwaysOnTop = ParseBool(S)
                Case "bringtofrontonfocus"
                    BringToFrontOnFocus = ParseBool(S)
                Case "rectangle"
                    SetRectangle(ParseRect(S))
                Case "height"
                    Height = Convert.ToInt32(S)
                Case "width"
                    Width = Convert.ToInt32(S)
                Case "top"
                    Top = Convert.ToInt32(S)
                Case "left"
                    Left = Convert.ToInt32(S)
                Case Else
                    LogError("Error Parsing Control Definition Text line.  The line is as follows:" & vbCrLf & DefLine, DebugLevel.General)
            End Select
        Catch ex As Exception
            LogError("Error in " & System.Reflection.MethodInfo.GetCurrentMethod.DeclaringType.Name & "." & System.Reflection.MethodInfo.GetCurrentMethod.Name & ": " & ex.Message, DebugLevel.Severe)
            LogError("Error Parsing Control Definition Text line.  The line is as follows:" & vbCrLf & DefLine, DebugLevel.General)
            Return False
        End Try
    End Function

    Protected Function ParseBool(ByVal s As String) As Boolean
        Select Case s.Trim.ToLower
            Case "yes" Or "true" Or "1" Or "y"
                Return True
            Case "no" Or "false" Or "0" Or "n"
                Return False
        End Select
    End Function
    Protected Function ParsePoint(ByVal s As String) As Point
        Dim Parts() As String = s.Split(":")
        Return New Point(Parts(0), Parts(1))
    End Function
    Protected Function ParseRect(ByVal s As String) As Rectangle
        Dim Parts() As String = s.Split(":")
        Return New Rectangle(Convert.ToInt32(Parts(0).Trim), Convert.ToInt32(Parts(1).Trim), Convert.ToInt32(Parts(2).Trim), Convert.ToInt32(Parts(3).Trim))
    End Function
    Protected Function ParseColor(ByVal s As String) As GUIColor
        Dim C As New GUIColor
        Dim Parts() As String = s.Split(",")
        C.TVColor = New TV_COLOR(Convert.ToSingle(Parts(0)), Convert.ToSingle(Parts(1)), Convert.ToSingle(Parts(2)), Convert.ToSingle(Parts(3)))
        Return C
    End Function
#End Region

« Last Edit: December 12, 2009, 04:21:12 AM by EagleEye » Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
tagget
Customers
Community Member
*****
Posts: 243


« Reply #3 on: December 13, 2009, 04:17:39 PM »

Looks nice. Why not just use XML for the settings?
Logged
EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« Reply #4 on: December 14, 2009, 12:03:23 AM »

Looks nice. Why not just use XML for the settings?

A very good question!

There are numerous reasons.
1) XML is not easily human-readable or editable.
2) XML is bulky.
3) Some projects may have GUI developers who are not programmers, and I want to keep it simple for those types of people to alter these config files.
4) This is far easier. Smiley
Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
Eric
Customers
Community Member
*****
Posts: 804


« Reply #5 on: December 14, 2009, 09:39:42 PM »

5) XML is annoying as balls!
Logged
EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« Reply #6 on: December 17, 2009, 04:43:53 PM »

5) XML is annoying as balls!

*thumbs up*
Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
Zaknafein
Customers
Community Member
*****
Posts: 2940


WWW
« Reply #7 on: December 17, 2009, 05:02:40 PM »

I know you've already made your choice and written the code for your parser, but I'd like to point out less verbose alternatives to XML : YAML, SDL and JSON.

I'm using SDL extensively in Fez and even if I had to fix a couple bugs in their .NET API, it's still very recommendable. The language maps to .NET data structures flawlessly.
Logged

EagleEye
Customers
Community Member
*****
Posts: 345


WWW
« Reply #8 on: December 19, 2009, 02:03:00 PM »

I know you've already made your choice and written the code for your parser, but I'd like to point out less verbose alternatives to XML : YAML, SDL and JSON.

I'm using SDL extensively in Fez and even if I had to fix a couple bugs in their .NET API, it's still very recommendable. The language maps to .NET data structures flawlessly.

I probably fail on some level when it comes to this whole thing... I never even considered that there may be pre-written libs to deal with this sort of thing, and for that I definitely fail. Smiley

Thanks for pointing this out though... it may help someone else in the future who are looking for this sort of thing.  Smiley
Logged

Vermund - A Matter of Life and Death MMORPG
My TV Projects - EEGUI (A GUI for TV6.5 with .NET 2005+), Material Editor, tutorials, and more!
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks