Jump to content
The Dark Mod Forums
Sign in to follow this  
STiFU

Understanding the Code

Recommended Posts

Ah, cool idea!! We'd kind of be supporting half way multilanguage then. :) Shall we add this feature to the TDM bugtracker for future reference?

 

As translations happen far less frequent than mappers editing the actual readables, the priority of the readable editor should be the latter - of course, if we can make life easier for translators, that's cool, but definitely not at the expend of mappers.

Yeah, you're right of course. But I didn't suggest we should omit your proposal. I am thinking more like one readable-entity-editor and one general readable editor accessible from the view-menu, the latter only allowing importing/exporting and entity independent xdata editing. This might spread some confusion however. Mappers might be mislead into thinking the general readable editor was the only interface of such sort. That this is not the case could be communicated to them by using the same gui for both editors and simply 'greying-out' entity related interface elements. Hovering those elements could tell them in a small tooltip, how mappers are supposed to use the editor.

Share this post


Link to post
Share on other sites

Ok, I just had a brief look at ReadableEditorDialog. I'll probably just start with loading and saving xdata, because that will be the easiert for me... ;)

 

On "Save", the xdata is created in memory and written to the map .xdata file, the spawnargs are saved to the entity. On "Cancel", nothing happens and no changes are applied to entity or xdata.

What do you mean by "map .xdata file"? A file that is named just like the map-file you're working on? If so, we'd somehow have to make sure that always the same file is used for importing and exporting. Otherwise this would lead to duplicates of xdata definitions. This could be achieved as follows:

-When the first readable is created, the xdata file is named just like the mapfile.

-When the ReadableEditorDialog is loaded it checks in which file all definitions are stored in. Problems might arise on duplicated xdata definitions with this solution. The filename is stored as a private variable.

 

The second step is necessary because a mapper might save his file under a different name during development.

 

Edit: I just saw the .darkradiant-files. Maybe we could store the filename inside those? We'd then have to let the user chose a xd-file if the specified one couldn't be found. It'd also be good if we let the user choose the desired filename of his xd-file on the initial save.

Share this post


Link to post
Share on other sites

Hm. This file name handling seems to be rather complex - for the sake of simplicity of the code, I'd vote for writing xdatas into an .xd file which is carrying the same name as the map (e.g. gathers.xd). If that file is not existing yet, it is created, otherwise xdatas are appended.

 

It could be problematic to let DarkRadiant deal with existing .xd files as code comments in the file could be lost. For the DarkRadiant-created files a comment could be added to the top of the .xd file, similar to the particle .prt files created by Doom 3:

 

/*
Generated by the Particle Editor.
To use the particle editor, launch the game and type 'editParticles' on the console.
*/

 

When xdatas are loaded from existing files, maybe these could be marked as read-only? Or does your code already support keeping all other defs including comments, just writing the changed definition only?

Share this post


Link to post
Share on other sites

Comments are neglected by the DefTokeniser I used. I'd have to rewrite the XData classes a little for that. But Read-Only is basically no option anyway. Imagine you open an already existing readable, change some things and save. Read-Only prevents the altered xdata definition from being saved in the same file and would result in a duplicated definition for that reason.

 

But I just two hours ago redesigned importDef(..) a little and it now returns an XData object containing the definition AND the corresponding filename (multiple filenames if duplicates have been found). :) So if we open already existing readables we'll just store them in their original file. If we create a new readable, it will be stored in a file that matches the current mapname. Merging functionality and all that stuff is already setup for the exporter, so there is really only little left to do with this solution... :)

Share this post


Link to post
Share on other sites

Hey Greebo, I am having a weird problem with compiling currently. Once I include my "XDataLoader.h" the compiler throws out errors in "aabb.h" and "selectionlib.h", as well as warnings about macros not being used right. I uploaded it to the SVN. If you have a few minutes spare, it'd be nice if you had a look at it. I am pretty perplexed about this...

 

Also, is there an interface with whom I can access GlobalMap(), so that I can retrieve the map-filename?

 

Edit: Found out what caused the compiler errors by successively commenting out lines in my headerfile. ScopedDebugTimer caused the problem.

Share this post


Link to post
Share on other sites

Also, is there an interface with whom I can access GlobalMap(), so that I can retrieve the map-filename?

No, I don't think so. But we can easily extend the Map class and the corresponding IMap interface by a std::string getMapName() method, if we need that.

Share this post


Link to post
Share on other sites

