Page 1 of 1

Tool API/Foundation

Posted: Sat Jun 23, 2007 12:15
by scriptkid
Hi,

as mentioned a while ago in a project update thread, the focus will be put on tools in the future. This posts presents some thoughts which are the result of earlier discussion within the team and users.

Especially since we have some new users on board who seem to be eager to get their hands dirty on some serious tool coding! :)

The general idea is that we need a sort of API/Framework/Foundation on which all CEGUI tools should rely, so that -in a perfect situation- starting a new tool could be as simple as:

Code: Select all

class CMyTool: public CEGUITool ...


Now besides the discussion whether we need one tool per problem (like it is now) or one 'solution', both situations would benefit from using a base layer.

Such a layer should include the following (note that some are already in place in the current editors):
-Iterating and (un)loading of CEGUI files;
-Saving and (re) loading of user created content;
-Managing resource groups to allow for projects who use different resource directories;
-Changing / Selecting renderer and imageset codec;
-Integration with the 'property finder' utility which was recently created;
-A property change listener system. This way, listeners can be added so that sub-systems can easily get notified about changes in a different part. Think a repaint of a layout when an imageset changes.

The advantage of CEGUI's property system is mainly that it defines a very generic way to change an object's attributes, no matter what it actually is. So don't expect this layer to become very big. See it more as handy collection of stuff to interact with CEGUI.

Any thoughts and suggestions are more then welcome! :)

Re: Tool API/Foundation

Posted: Sat Jun 23, 2007 17:05
by Rackle
Each resource file (.layout, .looknfeel, .imageset, and .scheme) should contain a version tag:

Code: Select all

<?xml version="1.0" ?>
<GUILayout version="1.1">
...


Code: Select all

<?xml version="1.0" ?>
<GUIScheme Name="WindowsLookSkin" version="1.1">
...


to allow the creation of an "update" tool. I don't think the contents of these files has changed much, with the .layout being the only exception.


scriptkid wrote:Now besides the discussion whether we need one tool per problem (like it is now) or one 'solution'


I advocate a separation from the interface of the tool and its functionality, to allow code reuse. For example the Python script to update .layout files could be recoded in C++ such that it would allow the creation of a command-line (DOS) tool, a GUI tool with a file chooser, as well as callable within a user-created program:

Code: Select all

try
{
  loadWindowLayout("MyLayout.layout");
}
catch(Exception &e)
{
  try
  {
    if(exception for wrong layout version)
    {
        CEGUI::Tools::getSingleton().getLayoutUpdate().updateLayout("MyLayout.layout");
        loadWindowLayout("MyLayout.layout");
    }
    else
      display e.getMessage()
  }
  catch(Exception &e)
  {
  }
}


Granted this is not the best example. In this code I'd try loading a .layout file and if it fails because it is not of the proper version then the program calls upon the layout update tool.

Posted: Sat Jun 23, 2007 21:22
by scriptkid
Good thinking about the vesioning!

About the splitup of interface and functionality: we could even make the tools layer a bunch of commands which can be called from multiple interface types, just like you suggested. That way we are not even tighly bound to a language(cpp) or a framework(wx). So maybe my sample code (public CEGUITool) wasn't so good, because that suggests a base application. Maybe this is a better apprauch of how i look at it:

Code: Select all

#include "cegui/toolset"
using namespace cegui::toolset


where the 'cegui/toolset' could even get bounded to scripting languages.
But that's too much details allready ;)

Just to be sure: in the part you quoted i meant that i am not sure yet whether one tool (exe) should be able to edit all cegui related files, or that we need one .exe per file type, like it is now.

Posted: Sun Jun 24, 2007 22:43
by Rackle
If the tools layer is a bunch of commands, incorporated within the Cegui core, then specialized tools (to handle a specific job) or a generic tool (an application/solution/IDE capable of performing every job) can be created at will. The building blocks are all present; all that's needed is to assemble them into a complete package.

Here's another example of the type of thing I'm thinking.

I'm creating multiple dialogs, each composed of buttons, editboxes, multiline editboxes, etc. I've laid them out in a way that makes sense to me. However if my application incorporates some of the Layout Editor tools then I could allow my uses to modify these dialogs by moving/resizing some of the widgets in a way that makes more sense to them. However I would not allow users to add nor remove widgets; thus I need to enable/disable some of the features.

