Skin editor proposal - long post

Discussion regarding the development of CEGUI itself - as opposed to questions about CEGUI usage that should be in the help forums.

Moderators: CEGUI MVP, CEGUI Team

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Skin editor proposal - long post

Postby scriptkid » Thu May 03, 2007 16:46

This post proposes a design for a skin editor for the CEGUI system. Please read it as a list of suggestions and ideas, rather than a formal design document. Such a writing can be a next step after a discussion in this thread. Note that I have not done any coding yet, not even prototyping. So this post is not limited by any technical knowledge yet ;)

Abstract
For a first version it is suggested to be able to edit and create files based on the current Falagard C++ setup, as can be found in the ‘WindowRenderSets’ directory. By looking in that directory, a hard-coded list of editable widget types can be created.

Communication with CEGUI
We can use (instantiate) the Falagard classes and use setters and getters, so that we actually build the looknfeel within CEGUI itself. This has (like the Layout- and Imageset editors) the advantage or having an actual CEGUI preview. Besides that, the falagard objects are able to serialize themselves to a .looknfeel file with the ‘writeXMLToStream’ method, which is rather powerful. We can use the knowlegde of the Falagard.XSD file within this utility, without actually reading that file itself.

Most logic has to be programmed anyway, and besides that the XSD file is not subject to modifications that likely. But we might look into (existing) utilities to represent an XSD file in memory with easy query functionality. That would reduce some copying of XSD ‘stuff’ to code.

Limitations
With this editor it is not possible (yet) to define new widgets, such as a Tree or an Animation to name a few. As mentioned in the abstract, users can only edit widgets which have a current C++ counterpart.

Overview
Based on initial research the following image shows a rough overview of a possible application:
Image

Creating a new looknfeel
When adding a looknfeel, the user is prompted for a name for it, such as “MyLook”. From now on, each added widget will automatically use this name + “/”.as its own name. As soon as a new looknfeel is created, an array of buttons will be added to a panel. By clicking such a button, the corresponding widget can be edited.

Loading an existing looknfeel
To load a file, we can pass it to the ‘WidgetLookManager::parseLookNFeelSpecification’ method, and then query it using a (new) ‘WidgetLookManager::getWidgetLookIterator’ method. From that query we can add a button array (see previous paragraph) with all the available widgets. Widget types which are not available yet can be marked in red or something.

Saving a looknfeel
The C++ call ‘writeXmlToStream’ can be used to serialize the current setup to a .looknfeel file.

Editing a widget
My first idea was to show a tree representing the looknfeel, and be able to edit settings via a grid. However a setting is very often more then just a Name, Value pair. For example a TextComponent defines an Area which is a componentAreaType. This block defines a choice of dimension types. Next, those choices themselves might contain sequences. This does not fit within a grid, and in order to avoid a very complex nested system of editing panels, a different apprauch was come up with…

Rich XML
Another option is to use a kind of “rich” XML edit panel, which is a read-only panel, but accepts user input through double mouse clicks and line browsing through the arrow keys. These mouse clicks will invoke helper dialogs, which will assure a safe -read: less error prone- way of editing the XML. However the user can still see what’s going on ‘under water’. Maybe there should be a ‘hardcore’ option which allows users to manually edit the XML for whatever reason. This panel will show the looknfeel XML contents of the currently edited widget (not the entire stream).

This panel has the following properties:
*Read-only (not mandatory).
*Coloured values (text between “’s), which clearly show that they can be modified.
*Ability to double-click these coloured texts in order to edit them. Editing is context sensitive; when the value is a ‘free’ value, an input dialog box is opened. When the text belongs to a choice-field (‘true/false’ or ‘add/subtract/multiply/divide’ or such) double-clicking will result in an option list dialog box. Choices are explained in detail in the “Choices” paragraph.
*A smart way to decide in which definition or block the cursor is currently residing. We can use the information from the XSD file in order to do this.
*The ability to add elements or blocks, based on the current position in the definition.

XML Editing Example
(note that i had coloured all values but this seems not to work on the forum...) This chapter will hopefully make clear –through a sample- how I see the XML editing panel work. For this example we start with a new looknfeel names “MyLook” and we start by editing the Button, which we initially call MyButton.