If we want to store the new xdata in a file named like the map, I guess we do... ;) Map already has the method getMapName(), but adding it to the IMap interface like this "virtual std::string getMapName() = 0;" returns in a compiler error for StaticModule.h saying "'map::Map': Instance of abstract class cannot be created". The compiler error was gone after I removed the "const" behind the according method. This probably not very clean coding... :)

Share this post


Link to post
Share on other sites

If we want to store the new xdata in a file named like the map, I guess we do... ;) Map already has the method getMapName(), but adding it to the IMap interface like this "virtual std::string getMapName() = 0;" returns in a compiler error for StaticModule.h saying "'map::Map': Instance of abstract class cannot be created". The compiler error was gone after I removed the "const" behind the according method. This probably not very clean coding... :)

Remember that the constness is important, adding the const turns your method to a completely different one, as if you changed the arguments or the name. A non-const method doesn't implement a pure virtual const one, even if the name, arguments and return value match otherwise.

 

The correct way is to add the const to the IMap interface, not removing the const from the Map implementation.

Share this post


Link to post
Share on other sites

Ah of course! What a stupid mistake!! Failed to copy the signature of a method... :laugh:

 

Importing and exporting of xdata works already for the ReadableEditorDialog and I also fixed a tiny bug it still had.

 

If a requested definition has been found in multiple files a filechooser pops up and let's the user pick a sourcefile. I used a treeview to display the filelist. Is there a way to hide the column-title?

Share this post


Link to post
Share on other sites

Just a quick note. This here:

GtkTreeIter iter;
GtkTreeModel *model;
gchar *file;

if (gtk_tree_selection_get_selected (select, &model, &iter))
{
// Use gtkutil::TreeModel here
gtk_tree_model_get (model, &iter, 0, &file, -1);
*_fileIterator = _xdMap->find(file);
g_free (file);
}

can be made simpler by using the convenience method gtkutil::TreeModel::getString(). Take a peek at them in gtkutil/TreeModel.h, they do the low-level work like g_free for you.

Share this post


Link to post
Share on other sites

Ok, will have another look at that later then... Those lines were actually copy-pasted of that gnome reference-page though! :)

 

I am currently planning to make a template out of that filechooser, for use with .gui- and .xd-files in a similar fashion.

Share this post


Link to post
Share on other sites

So here is a first WIP shot of the basic layout of the readable editor. Of course I am open for suggestions.

post-684-126727571359_thumb.jpg

 

Implemented:

  • Don't allow typing of forbidden characters in inventory- and xdataname.
  • Only allow typing of numbers in numPages-entry. Zero should be forbidden.
  • While editing numPages, if you press escape, the old value will be restored.
  • Changing the pagelayout will eventually hide the two right textviews and the headlines "Left" and "Right".
  • Switching pagelayouts should not discard text.
  • A newly created page will be initialized with the same gui as the page before.
  • After entering an XData name, it will be checked whether that name is unique. If it's not a popup will ask the user whether the existing definition shall be imported. If it's not imported, another name is suggested (numbers appended).
  • If a new XData definition is created an XData name should be suggested, like: readables/[MapName]/<enter name>
  • Provide method for inserting a page before the current page.
  • Further extension of the insert/delete feature for twosided readables. It should be possible to inser/delete single sides.
  • Provide method for deleting a page.
  • Comfort feature: If the current page is an end of the readable (beginning or end) and the user clicks the switch-page-button of the "end-direction", a little pullup-menu could be shown, asking whether a page shall be inserted.
  • Tools: "Show last Import summary"
  • Tools: "Show duplicated Definitions"
  • Tools: "Show gui definition summary"
  • Derive pagelayout from entity. Greedy approach: Check whether entity name contains "book".
  • Make sure XDataName is set properly before saving.
  • New XData is now stored in the [mod_path]/xdata/ directory.
  • The GUI-browser will only list definitions that match the page-layout.
  • Hand-typed gui-definitions should be checked, whether they match the pagelayout.
  • Changing page-layout in the gui-browser should change pagelayout on the ReadableEditorDialog and preview accordingly.
  • Choosing a different GUI will update the preview. Optimally while the gui-chooser dialog is still opened.
  • Limit gui manager filevisitor to the readables folder. It just takes too long to parse all definitions and we don't gain anything from it.
  • XData-Browser previews the selected XData definition.
  • Fix issue with crash upon previewing certain readables in the XData browser.
  • Add loading definitions screen.
  • Maybe add options to the DR preferences menu in which the user can specify in which folder xdata definitions are supposed to be stored.
  • Tweak the preview: Cropping and gray background.

 