Traditionally this is coded via the menuitems and their associated hotkeys, or via pushbuttons. One implementation is that when the menu is opened the application's state is queried to determine which menuitem should be enabled/disabled. For a concrete example, think of the paste option, which is only available when there's something in the clipboard. Back to my idea/proposal, each action/command would then need to support something like:

Code: Select all

void performActionX(); // do the action
void enableActionX(const bool); // enable or disable the action
bool canPerformActionX(); // returns whether the action is enabled

With these functions the parent application should have everything it needs to build a suitable .exe.

Posted: Tue Jun 26, 2007 05:26
by ldb
what do you guys think about a layout system?

for instance, you could have horizontal layouts, vertical layouts and grid layouts, similar to toolkits such as gtk or qt. you could then nest these layouts to have any kind of layout you could imagine.

basically just create the widget, add it to the layout, and forget about it.

i think that would make tools easier to build. simply drag and drop layout containers onto a form, drop widgets in and let the layout container do all the sizing calculations.

Posted: Tue Jun 26, 2007 06:43
by scriptkid
@rackle: about allowing or not certain calls to the sytem. Are you thinking about adding methods like:

Code: Select all

WindowManager::DontAllowNewWindowsFromNowOn();
?

I'm affaight i didn't quite understand that paragraph. Do you mean that you want a game developer to be able to incorporate some tool functionalty into his game? Or that one tool developer can 'derive' from another tool?

@ldb
Yes there has been some discussion about layout managers. However IMO you hit the spot with mentioning to make it easier for tools. Because i don't really believe in them for in-game. My experience is that artists don't feel they have enough control when using layout managers. You end up by adding all kind of parameters and constraints to tweak the layour managing and thereby 'ruining' the whole idea of layout managers.

Discussing this area, i would like to be able to define templates for each widget. Just like powerpoint for example where you can say 'i want each next arrow to look like this'. Think this for widgets. What do you think?

Posted: Wed Jun 27, 2007 07:48
by Rackle
scriptkid wrote:@rackle: about allowing or not certain calls to the sytem. Are you thinking about adding methods like:

Code: Select all

WindowManager::DontAllowNewWindowsFromNowOn();
?


Yes, but more like CEGUI::Tools::LayoutEditor::DontAllowNewWindowsFromNowOn(). The Layout Editor tool would make use of the core Cegui functions, such as WindowManager::createWindow() and WindowManager::destroyWindow(). The restriction would be placed on the functions of the tool, not those of the core Cegui library.

To reiterate, I suggest that three prototypical functions be the interface for every functionality/component provided by a tool. With our addWindow() example, the Layout Editor tool would provide:

Code: Select all

void CEGUI::Tools::LayoutEditor::addWindow(parentWindow, schemeName, windowType, windowName);
void CEGUI::Tools::LayoutEditor::enableAddWindow(const bool);
bool CEGUI::Tools::LayoutEditor::canAddWindow(void);


This may not be the most obvious example since it is very close to the implementation of the WindowManager::createWindow() function. The Layout Editor provides more complex functions, such as the alignment functions. It also handles multiple selection, copy, paste, and delete. To get back to the example in my previous post, I'd like my users to be able to modify the layout of some dialogs and would like to make the "align top" feature of the Layout Editor available to them. Sure I could look for the code within the tool and copy it into my application but if instead every tool was coded as a library of reusable code I could simply call upon CEGUI::Tools::LayoutEditor::alignTop().

Another point is that I'd want to incorporate the Layout Editor directly within my application, rather than having my users having to exit my application and switch to the Layout Editor, load the appropriate .layout file, perform their modifications, and switch back to my application which needs to reload the appropriate .layout.

scriptkid wrote:I'm affaight i didn't quite understand that paragraph. Do you mean that you want a game developer to be able to incorporate some tool functionalty into his game? Or that one tool developer can 'derive' from another tool?


Yes to both.

I would like a game developer to be able to incorporate some of the functionality/components of a tools, such as a subset of the Layout Editor tool, as well as a tool developer to be able to incorporate the entire functionalities/components of tools, such as creating an IDE (think Visual Studio).