Now based on the Falagard.xsd file we determine what we may add, and come up with an initial XML content. Rule 1: When an element is optional (‘minocurs=0’), it will be added as a ‘Double-click here to add this’ line.

Code: Select all

<WidgetLook name="MyLook/MyButton">
   [Double-click here to add a property definition]
   [Double-click here to add a property link definition]
   [Double-click here to add a property type]
   [Double-click here to add a named area]
   [Double-click here to add a child widget]
   [Double-click here to add an imagery section]
   [Double-click here to add a state imagery section]
</WidgetLook>


Now we add a property definition by clicking on the first line. The XML changes to:

Code: Select all

<WidgetLook name="MyLook/MyButton">
<PropertyDefinition name="Nameless" initialValue="" redrawOnWrite="false" redrawOnWrite="false" />
   [Double-click  here to add another property definition]
   [Double-click  here to add a property link definition]
   [Double-click  here to add a property type]
   [Double-click  here to add a named area]
   [Double-click  here to add a child widget]
   [Double-click  here to add an imagery section]
   [Double-click  here to add a state imagery section]
</WidgetLook>


Rule 2: we will use the default values for element attributes as found in the .XSD file. Rule 3: when an added line is part of a sequence, we add the option for another line of the same type.

Let’s now add an Imagery Section for the ‘hover’ state of the button. This is a bit more advanced:

Step 1: double-clicking the Imagery Section expands with the optional sub-tags.

Code: Select all

<WidgetLook name="MyLook/MyButton">
<PropertyDefinition name="Nameless" initialValue="" redrawOnWrite="true" redrawOnWrite="true" />
   [Double-click here to add another property definition]
   [Double-click here to add a property link definition]
   [Double-click here to add a property type]
   [Double-click here to add a named area]
   [Double-click here to add a child widget]
   <ImagerySection name="hover">
      [Double-click here to select a colour type]
      [Double-click here to add a FrameComponent definition]
      [Double-click here to add a ImageryComponent definition]
      [Double-click here to add a TextComponent definition]
   </ImagerySection>
   [Double-click here to add a state imagery section]
</WidgetLook>


Step 2: double-clicking the ImageryComponent Section expands too. Note that required options (such as the Area) are automatically added and don’t need be double-clicked in order to create, since that would invoke a needless extra step.

Code: Select all

<WidgetLook name="MyLook/MyButton">
<PropertyDefinition name="Nameless" initialValue="" redrawOnWrite="true" redrawOnWrite="true" />
   [Double-click here to add another property definition]
   [Double-click here to add a property link definition]
   [Double-click here to add a property type]
   [Double-click here to add a named area]
   [Double-click here to add a child widget]
   <ImagerySection name="label">
      [Double-click here to choose a colour type]
      [Double-click here to add a FrameComponent definition]
      <ImageryComponent>
         <Area>
            [Double-click here to choose a dimension type]
         </Area>
         [Double-click here to choose an image type]
         [Double-click here to choose a colour type]
         [Double-click here to choose a vertical format type]
         [Double-click here to choose a horizontal format type]
      </ImageryComponent>
      <!-- Rule 3: Again note the ‘another’ line 
      [Double-click here to add another ImageryComponent definition]
      [Double-click here to add a TextComponent definition]
   </ImagerySection>
   [Double-click here to add a state imagery section]
</WidgetLook>


We double-click the dimension choice (see paragraph on choices), and choose the ‘dimensionType’ instead of the ‘settingByPropertyType’ option (both found in the XSD). This will automatically expand 4 elements with their default values. Since the dimension type’s attribute (dimensionTypeEnum) is also a choice value by it selves, we default to the first option which is ‘LeftEdge’. I consider this defaulting as ‘Rule 4’.

Code: Select all