Postponed to future releases:

  • Notify the user when he typed a character that is not available in the font.
  • Option to check syntax of a specified file.
  • Option to duplicate and freeze preview or a general translator's dialog.
  • If the end of a page is reached in the preview, the editor should automatically jump to the next textView field.
  • Reducing page count via the spinbutton, should not delete the content directly so that the user can revert, if necessary.

Share this post


Link to post
Share on other sites
How to adjust width or height of a certain column respectively row of a table.

The width and height are determined by the child widgets, the table rows or columns themselves don't require space. You can set a minimum total width and height of the table by calling gtk_widget_set_size_request() but maybe this won't be necessary.

 

How to add a nice border to the textview widgets, similar to Entry-widgets.

Use gtkutil::FramedWidget to add frames to any widget.

 

How to make the textview widgets scrollable and how to limit the vertical size of the title-textview widgets to let's say two lines.

Use gtkutil::ScrolledFrame. The height can only be adjusted by querying the pango font properties and setting the space requisition accordingly, from what I've read in the past. You can have a look at some other GtkTextView examples if you try to search for that term in "Entire Solution".

 

How to add horizontal padding inside a Frame widget.

The frame shouldn't be used according to the Gnome Human Interface Guidelines, as it represents "visual noise". Use a bold gtkutil::LeftAlignedLabel() instead and indent the child widgets by 12 pixels. Similar to how the Surface Inspector is grouping its controls. The indentation can be achieved by using gtkutil::LeftAlignment() and packing the child widgets in there.

 

It's nice to see your progress, keep it coming.

Share this post


Link to post
Share on other sites

Hmn, what I want to achieve is that the left column of the lower table is always as narrow as possible and the top row as low as possible. I have tried different things now, but I don't get it right apparently. Is there no command to specify a maximum size or something like that?

 

I am trying to find proper examples for that in DR. Without any luck...

 

Edit: Ah, Stim/Response does what I want (at least horizontally). Gonna look at that.

Share this post


Link to post
Share on other sites

Uargh, finally! That was really a major pain!!! But now I finally got it. The key was to use gtk_table_attach with proper GtkAttachOptions instead of the default one. The GUI looks as it's supposed to know. Just a few buttons missing and then I can start with filling it with functionality.

On this picture the editor has already been scaled to show, that the vertical size of the title textViews remains as it is.

post-684-126729536331_thumb.jpg

Share this post


Link to post
Share on other sites

I am having a problem with other signals than "clicked". A Null-pointer is sent for the self-parameter instead of the actual data. Any ideas?

 

I assume it's got something to do with gtk_widget_add_events(). I am not quite sure on what I should apply that function. I tried it on the readable-editor window and on the event-inducing widget itself. But the weird thing about this is, that the event is definitely "thrown", but the data is missing...

 

Also ShaderChooser for instance doesn't add any events to any widget... Hmn! What could I be doing wrong?

Share this post


Link to post
Share on other sites

Which event are you trying to subscribe to? I can post example code then.

 

Generally, you don't use gtk_widget_add_events, you use g_signal_connect() instead.

Share this post


Link to post
Share on other sites

Argh, forgot to add the GdkEventKey to the callback method. Nevermind!! :) I must've been blind. Searched for so long for this little issue... :-/

Share this post


Link to post
Share on other sites

So, editing now fully works. You can view my progress in my upper post. I've added feature ideas to it and used it as a check list the last few days.

 

Just a couple of things left to do. The biggest of them being integrating the real-time gui Preview. I've already setup everything for integrating the preview. How far were you with the implementation of the renderer? Is it usable? I also still have to add the filechoosers for XData and gui files. You said the filechoosers of GlobalDialogManager() couldn't access the VFS right? So I'd have to create my own treeview. Any tips for that? I'd like to browse the XData definitions as if they were contained in real folders.

 

I still receive a weird warning of GTK however: "Did not receive focus-out event. If you connect a handler to this signal, it must return FALSE so the entry gets the event as well". The weird thing is that I have added this event only to one entry and the callback method returns FALSE in any case. Maybe the event is somewhat surpassed by the key-press event, but judging from my recent observations this shouldn't be the case generally.

 

