• Categories

    Archives

  • GUI Editor: Part 1

    No Comments

    I have been doing more work on my GUI system. I intend on creating a GUI editor in the vein of the windows forms editor. To this I have added support for loading menus via XML. I am using RapidXML, created by Marcin Kalicinski (http://rapidxml.sourceforge.net/), as he claims it is the fastest free library in existence.

    Here is an example of initializing the position of the menu:

    <position>
    	<x>
    		<copy src="window_main.width"/>
    		<divide>2</divide>
    	</x>
    	<y>
    		<copy src="window_main.height"/>
    		<divide>2</divide>
    	</y>
    </position>
    

    Notice the font line. That is my XML scripting system. Inspired by Fallout New Vegas’s XML scripting system it allows for variable copying, math operations, and string concatenation, with extreme extensibility. Here is my format.xml file which documents and gives examples of all possible uses:

    <?xml version=\"1.0\" encoding=\"utf-8\"?>
    
    <ui>
    
    	<!-- math examples, must begin with the copy command -->
    	<mathnode>
    		<!--
    			funcitons available:
    				copy
    				add
    				subtract
    				multiply
    				divide
    				concat (for strings)
    					
    			all of these functions can have a static value passed in,
    			alternatively you can pull variables set set in the program
    			
    			this is done via the src attribute, the string passed in this
    			attribute is dereferenced from left to right in a c-esque fashion
    			
    			for example the string "this.position.x" will get the current item's
    			position.x value, to access the parent object use "this.parent.xxx",
    			to access a child object use "this.child(childname).xxx", same goes for
    			child effects "this.effect(effectname).xxx"
    			
    			on the top level one more function exists: element(elementname), it gets the first
    			element of the specified name that exists in the current menu
    			
    			the variables that can be accessed are all of the ones that are defined in
    			the xml document (position,scale,font,rotation,etc) with the exception of
    			flags
    		-->
    			 
    		<!-- access the window_main.width variable -->
    		<copy src="global" src="window_main.width"/>
    		
    		<!-- divide it by two -->
    		<divide>2</divide>
    		
    		<!-- add thirty -->
    		<add>30</add>
    		
    		<!-- these functions can also have nested scopes, for example (new scope must begin with the copy command) -->
    		<multiply>
    			<copy>25</copy>
    			<add src="a.b.something"/>
    			<divide src="b.f.somethingelse"/>
    		</multiply>
    	</mathnode>
    	<!-- mathnode's value is equal to: window_main.width / 2 + 30 * ((25 + a.b.something) / b.f.somethingelse) -->
    	 
    	<uielement name="myname" type="menu">
    		<position>
    			<x>10</x>
    			<y>10</y>
    		</position>
    		<scale>
    			<x>1</x>
    			<y>1</y>
    		</scale>
    		<rotation>
    			<z>0</z>
    		</rotation>
    		<blendcolor>ffffffff</blendcolor>
    		<enabled>true</enabled>
    		<active>true</active>
    		
    		<!--
    			the actionsize is the size that text placement is based upon as well as mouse interactions
    			usually overridden by the texture_main effect
    		-->
    		<actionsize>
    			<x>0</x>
    			<y>0</y>
    		</actionsize>
    		
    		<!-- texture effect should be first, as the action size is often set from them -->
    		
    		<uieffect name="texture_main" type="draw_texture">
    			<file>texture.png</file>
    			<blendcolor>ffffffff</blendcolor>
    			<sourcerect mode="texture"/>
    			<!--
    			<sourcerect mode="rect">
    				<t>0</t>
    				<l>0</l>
    				<b>10</b>
    				<r>10</r>
    			</sourcerect>
    			-->
    			<sourcecenter mode="sourcerect"/>
    			<!--
    			<sourcecenter mode="pos">
    				<x>0</x>
    				<y>0</y>
    			<sourcecenter>
    			-->
    			
    			<!-- sets the parent element's action rect to the sourcerect scaled by x and y -->
    			<setparentactionrect>
    				<x>1</x>
    				<y>1</y>
    			</setparentactionrect>0
    		</uieffect>
    		
    		<uieffect name="text_main" type="draw_text">
    			<font>Arial</font>
    			<color>ffffffff</color>
    			<!-- only use a valid combination of the flags, if they are present they are concidered to be in use -->
    			<drawflags r="" l="" c="" vt="" vb="" vc=""/>
    			<drawrect mode="actionsize"/>
    			<!--
    			<drawrect mode="rect">
    				<t>0</t>
    				<l>0</l>
    				<b>10</b>
    				<r>10</r>
    			</drawrect>
    			-->
    			<text>My Text</text>
    		</uieffect>
    		
    		<!-- child elements -->
    		
    		<uielement name="myname" type="alignment">
    			<!-- same stuff as above, with extra attributes -->
    			<posflags r="" l="" c="" vt="" vb="" vc=""/>
    			<padding>10</padding>
    			<offset>
    				<x>0</x>
    				<y>0</y>
    			</offset>
    			<direction>
    				<x>0</x>
    				<y>1</y>
    			</direction>
    		</uielement>
    		
    		<uielement name="myname" type="button">
    			<!-- same stuff as above, with extra attributes -->
    			<!-- another texture effect named texture_hover, shown when the mouse hovers over the button -->
    		</uielement>
    		
    		<uielement name="myname" type="checkbox">
    			<!-- same stuff as above, with extra attributes -->
    			<!-- another texture effect named texture_hover, shown when the mouse hovers over the button -->
    			<!-- another texture effect named texture_check, shown when the checkbox is checked -->
    			<checked>false</checked>
    		</uielement>
    		
    		<uielement name="myname" type="slider">
    			<!-- same stuff as above, with extra attributes -->
    			
    			<!-- the texture_handle must be defined AFTER the actionsize is set, meaning after texture_main -->
    			<texture_handle>texture.png</texture_handle>
    			<value>0.5</value>
    		</uielement>
    		
    		<!--
    			var_oscillate:
    				allows oscillation of a variable, the variable to be oscillated must be passed in
    				though the attribute "variable", as shown below, the available variables are:
    					position
    					scale
    					rotation
    		-->
    		<uieffect name="myname" type="var_oscillate" variable="position">
    			<wavelength>
    				<!-- for vector variables (position, scale) -->
    				<x>50</x>
    				<y>0</y>
    				<!-- for rotation just give the value -->
    				<!-- 10 -->
    			</wavelength>
    			<!-- frequency is in seconds -->
    			<frequency>5</frequency>
    			<!-- phaseshift must be defined after wavelength and frequency -->
    			<phaseshift>0</phaseshift>
    		</uieffect>
    		
    		<!--
    			transitions:
    				all transitions have "runflags" when determine when the transition is run,
    				if only one of the two flags is supplied then the transition will only run at that
    				specific time, but if both are supplied then when the transition concludes the target
    				and current states are swapped, allowing one transition decleration control entry and exit
    				gracefully
    		-->
    		
    		<!--
    			transition_lerp:
    				allows linear interpolation of a variable, this works very similarly to var_oscillate
    				described above, variable definition is identical
    		-->
    		<uieffect name="myname" type="transition_lerp" variable="scale">
    			<runflags onenter="" onexit=""/>
    			<duration>3</duration>
    			<target>
    				<!-- chaing scale to (1,1) so assume that it originated at a different value -->
    				<x>1</x>
    				<y>1</y>
    			</target>
    		</uieffect>
    	</uielement>
    
    </ui>
    

    The first section explains in detail how the math and variable system works, although it is likely that I will implement a math string parser via the shunting-yard algorithm to allow clean, single-line infix scripts (“parent.position.x*2” for example).

     

    Comment RSS

    No Responses to “GUI Editor: Part 1”

    Leave a Reply

  • Recent Posts

home login
content