<WidgetLook name="MyLook/MyButton">
<PropertyDefinition name="Nameless" initialValue="" redrawOnWrite="true" redrawOnWrite="true" />
   [Double-click  here to add another property definition]
   [Double-click  here to add a property link definition]
   [Double-click  here to add a property type]
   [Double-click  here to add a named area]
   [Double-click  here to add a child widget]
   <ImagerySection name="label">
      [Double-click  here to select a colour type]
      [Double-click  here to add a FrameComponent definition]
      <ImageryComponent>
         <Area>
            <!-- Rule 4: default to the first option
            <Dim type="LeftEdge">
               <!-- Rule 1: default arguments
               <UnifiedDim scale="1" offset="0" />                               
            </Dim>
            <!—- Here we show changed values
            <Dim type="TopEdge">
               <ImageDim imageset="WindowsLook" image="ButtonHoverTop" dimension="Height" />
            </Dim>
            <Dim type="RightEdge">
               <UnifiedDim scale="1" type="RightEdge">
               <!—- Another nested option
                  <DimOperator op="Subtract">
                     <ImageDim  imageset="WindowsLook" image="ButtonHoverRight" dimension="Width" />
                  </DimOperator>
                  [Double-click  here to add another DimOperator]
               </UnifiedDim>
            </Dim>
            <Dim type="BottomEdge">
               <UnifiedDim scale="1" type="BottomEdge">
                  [Double-click  here to add a DimOperator]
               </UnifiedDim>
            </Dim>
         </Area>
         [Double-click here to choose an image type]
         [Double-click here to choose a colour type]
         [Double-click here to choose a vertical format type]
         [Double-click here to choose a horizontal format type]
      </ImageryComponent>
      [Double-click  here to add a TextComponent definition]
   </ImagerySection>
   [Double-click  here to add a state imagery section]
</WidgetLook>


And so on…

We can–for extra robustness- validate the current XML contents against the XSD file after a modification and present the user with warnings and errors. However -because of the readonly-ness of the panel- this should only occur in case of bugs in the tool’s editing capabilities. So it’s a good for testing purposes and bug hunting.

Choice and restrictions
Each “Double click to choose …” line corresponds to an input dialog which requests the user to make a choice. The following choice types have the following options, which will just be shown as strings to the user:

*ComponentAreaType: { Dim(dimensionType), AreaProperty(settingByPropertyType)}

*Dimension type: { UnifiedDim (unifiedDimType), AbsoluteDim (absoluteDimType), ImageDim(imageDimType), WidgetDim(widgetDimType), FontDim(fontDimType), propertyDim(propertyDimType)}

*Colour type: { Colour(colourType), Colours(colourRectType), ColourProperty(settingByPropertyType), ColourRectProperty(settingByPropertyType)}

*Image type : { Image(imageType), ImageProperty(settingByPropertyType)}

*Horizontal Format type: { HorzFormat (horzFormatType), HorzFormatProperty (settingByPropertyType)}

*Vertical Format type: { VertFormat(vertFormatType), VertFormatProperty(settingByPropertyType)}[/list]

After selecting an option, the editor will replace the XML line to an actual tag or block. For example when choosing ‘HorzFormat (horzFormatType)’ from the Horizontal Format type choice, this XML line will be inserted:

Code: Select all

<HorzFormat type="LeftAligned" />


Again note the default value (LeftAligned) for the ‘type’ attribute’s choice(horzFormatEnum).

Besides choices, there are also limitations such as enumeration values. This list is not pasted in here, because it’s quite big and very readable in XSD format. Just open the Falard.xsd file and look at this line and below:

Code: Select all

<xsd:simpleType name="propertyDimensionTypeEnum">


Discussion
Besides (of course) everything written above, there are some remaining points of discussion:

*When attributes are optional, such as ‘RedrawOnWrite’ in a PropertyDefinition, should we write them or not? The example shows then sometimes, just based on an existing (WindowsLook) file. Optional attributes could be marked in a different colour.
* …

Required CEGUI code changes
Probably independent of the actual implementation we choose, some changes are required to CEGUI itself in order to help querying the Falagard system a little better:

*Some Falagard classes should be enhanced with iterators on their privately defined elements. For example a ‘getImagerySectionIterator()’ in the ‘WidgetLookFeel’ class. And some more of those.
* …

Conclusion
You have just read my initial thought written down during a short holiday. Please comment on it, ask questions and so on. Thanks for your time! :-)

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Re: Skin editor proposal - long post

Postby Pompei2 » Thu May 03, 2007 22:35

here are the points that went trough my head while reading your post:

Split Files:
I'm a person that hates editing very big files - like TaharezLook.looknfeel. You just can't find what you're looking for within these thousand lines.So while creating my skin, I chose a different approach: create one looknfeel file for every widget. Even if not everybody thinks like me, I think it would be nice to have an option to choose this while saving, or maybe a "Export to [multiples|split] files ..." entry in the File menu. But it's not vital.