I was thinking about removing the Left/Right-Labels to make some more room for the textviews. After all, everyone can tell which side is left and which one is right. :)

 

I also somehow accidentally made some changes to the stimresponse project. Have been looking up quite a few things there. Feel free to revert!! :)

Share this post


Link to post
Share on other sites

So, editing now fully works. You can view my progress in my upper post. I've added feature ideas to it and used it as a check list the last few days.

Nice! I have to check out the code in the next few days.

 

Just a couple of things left to do. The biggest of them being integrating the real-time gui Preview. I've already setup everything for integrating the preview. How far were you with the implementation of the renderer? Is it usable?

I am currently planning out how to handle the GUI scripts, which will take a little longer. In the meantime you could directly write to a hardcoded named windowDef of the books/bamberic_whatever.gui, but I can set this up for you if you want me to.

 

I also still have to add the filechoosers for XData and gui files. You said the filechoosers of GlobalDialogManager() couldn't access the VFS right? So I'd have to create my own treeview. Any tips for that? I'd like to browse the XData definitions as if they were contained in real folders.

A full fledged VFS-compatible file browser FTW! But this is not an easy job. I tried to implement my own GLib-compatible filesystem in the past, but I failed, it's too low-level for DarkRadiant. The only option is to add a new class to the gtkutil namespace, which features a treeview and a file list, plus the (configurable) default buttons and path entries. In the meantime, you could emulate the ModelSelector class, which can be found in radiant/ui/common/ModelSelector.h if I recall correctly.

 

I also somehow accidentally made some changes to the stimresponse project. Have been looking up quite a few things there. Feel free to revert!! :)

Depends on the changes? You can revert them yourself if you feel they are wrong. Just "revert changes from this revision" and commit.

Share this post


Link to post
Share on other sites
I am currently planning out how to handle the GUI scripts, which will take a little longer. In the meantime you could directly write to a hardcoded named windowDef of the books/bamberic_whatever.gui, but I can set this up for you if you want me to.

I have no clue about guis. What scripts would we need to handle? I thought we'd just need grab the background images of a Gui, check out in which areas the text is supposed to appear and then stuff the text inside... :) But I have time. No need to work on something that is likely to be thrown away anyway.

 

A full fledged VFS-compatible file browser FTW! But this is not an easy job. I tried to implement my own GLib-compatible filesystem in the past, but I failed, it's too low-level for DarkRadiant. The only option is to add a new class to the gtkutil namespace, which features a treeview and a file list, plus the (configurable) default buttons and path entries. In the meantime, you could emulate the ModelSelector class, which can be found in radiant/ui/common/ModelSelector.h if I recall correctly.

I was thinking more like a highlevel approach. I was planning to retrieve all xdata definitions first (basically the way I currently already do it) and create an appropriate data-structure from those. For example a definition is named "readables/MyMap/blah". So I'd create a container called "MyMap", put "blah" inside, and put it all together in a container "readable" and so forth with all other definitions. I was then going to display the result using such an expandable treeView like in preferences.

 

For better performance, I could also imagine "expanding" the data-structure only on request.

Share this post


Link to post
Share on other sites

I was thinking more like a highlevel approach. I was planning to retrieve all xdata definitions first (basically the way I currently already do it) and create an appropriate data-structure from those. For example a definition is named "readables/MyMap/blah". So I'd create a container called "MyMap", put "blah" inside, and put it all together in a container "readable" and so forth with all other definitions. I was then going to display the result using such an expandable treeView like in preferences.

What benefit would you have from creating those containers? If they just serve the purpose of grouping xdatas for display, you might as well use the GtkTreeModel for that. There is even a populator class which helps you sorting the containers into a hierarchical GtkTreeModel, it's called gtkutil::VFSTreePopulator.

Share this post


Link to post
Share on other sites

Hehe that's what I needed to know... :) I was just going to create a tree manually.

Share this post


Link to post
Share on other sites

Well that was easy. Quite a bit of copy-pasting, but it works nicely and I also understand the creation of dialogs much better now. Sweet! Do you have a filevisitor setup for your guiparser or should I create one?

 

Question: How can I retrieve the Mod- or Mod_base-directory. Currently I retrieve the engine path and add "darkmod/xdata/" for saving, but it'd be much better to retrieve the mod-path and append "xdata/", so that it's always stored in the right folder. Fidcal for instance said that he likes to setup a new project folder inside the doom folder when creating an FM and retrieving the modpath would ensure that the files are stored in the right place.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...