Put another way, the current Layout Editor could be split in two. One part would be the GTK GUI, containing the layout window, the titlebar, the menu and hotkeys, the ?contents? pane, etc. And the other part would be the reusable functions such as the addWindow(), enableAddWindow(), and canAddWindow() mentioned above. This second part could be segregated into a .lib such that applications/games that use only the "pure" UI features of Cegui would have a smaller executable size whereas a tool would link to both cegui.lib and LayoutEditor.lib (and whatever other tools it made use of).

Hopefully what I meant is clearer.

Posted: Fri Jun 29, 2007 17:51
by scriptkid
Okay, so resumé we can define a number of (new) functionality (besides the mentioned in the first message in this thread) to this tool layer:

*Some 'state management' regarding being able to make certain modification to the system. I was thinking that besides blocking adding of windows we could also do this for certain properties. For example disallow colour changes. Just a random idea ;)
*Being able to make selections and modify those with all kind of modifiers such as alignment, copying and deleting and so on.

To keep all this in a command/function apprauch, we could set this up as follows:

Code: Select all

... prepare tooling
CEGUI::Tools::LayoutEditor::enableAddWindow(true);
CEGUI::Tools::LayoutEditor::enableSelections(true);
CEGUI::Tools::LayoutEditor::enablePropertyChange("Text",True);
CEGUI::Tools::LayoutEditor::enablePropertyChange("TextColour",False);
... somewhere during the actual usage
CEGUI::Tools::LayoutEditor::clearSelection();
CEGUI::Tools::LayoutEditor::selectWidget(widget1);
CEGUI::Tools::LayoutEditor::selectWidget(widget2);
CEGUI::Tools::LayoutEditor::setProperty("text", "hello");
CEGUI::Tools::LayoutEditor::alignSelection("top");
... and so on


Such a line-by-line apprauch can be creatly put into scripts as well. While writing this code i think that we can maybe skip the 'LayoutEditor' part and put everything in a generic Tools library. So just:

Code: Select all

CEGUI::Tools::alignSelection("top");


Idea?

Btw. this is a nice thread about the visual aspect of a new toolset:
http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2685

Posted: Sat Jun 30, 2007 02:42
by Rackle
>> besides blocking adding of windows we could also do this for certain properties

Yes, that was only one example for one command. But rather than simply having a function to execute particular command I'm advocating two other complementary functions. One to determine whether the function can currently be activated; it is not possible to paste the contents of the clipboard when it is empty, thus requiring that the command not be available, either in a menu or at the press of a button. And the other to purposedly disable a function, althought on further thought this may not be needed; if a tool/application wants to disable a feature then it should simply not call that function.


>> i think that we can maybe skip the 'LayoutEditor' part and put everything in a generic Tools library

It's hard to say in advance, as we do not know the extent to which the various tools will overlap, providing similar but not identical features. But some features/functions seem to easily overlap (or be present in every tool), such as the clearSelection(), which most tools would provide.

Posted: Sat Jun 30, 2007 10:47
by scriptkid
You are right, i forgot to put some checks between those calls. However what i hope we can agree on is that behind this API style layer, there will be true class instances like we currently have in our tools. So that for example the selection functions will call an object such as the LayoutEditor uses right now. A little sample:

Code: Select all

namespace Tools::Layouts {
// Global, static, singleton or whatever
CSelection theSelection;
bool clearSelection() {
  theSelection.clearSelection();
}

bool selectWidget(aWidget){
  theSelection.select(aWidget);
}

bool canPaste(){
  return theSelection.size() > 0;
}
}


If we choose an implementation like this, this means that 'Tools' and 'LayoutEditor' are namespaces, right? Not classes themselves?

Posted: Sun Jul 08, 2007 16:33
by ldb
so, the actions that are currently available will depend on which view is currently active? so, perhaps on a view change, you could ask what tools are available and enable/disable tools in the main frame? also, things like copy/paste will work differently based on which view is currently active? all this will be queryable in these base tools you guys are discussing?

im trying to wrap my brain around how the doc/views will interact with these base tools, like, would a document enable/disable application menus/buttons -- that way each document would contain specific mechanisms for modifying the main frame tools. or would things like this be done in a view? how i understand it, the view would mainly be responsible for the actual manipulation of the data. so, it seems like keeping the information about what the tool can do in the doc would make sense.

so, like doc would ask what tools should be enabled/disabled, then these are actually usable once the view is selected.