Multiple widgets:
I think you should integrate the nice falagard feature that is to be able to have multiple widgets of the same type, like TaharezLook has two progress bars I think. So one should be able to "create a new widget", based on another one.

Rich XML:
scriptkid wrote:Maybe there should be a ‘hardcore’ option which allows users to manually edit the XML for whatever reason.

Definitely ! the main reason is that (if you know what you do) writing this yourself is MUCH quicker then clicking, clicking, typing, clicking, clicking, ...
some kind of live-update would then be cool, and maybe live syntax checking like in most office programs ... I'm dreaming :)
A second reason is that using some missing/buggy feature (missing/buggy in the skin editor, not in CEGUI) would become very hard if there is no such 'hardcore' option !

Discussion
scriptkid wrote:*When attributes are optional, such as ‘RedrawOnWrite’ in a PropertyDefinition, should we write them or not? The example shows then sometimes, just based on an existing (WindowsLook) file. Optional attributes could be marked in a different colour.

To fully write them would be a waste of place, to not write them would result in a lot of users ot even knowing about them ... So I suggest to write the half of them :) maybe write a "..." that expands or opens a dialog when clicked ?

Required CEGUI code changes
scriptkid wrote:Probably independent of the actual implementation we choose, some changes are required to CEGUI itself in order to help querying the Falagard system a little better.

The only thing I'd like to add here is that it would be really really nice to release an "official" version between 0.5 and 0.6 when these changes are done, maybe a 0.5.1 ? The reason: That every linux user with an online-updating distribution can keep their CEGUI installed from the distribution instead of svn. I can't really explain what I mean here, sorry :)

General:
Ah, and I would suggest a single-click to choose, and the cursor becoming a hand when hovering (just like a link in a web browser), that is kinda quicker and so your finger won't get overkilled :P

And don't forget about teh .scheme files, you haven't said one word about them ! their design could go together with my two questions about multiple widgets and split files.

Thanks for the reading, too.

PS: all these suggestions are not in my personal interest, as I will (hopefully) be finished with writing my skin before this editor comes out. It's just based on my experience.

User avatar
Taharez
Not too shy to talk
Not too shy to talk
Posts: 30
Joined: Mon Mar 07, 2005 19:06
Location: Sweden
Contact:

Postby Taharez » Fri May 04, 2007 07:39

Sounds pretty good so far scriptkid!

I have to agree with Pompei2, especially about the direct XML editing. I'm quite used to editing the files in Visual Studio now (which has syntax highlighting, auto-complete, formatting, and such nice features), and I do it pretty quickly. I imagine most existing users also would think a click and choose approach would be too slow compared to manual editing. This is not to say it would be a great feature for new users, I really think it will get more people into building their own skins.

Regarding optional attributes, if there were no user interface restrictions I'd like something like what Pompei2 suggests here too, a "..." row which displays a list of possibilities on mouse hover.

As for splitting files, I think having a file for every widget is a bit of an overkill; the editor could just display the xml for the current widget.

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Postby scriptkid » Fri May 04, 2007 10:08

Hi,

thanks for the replies so far!

About the:

Split files
You are right, and i already mentioned that the XML panel will show the current widget only, in order to avoid the clutter. I think that when an editor does the splitting when editing widgets, this is good enough, no?

Multiple widgets
Good one. So in stead of populating the left panel with all possible widgets, adding widgets might change to: Start a new looknfeel, but instead of creating one of each widget, this should be manually. So the user chooses "add widget" and then selects a base class, like "cegui/scrollbar" + a name. Something like that? This isn't too bad either since i can imagine users creating a basic looknfeel with only a few widgets...

Rich XML
Good that you both like the mix of safe- and hardcode editing. Then there is always a choice at least. Live updating / syntax checking is possible by validating the widget's XML against the XSD. But maybe not for a first version. But as i said, maybe it should be in a first version for bug hunting and such...

New release
You mean distributions like Ubuntu right, which only allow releases? Sounds fair to me :)

General
Okay so the double clicking becomes a single click link, like a browser. Good idea!

Optional attributes
As a rule we can always write the required ones, and indeed click something (like the ...) to open a submenu (like right-clicking) where the user can select one of the optional attributes. By selecting it the xml will be updated. We can still use a different colour to distinguish required and optional ones though.

