RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[RunUO 2.0 RC1] Gump Skin Core (TMSS 4 Sub-Component)

TMSTKSBK

Lord
Gump Skin Core (TMSS 4 Sub-Component)

[[EOL. Please refer to http://www.runuo.com/forums/custom-script-releases/86918-tmss-gump-skin-system-2-0-a.html]]

BaseSkin
(open skin standard) for developers.
- TMSS 4 Component (not required for use)

DEFINITELY DOES NOT WORK ON 1.0! Requires .NET 2.0 to run.

Version: 2.3

Changelog:
7-18-06: Upgrade to 2.0, including new XML method and BaseTMSkin, which includes required variables for implementations of the skin to be used on GumpList.
8-19-06: RC 0 released. This is the final concept for the skin base.
8-19-06: RC 1 released. This is the new final concept.
8-20-06: RC 2 released. Fixes some problems in extensibility of the system.

Introduction:
This is the core of my skins for TMSS 4. It is a fast, extensible method of skinning a system's gumps. Runtime is not memory or processor-intensive. Developers are able to create inherited classes to add variables as needed, with BaseSkin performing the save and load actions, and adding some additional core variables.

What it does is this:
1 - Dictionary to hold skins.
2 - Class to hold Skin variables (mebbe I should use a struct?)
3 - Dynamic XML Writer (no variable list req'd)
4 - Dynamic XML Reader
5 - Structs for ButtonInfo and WindowInfo -- to keep track of button appearance/location, and gump window appearance and location.

Further information:
Tutorial:
Code:
General implementation and use of BaseSkin.
 
 
Introduction:
 
BaseSkin is meant as an open skinning standard. This means that it may take on new features as time goes on, based on suggestions from community members.
 
BaseSkin will allow you to easily generate and utilize “.tskn” files containing variables for your system. You can then call these variables from your system to utilize the skin. The only requirement is that you create your own class inherited from BaseSkin. BaseSkin’s internal workings take care of save, load, and in-server storage.
 
Features:
•    Allows easy non-programmatic alteration of skins in any text editor, since all .tskn files are XML, allowing the end user to edit the skin without any special tools or knowledge.
•    Supports multiple windows with a “WindowInfo” struct.
•    Supports button information with a “ButtonInfo” struct.
•    Does not require any I/O work to implement.
•    Does not require user to restart server to implement changes.
 
Due to its nature, BaseSkin can be used to aid in setting up gump appearances during development, without the need to restart the server every five minutes. A simple command suffices to reset the skin, and thus, the gump.
 
 
Implementation:
 
Part 1 – Creating sub-skin:
In order to implement BaseSkin, you must create a sub-class inherited from BaseSkin. You do this in this manner:
 
public class MySkin : BaseSkin{ …
 
From this, you add a no-argument constructor, like so:
 
public MySkin() : base()
{…
 
If you wish to add any window information (separate gumps), you may do so now by saying:
 
this.WindowInfo.Add("MyWindow",new WindowInfo(15,25,200,380,9270));
 
The arguments here are: (Name, WindowInfo(x,y,w,h,bgid)).
 
You may also add any button info you like, with about the same arguments:
 
this.ButtonInfo.Add("SessionAddButton", new ButtonInfo( 203,252,80,25,ListButtonOverlay,"ADD"));
 
Again, this is:
Name, ButtonInfo(x,y,w,h,overlayID,text
ButtonInfo are set up to supply most information for a ImageTiledButton.
 
Next, you need to add whatever variables still remain to set up your gump. Mostly this will consist of IDs, X/Y, and W/H information.
 
Almost there – now you need to add the reload command. The template for this command can be found in the BaseSkin thread. The major change is that you need to specify “MySkin” as the type, as opposed to “TMSS4Skin”.
 
After this, simply save your file into whatever namespace you like, making sure that it has the “using Server.Gumps;” directive at the top.
 
Part 2 - Using in scripts:
The end use of BaseSkin is very simple. Simply pass in a “MySkin” object, and refer to the variables in the class. When the server is loaded, BaseSkin will load all .tskn files, and your skin will be populated with the correct values.
 
The Last Word:
Please spread the word about BaseSkin, and make suggestions for improvements. My intention is to make this a supremely accessible system for all RunUO developers to work with. If there’s something that irks you, or something that you really think should be there, let me know, and we will discuss possible solutions.


This particular implementation writes the skin data out in XML format, which allows you to open it in any text editor and poke elements around.

Note that you can really fubar the XML reader if you change the variable count inbetween write and read. You can insert variables manually if you want to keep the skin. The element name is the same as the variable name. Keeps things simple.

<You can then save it, and, with the server still running, type the command "[rlskin" to reload the skin. Then whatever gump is affected will reflect the changes made to the skin (when re-opened).> This command was taken out, but is pretty easily implemented for your system. Just call the LoadSkin method. I will not be supporting your conversions to systems unless I'm in a really good mood.

You will need to implement a custom method, which looks like this:
Code:
[Usage("[rlskin or [rlskin *name*")]
        [Description("Reloads all skins.")]
        public static void LMS_OnCommand(CommandEventArgs e)
        {
            string which = "";
            if (e.Arguments.Length > 0)
            {
                try { which = e.Arguments[0]; }
                catch (Exception ex)
                { Console.WriteLine("Invalid arguments. " + ex); }
            }
            if (which != "")
            {
                try { SkinHelper.LoadSkin(which, typeof(TMSS4Skin), true); }
                catch (Exception ex) { Console.WriteLine("Invalid skin name argument: " + ex); }
            }
            else
            {
                try
                {
                    DirectoryInfo di = new DirectoryInfo("TMSS/Data/Skins");
                    foreach (FileInfo f in di.GetFiles())
                    {
                        if( f.Extension == ".tskn" )
                            SkinHelper.LoadSkin(f.Name.Remove(f.Name.IndexOf(".tskn"),5), typeof(TMSS4Skin), true);
                    }
                }
                catch (Exception ex)
                {
                    SystemWrite("Error when reloading a skin. "+ex);
                }
            }
            //LoadSkin(SkillSettings.CCSkinName, true);
        }
If some things in there don't compile, they're probably TMSS 4 specific.

Performance Summary:
Non-Save Operations: O( 1 )
Save: O( n ) <-- grrrr....

Plans:
Add support for in-game customization of the skin. Not quite there yet, but I'm working on it.

How you actually do the implementation of the skin is up to you. What follows is my complete file, including variables and whatnot.
Code:
using System;
using System.Collections;
using System.Text;
using System.Xml;
using System.IO;
using System.Data;
using System.Reflection;
using Server.Commands;
using Server.Gumps;
using System.Collections.Generic;
//Computer meus nefandus est.
namespace Server.TMSS
{
    #region TMSS4 Skin Class
    public class TMSS4Skin : BaseSkin
    {
        //This is almost the entire class.
        //All "operations" are done in the SkinHelper
        #region Variables        
        //Backgrounds
        public int ProfileButtonW = 140;
        public int ProfileButtonH = 42;
        public int FinishButtonW = 65;
        public int FinishButtonH = 25;
        public int PrevButtonMW = 80;
        public int PrevButtonMH = 25;
        public int NextButtonMW = 80;
        public int NextButtonMH = 25;
        public int PrevButtonSW = 80;
        public int PrevButtonSH = 25;
        public int NextButtonSW = 80;
        public int NextButtonSH = 25;
        public int SelectW = 425;
        public int SelectH = 20;
        //Lists:
        public int ProfileX = 38;
        public int ProfileY = 38;
        public int RemoveX = 15;
        public int RemoveY = 90;
        public int AddX = 25;
        public int AddY = 365;
        public int UsedMaxX = 45;
        public int UsedMaxY = 360;
        public int FinishButtonX = 38;
        public int FinishButtonY = 263;
        public int BarMHX = 35;
        public int BarMHY = 35;
        public int BarMVX = 35;
        public int BarMVY = 35;
        public int BarSHX = 65;
        public int BarSHY = 95;
        public int BarSVX = 470;
        public int BarSVY = 95;
        public int BarMHW = 136;
        public int BarMHH = 3;
        public int BarMVH = 208;
        public int BarMVW = 3;
        public int BarSHW = 405;
        public int BarSHH = 2;
        public int PrevButtonMX = 120;
        public int PrevButtonMY = 330;
        public int PrevButtonSX = 522;
        public int PrevButtonSY = 330;
        public int NextButtonMX = 120;
        public int NextButtonMY = 358;
        public int NextButtonSX = 605;
        public int NextButtonSY = 330;
        public int SelectStartX = 45;
        public int SelectStartY = 100;
        public int CheckTopX = 405;
        public int CheckTopY = 52;
        public int NameLabelX = 80;
        public int NameLabelY = 50;
        public int WeightLabelX = 215;
        public int WeightLabelY = 65;
        public int PointsLabelX = 65;
        public int PointsLabelY = 320;
        public int Divider1X = 190;
        public int Divider1Y = 60;
        public int Divider2X = 290;
        public int Divider2Y = 60;
        public int Divider3X = 390;
        public int Divider3Y = 60;
        public int SelectTitleX = 80;
        public int SelectTitleY = 45;
        public int TMSSX = 345;
        public int TMSSY = 345;
        public int HelpLabelX = 35;
        public int HelpLabelY = 10;
        public int HelpLabelW = 450;
        public int HelpLabelH = 45;
        public int TMSSHue = 1152;
 
        //Deltas:
        public int ProfileDelta = 25;
        public int SpaceMainSele = 5;
        public int SpaceSeleHelp = 5;
        public int SpacerBase = 15;
        public int SkillSpacer = 5;
        public int ProfileSpacer = 3;
        public int RemoveSpacer = 15;
        public int SelectInset = 20;        
 
        //Icons/Buttons
        //IconM is an item. Default is the TMSS skillstone.
        public int IconMColor = 96;
        public int IconMID = 3805;
        public int IconMX = 0;
        public int IconMY = 0;
        public bool IconMOn = true;
        //IconS is an image, not an item.
        public int IconSID = 2245;
        public int IconSX = 15;
        public int IconSY = 15;
        public bool IconSOn = true;
        //IconH is also an image.
        public int IconHID = 22153;
        public int IconHX = 14;
        public int IconHY = 12;
        public bool IconHOn = true;
        //Generic button:
        public int genericID = 2488;
        //Add/removes
        public int removeID = 2510;
        public int addID = 2511;
        //Button overlay
        public int ProfileNormalID = 3004;
        public int ProfileUsedID = 2604;
        //Normal Button:
        public int ButtonOverlay = 3004;
        public int ButtonUnderID = 247;
        public int ButtonUnderIDPress = 248;
        //Arrows for profiles
        public int ArrowSide = 2087;
        public int ArrowDown = 2086;
        //Checkbox IDs:
        public int SelectUp = 2474;
        public int SelectDn = 9730;
        //Select bar
        public int SelectUnderlay = 9385;
 
        //Labels:
        public string MasterLabel = "Select a Category:";
        public string PrevTextM = "PREV";
        public string PrevTextS = "PREV";
        public string NextTextM = "NEXT";
        public string NextTextS = "NEXT";
        public string ProfileSuffix = "";
        public string ProfilePrefix = " - ";
        public string NameLabel = "Name:";
        public string WeightLabel = "Weight:";
        public string PointsLabel = "Points:";
        public string MaxLabel = "Max: ";
        public string HelpLabel = "Help: ";
        public string FinishLabel = "Finish";
        public string AddLabel = "ADD";
 
        //Hues
        public int ProfileHue = 1152;
        public int ProfileUseText = 1358;        
 
        //IDs:
        public int DividerID = 2700;
        public int MasterLineV = 2700;
        public int MasterLineH = 2701;
        public int SelectLineV = 2700;
        public int SelectLineH = 2701;
        public int genericSelectUp = 2474;
        public int genericSelectDn = 2118;
        public bool HelpOn = true;
        #endregion
 
        public TMSS4Skin() : base() 
        {
            this.WindowInfo.Add( "Master", new WindowInfo( 15, 25, 200, 380, 9270 ) );
            this.WindowInfo.Add("Underbar", new WindowInfo(215, 405, 500, 70, 9270));
            this.WindowInfo.Add("Control", new WindowInfo(215, 25, 500, 380, 9270));
            this.ButtonInfo.Add("SessionAddButton", new ButtonInfo( 203,252,80,25,ListButtonOverlay,"ADD"));
            this.ButtonInfo.Add("StatAddButton", new ButtonInfo(366, 188, 80, 25, ListButtonOverlay, "ADD"));
        }
        public TMSS4Skin(string name) : base( name ){}
 
        internal int GetCoord(string gumptype, string coord)
        {
            WindowInfo inf = WindowInfo[gumptype];
            switch (coord)
            { 
                case "X":
                    return inf.X;
                case "Y":
                    return inf.Y;
                case "W":
                    return inf.W;
                case "H":
                    return inf.H;
                default:
                    return -1;
            }
        }
    }
    #endregion    
}
 

Attachments

  • BaseSkin.cs
    11.3 KB · Views: 118

TMSTKSBK

Lord
I try :-\. This is actually supposed to be used in conjunction with the Distributed Gump System (currently Distributed Control Center), which I have not yet clobbered to the point of wanting to release...
 

TMSTKSBK

Lord
v2.0b released. Now has a BaseTMSkin class to define required variables. Also includes structs WindowInfo and ButtonInfo to define sub-windows and super buttons.
 

TMSTKSBK

Lord
Ok. Here's a release that actually works with something besides TMSS4. It's generic, which allows other devs to move stuff around as necessary, and actually create other types of skin.

DO NOT make modifications to the BaseSkin class. The BaseSkin class is required for the GumpList script, and should be left alone, unless you're configuring a GumpList. Basically don't add or remove variables from the class. It is intended as an open standard, but please don't abuse the "openness" of the offering. Instead, feel free to discuss possible additions or alterations to the standard.
 
Top