programming

let's try some gui business

lately i've been pruning things down and putting some magic sugar in. i go back and forth how i feel on magic sugar, but today i am pro. i also got rid of the semicolons for no reason.

the magic sugar for today is the ability for an a single object container member to become the default for any appends to the container. the most useful and obvious one is for GlyphNodes->Childs. the magic sugar allows for you to skip out on specifying 'Childs'. in theory i could make it extra magic-tastic by comparing what you are trying to add as long as it was not ambiguous. the more determining factor is not parsing it in, but deciding whether a member container name should be saved out. instead of assuming i'll just always require an attribute that tells it to enable it or not.

below is an implementation of a mainmenu. there really is no difference between this and any other content. this could live in 3d or not, that's up to the viewport it lives in. even what an 'OnClick' or whatever is up to the viewport. raycasting is raycasting whether it is from a mouse moving around or from a dudes gun (well, if you implement it that way.)

all the big gui kids will tell you that you need a.. "complete separation of business logic and ui." well, they are wrong! ha! there is no reason to not mix code in for special cases. stuff like a menu begs for it because it is just so simple. splitting things up just adds excessive complexity.

a bunch of magic sugar also happens in the scope below ScriptFunctionCS. the object does a bunch of work to make it seem as if you are 'almost' a method of the object that the script is in. 'almost' in you'll need to use a this to access it. any other live variables will also magically be available too.

one other thing.. you'll notice a variable called file:/game_instance being used, but it is never specified. this would work like in php and passed into the file and used something like this..

page=new file://robote/pages/mainmenu.page?game_instance=teh_game_instance/page();

Code:
-----------------------------
robote/locales/guitext.locale

newGame
{
   english=[[New Game]]
   spanish=[[Nuevo Juego]]
   german=[[Neues Spiel]]
}

resumeGame
{
   english=[[Resume Game]]
   spanish=[[Continue]]
   german=[[setzen Sie Spiel fort]]
}

--------------------------
robote/pages/mainmenu.page

divider=new cli://gamebasis/code/DockPanel()
{
   Dock=[[Center]]

   new cli://gamebasis/code/Line()
   {
      {0 0}
      {100 0}
      StrokeColor=ptr file://gamebasis/styles/colors.style/black
   }
}

menuitem=new cli://gamebasis/code/Label()
{
   Text="Text Please!!!"
   FillColor=nullptr //-- this would not really save out, it's the default which means.. inherited
}

page=new cli://gamebasis/code/Page()
{
   new cli://gamebasis/styles/default.style
   {
      TextLocalizer=new gamebasis/code/TextLocalizer()
      {
         ReferenceLanguage=[[english]]
         TargetLanguage=file:/game_instance/settings/CurrentLanguage
         LocalePaths
         {
            ptr file://robote/locales/guitext.locale
         }
      }
   }

   new cli://gamebasis/code/DockPanel()
   {
      Dock=[[Center]]

      new cli://gamebasis/code/StackPanel()
      {
         VerticalSpacing=10

         new cli://gamebasis/code/TextStyling()
         {
            Size=50
            Font=gamebasis/fonts/fixedsys.font
            TextFillColor=ptr file://gamebasis/styles/colors.style/black
         }

         newGame=new file:/menuitem()
         {
            Text="New Game"
            OnClickScript=new cli://gamebasis/code/ScriptFunctionCS()
            {
               if(game_instance.NewGame())
               {
                  this.Parent.resumeGame.Visible=true;
                  this.Parent.saveGame.Visible=true;
               }
            }
         }

         resumeGame=new file:/menuitem()
         {
            Text="Resume Game"
            Visible=false
            OnClickScript=new cli://gamebasis/code/ScriptFunctionCS()
            {
               game_instance.ResumeGame();
            }
         }

         new file:/divider()

         loadGame=new file:/menuitem()
         {
            Text="Load Game"
            OnClickScript=new cli://gamebasis/code/ScriptFunctionCS()
            {
               game_instance.LoadGame();
            }
         }

         new file:/divider()

         saveGame=new file:/menuitem()
         {
            Text="Save Game"
            Visible=false;
            OnClickScript=new cli://gamebasis/code/ScriptFunctionCS()
            {
               game_instance.SaveGame();
            }
         }

         new file:/divider()

         exit=new file:/menuitem()
         {
            Text="Exit"
            OnClickScript=new cli://gamebasis/code/ScriptFunctionCS()
            {
               game_instance.Exit();
            }
         }

      }
   }

}


the way all the scripting business works is all arbitrary and depended on how the game works. it mearly is meant to just be glue. in theory you could put tons of logic in here, but you really don't want to because the code is compiled at runtime and who wants to debug anything complicated that way.