I forgot to mention scheme files. It shouldn't be too hard to add a 'create scheme' option into the skin editor. It will just grab the name you choose and all currently created widgets and their required fonts and images, and writes a .scheme file.

Seems that we can get somewhere :)

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Fri May 04, 2007 13:49

hey ho,

Split files:
sounds fair. But anyways 'd like a export to multiple files "special" function, but this could be added as a nice to have gimmick at the end.

New Release:
I was thinking of gentoo (witch I'm running), as I don't know ubuntu, but ok nice that you agree :)

Rich XML:
That was a REALLY good idea of you, maybe the best one in the whole document. It would be similar to (even better than) the Warcraft 3 campaign editor - Their maps have (powerful) scripting abilities that ware integrated into the editor a bit like this, but withoute really seing the code ... I#ll post a screenshot if you don't know what i mean :) It's very good for beginners, the proof: my lil bro learned programming trough this :P

I have nothing more to add, it all sounds really good !

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Postby scriptkid » Fri May 04, 2007 14:05

Okay i get the motivation for the splitting :) But i wonder how the editor should load them. I mean how would it know which files belong to a requested looknfeel. By looking at filenames containing a given name or something? Or using an editor-only 'meta' file with this info?

Hehe thanks for the compliments about the rich xml, however i am not sure whether that would be the correct word. "Rich" -as in "rich text" implies an "xml ++" or something; maybe "smart xml panel" would be a better word. Not important at this moment anyway ;)

I only used the Starcraft editor for a bit a looong time ago. Feel free to post a screen :)

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Fri May 04, 2007 18:54

About the split files, and load/save in general, I think it would be good to use .scheme files as "main" files (to load/save), as they contain all informations about the skin, including the looknfeel files and mappings ! maybe there could then be a "Import ..." and "Export ..." function that handles single .looknfeel files.
Hey I got an idea :P export could open a dialog box with a list of all widgets and a checkbox for each, where the user chooses witch ones to export to the looknfeel file. this would kinda solve the split files problem.


A screenshot of the WC3 script editor (found on google, as I'm too lazy to start the editor etc.:P) The main part is the one noted with a 7. And here another one that represents a more complex script with if's, loops, etc.
Sorry, it's in german. But if you doubleclick one node, a dialog box opens with the same text as you see here, but the variable parts are like hyperlinks, when you click on them you get a input dialog - much like the "ultra-xml-panel" :P

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Postby scriptkid » Sat May 05, 2007 18:22

Using a .scheme files to collect all widgets sounds like an idea, but then there might be -using your idea- a difference between the scheme and the looknfeel. For example when a user only selects half of its widgets to export, the next time opening the .scheme file will result in loading all others too, right? While the looknfeel contains less widgets then the scheme file...

Thanks for the screens; i get the idea. I used to work with such a tool myself (not game related). A kind-of visual way of coding :) Or :-( maybe...? ;)

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Sun May 06, 2007 11:53

Hmmm I think when the user 'exports' them, he knows that he isn't saving to the "same" file but to a different one that he might not edit again, or am I wrong/missunderstood you ?

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Postby scriptkid » Sun May 06, 2007 15:12

Okay so the user exports a .looknfeel and a .scheme as a pair? Then it should be fine :)

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Sun May 06, 2007 18:17

yup, that's it ;)

User avatar
jacmoe
Just can't stay away
Just can't stay away
Posts: 136
Joined: Sun Apr 03, 2005 14:18
Location: Holbaek, Denmark
Contact:

Postby jacmoe » Thu May 10, 2007 18:53

Looking forward to this editor! :)

However, I feel for drumicube who is feeling left alone with the CEImageSetEditor..

I this going to be the next generation of that tool?

User avatar
scriptkid
Home away from home
Home away from home
Posts: 1178
Joined: Wed Jan 12, 2005 12:06
Location: The Hague, The Netherlands
Contact:

Postby scriptkid » Fri May 11, 2007 11:44

No no,

this tool will be another tool, next to the existing layout- and imageset editors. Maybe to ease the workflow we might integrate some functionality in the future, which is another point of discussion at the moment.

So it won't replace drumicube's good work! :)


Return to “CEGUI Library Development Discussion”

Who is online

Users browsing this forum: No registered users and 3 guests