The International Simutrans Forum

Development => Patches & Projects => Larger Projects => Topic started by: Max-Max on May 31, 2013, 11:12:48 PM

Title: [Project] GUI Theme
Post by: Max-Max on May 31, 2013, 11:12:48 PM
Project description
This project's goal is to implement user created themes into Simutrans' GUI with resize capabilities.
We will also see if we can use the theme system to also cover themes targeting portable devices.

The project documentation can be read in this PDF (http://mkdevelopment.se/simutrans/SimutransTheme.pdf).

Examples of suggested themed components
  • Window title borders, title background and gadgets
  • Windows border (other than title), backround and resize icon
  • Button,checkbox,radio button,scrollbars, arrow buttons
  • Edit control (border, background)
  • Frame border (to group stuff), separator
  • System colors, such as, text, highlight, shadow
There will be a fallback theme for all GUI items.

Example of suggested resize capabilities
A window can be constraint to a minimum and/or maximum size.

When a window's client area gets to a point where its client area can't fit all child controls, it will automatically start to optimize/collapse the child controls. This is a suggested chain of reactions.
  • Make paddings smaller until they are 1px
  • Make Dividers smaller until they are their minimum graphical representation
  • D_H_SPACE and D_V_SPACE smaller until they are 1px
  • Remove dividers
  • Collapse expanded group boxes
  • Make buttons smaller (width) to the containing text width
  • Remove text from buttons with an icon associated, only show the icon
  • make window area scrollable
Each control type will have a minimum size, defined by the theme. This to ensure that buttons, edit fields, etc. will always be accessible on a portable device.

Road map
  • Convert all GUI elements to use the elements defined in frame_t.h instead of all the magic numbers. This may result in additional element definitions.
  • Set each element size to the size of its skin image.
  • Create a true window class, gadget bar class and a gadget class
  • Introduce a true client relation and update all dialogs
  • Modify/add controls if needed to work better with the concept of resizing
  • Create a dialog to select and apply a skin (theme).
  • Add detection and special handling for a small screen area (example portable devices).

Developer team
Max-Max (Max Kielland)

Drop a line if you are interested in joining the team.

Snapshot (http://forum.simutrans.com/index.php?topic=11956.msg125513#msg125513) of work in progress

Progress
Buttons are not bound to use the same size as the their image. You are no longer restricted to use the hard coded sizes for skin button elements (well, as long they fit in the PAK cell size). The default button size can be overridden in the theme.tab file. Button images are split into 9 images so a button can be drawn in any size with the same graphical look.
text and system colours, such as highlight, shadow, face etc can be configured in the new theme.tab file.

Patches:
So far the patches has all gone into the main trunk already.

Project documentation
This document (http://mkdevelopment.se/simutrans/SimutransTheme.pdf) is a draft in progress. It has information for both coders and artists.
Title: Re: [Project] GUI Theme
Post by: jamespetts on May 31, 2013, 11:25:12 PM
The snapshot seems to be set to private.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 01, 2013, 12:27:21 AM
Sorry for that, the permission should be public now.
Title: Re: [Project] GUI Theme
Post by: jamespetts on June 01, 2013, 12:33:08 AM
Yes, does work. Those larger buttons do look quite pleasing; but I wonder how this would work with some of the larger dialogues (finance?) or with lots of dialogues on screen?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 01, 2013, 12:37:07 AM
These large buttons are only a test case to see that everything is coded right. The size of the buttons will be determined by the theme later on.

With some advance resize features we could even have the dialogue to rearrange them better if the client area gets too small.
We are only at the first step so far...
Title: Re: [Project] GUI Theme
Post by: Markohs on June 01, 2013, 01:01:04 AM
I'm glad someone is in this project, I really hope it's sucessful and it brings order to the GUI, that's a bit cryptic part of the code, just because all of this hardcoded values splattered all across the code.
Title: Re: [Project] GUI Theme
Post by: ӔO on June 01, 2013, 02:02:11 AM
good luck with the project!

the current gui is definitely in need of improvement.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 01, 2013, 02:11:35 AM
Well, GUIs is one of my little passions and I have written some customized controls to Windows in may days and another GUI systems for LCD displays in embedded projects :)

The basic design of it is here is quite good with a light weight framework. However I do miss the client area concept and that the various buttons should probably be in their own classes to keep a true object oriented design.

A back link from each control to its parent (owner) would be desirable too, especially if we want the to reorder stuff when the client area is growing/shrinking.

With the concept of a true client area, a container can change parent and all its child control will follow in the same relative position, to the new parent's client area.

I don't want to mess around to much in the first phase. I will probably do it a little further up on the road map.

If someone wants to help we could need a rect_t class (similar to Windows RECT).

class RECT {

  public:
    sint32 left;
    sint32 top;
    sint32 width;
    sint32 height;

};


and some basic operator to go with it...
This will mainly be used to define a client area within each control.
Title: Re: [Project] GUI Theme
Post by: IgorEliezer on June 01, 2013, 02:16:20 AM
Pretty cool. :)

I sometimes think how it would look the title bars with bigger fonts. What if the current fonts were used, but scaled up 1.5x or 2x?
Title: Re: [Project] GUI Theme
Post by: Fabio on June 01, 2013, 12:34:51 PM
I find splendid you picked this project.
GUI needs some love and most in current dev team don't like GUI coding much.

:thumbsup:
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 01, 2013, 02:32:00 PM
Regarding fonts, I have only found one class reading a font and a bunch of helper functions to draw text.

One thought would be to expand the system with a logic font class derived from the current that transforme a font to create Bold, Italic, double size, half size etc... If the logic font takes a font class as a parameter it will be possible to transform a font in multiple steps.
I guess this is an entirely project on its own...  fell free to pick that one up :)

Already now, I need some new font class members:
  • Returns the bounding box of a string if it was drawn on screen. This would be a typical member of the font class.
  • Returns how many characters in a string will fit inside a provided box.
  • Returns the size of the widest character in a string of chars.

If some one would be willing to implement them I would be very happy...
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 01, 2013, 10:48:04 PM
The building blocks of your requested members are already present. display_calc_proportional_string_len_width() * large_font_total_height gives the bounding box.
Title: Re: [Project] GUI Theme
Post by: prissi on June 01, 2013, 10:52:47 PM
display_proportional_... returns the length of a text in pixel and LINESPACE the height. But since the buttons are skinned BUTTON_HEIGHT is taken directly from the skin images. (Btw use KOORD_VAL for coordinates, to be ready to switch to whatever size we may need next.)

In order to keep contribution for outsiders possible, I would rather not introduce to much different fonts. Maybe if really needed two fonts, a large and a small one for tooltips or infoscreens (both could be identical for normal machines).

As said I started work on the list windows/filter frame and line window, so no need to touch those. They will only use the variables from gui_frame_t and button_t and LINESPACE (which were obviously introduced for this purpose).

Which variables did you add? You just show a screenshot but no code? Could you show a diff?

Offtopic:
Actually, what simutrans really could use by now are an unified statistics class, which shows the gui_component, has a statistics for all the last 48 game months and all game years since start, and can export these data to CSV. But that is an entirely different project.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 12:10:55 AM
I'm removing all magic numbers and replacing them with the defines in frame_t.

To make all dialogues consistent, it means that some of their controls will move slightly a bit because I use the D_V_SPACE and D_H_SPACE between them. Some classes has only magic numbers and some are already updated correctly and don't need any updates, but most of them are a mix.

I'm also replacing dividers drawn directly with the class divider_t.
There are a number of "controls" that are drawn directly, instead of being its own class. I plan to convert them into classes.

Yes, some dialogues will increase slightly in size, but I have a pretty cool plan on how to make them auto-collapse in several levels when the client area becomes to small. To do this we need to use the concept of a client area.

The work has just began and I don't see any point in posting a diff already?

These has been added and will be replaced by proper variables in the theme system.

// gadget size (replace with real values from the skin images)
#define D_GADGET_SIZE D_TITLEBAR_HEIGHT

// Arrow size (replace with real values from the skin images)
#define D_ARROW_WIDTH  (10)
#define D_ARROW_HEIGHT (10)

// Scrollbar params (replace with real values from the skin images)
#define KNOB_SIZE    (32)

// Vertical divider element height (replace with real values from the skin images)
#define D_DIVIDER_HEIGHT (D_V_SPACE)

// Tooltip position (replace with real values from the theme)
#define TOOLTIP_MOUSE_OFFSET_X (16)
#define TOOLTIP_MOUSE_OFFSET_Y (12)


There are many defines in frame_t that doesn't belong there at all, like the button size. I think all these kind of variables should be in a theme class instead. Remember this is work in progress and there might be more or less elements...

When it comes to fonts, well it was just an idea and it is really up to the theme designer what fonts to use. But we are not touching that area until the themes are done. The creation of logical fonts is just a neat way to create variations of an existing font, without having additional fonts added to the font directory. These only exist in memory during runtime, but we deal with this later.

Another cool thing for theme designers would be to draw their on fonts in a sprite sheet and then have them "compiled" into a theme font (or a BDF,FNT,whatever...)

- For every obstacle, I see a challenge and for each challenge I see an opportunity...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 12:25:43 AM
Quote
display_proportional_... returns the length of a text in pixel
Okay I will take a look at these functions.

Quote
But since the buttons are skinned BUTTON_HEIGHT is taken directly from the skin images.
I guess you mean D_BUTTON_HEIGHT and D_BUTTON_WIDTH, yes I use them already.

Quote
(Btw use KOORD_VAL for coordinates, to be ready to switch to whatever size we may need next.)
Okay, so you want me to use koord(KOORD_VAL,KOORD_VAL). While I'm at it, why not rename and use COORD_VAL instead? KOORD_VAL seems to be pretty safe to rename...

Quote
...and LINESPACE (which were obviously introduced for this purpose).
Already using that one and even centre it around each complementary edit control.

The divider is also centred inside its client area, defined by the theme.
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 02, 2013, 12:27:40 AM
If replacing the magic numbers with a define results in things moving, then IMHO the wrong define was used...
I'm sure the current list of defines is not sufficient to fully replicate the structure of the existing dialogs; More need to be added.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 12:51:46 AM
There are many places where a smaller magic number is used instead of D_V_SPACE and D_H_SPACE. In many cases a magic number is used instead of D_MARGIN_XXXX that differs a few pixels.

Some places use a magic number, LINESPACE, D_V_SPACE or D_BUTTON_HEIGHT for dividers, I replace all these with the new D_DIVIDER_HEIGHT.

The difference isn't in the 100 pixel range, it is a few pixels here and there...

My screen shots are only test cases to see that I have covered everything, not the final and only result. All these relations can be controlled by the theme...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 03:03:50 PM
There is a Label control (gui_label_t) that isn't used at all.
I suspect the thought was to replace all direct drawn text labels with this label class. It takes care of both translations, tooltip, text colours, text justification and some text formatting.

Was this the intention? Shall I replace all direct drawn texts labels (not text inside other controls, such as buttons, edits etc...) with this control?
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 02, 2013, 03:57:48 PM
??. gui_label_t is used in many dialogues: halt_detail, money_frame, detail_frame, ...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 05:03:29 PM
Yes, you are right :) I had the wrong filter when I searched for it.
But there are a many dialogues that do not use it, so I guess I should replace all these direct draw with the label class instead.

The more I dig into this, the more it stands clear. The simWin and frame_t needs to be rearranged to get a more defined role. frame_t has nothing to do with a windows title and gadget bar. Now it leaves space for it at the top, bot do not handle it.

The result of this is that if you initialises controls in a frame_t constructor you need to take the title bar into account, but in the draw routine you should not.

The frame_t should operate without the knowledge of a title bar and leave that part to the simwin. Simwin should position the frame_t right depending on a visible title bar or not. With this concept the frame_t becomes a true client area for simwin and all controls are positioned the same in both constructor and redraw routines.

frame_t positions a container within the D_MARGIN_XXXX margins and now you don't need to worry about the margins at all when positioning controls. All controls will be relative to the frame_t's client area (container).

You can easily minimize a window by simply not drawing the frame_t from simwin, only showing the title bar at the bottom of the screen.
Title: Re: [Project] GUI Theme
Post by: prissi on June 02, 2013, 08:11:26 PM
Just a few things to remember:

Originally simutrans had three! different dialogue classes. It took me three month to unify them to the one (well, the tool window are still somewhat different). Also the container does not care about the title bar. Therefore I left the offset. But you are right: Removing the titlebar offset completely is something that should be done when one anyway touches all dialogues. One way woudl be to use two constants, one for the current code which draws the actual bar and one which is set to zero when everything else is in place. (Also iron way has skinable title bars; maybe we shoudl think about this too?)

Another outcome of the different dialogue classes were the handling of redraws. Many dialogues had text drawn themselves, while other used labels. When using labels would allow me to get rid of zeichen() completely, I did the conversion (at least for most of them), while I left others as they were.

The D_MARGIN_XXXX are very recent. Dialogues using these should be fully scaleable (or there has been errors in implementation). The other will use mostly offsets of either 1, 4, or 10 pixel.

In some cases (Depot) even though there might be a margin defined, the vehicle lists should use no margin at all, to squeeze as much evhicles in the depot as possible. Also scroll areas should have there scrollbar at the right. Thus using an offsetted continer for this will not work.

NB: Simutrans dialogues try to get intially a single width (and height). This fails (in the moment) for the line dialogue, finances, and some option frames. The idea is to have tileable dialogues.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 08:29:05 PM
Prissi, you have done a good job so far :)

I started to dig into it, but came to the conclusion that I will continue my current work first. I had it almost to work, but there is a problem  in banner_t where it overloads has_title(), but the original frame_t version is called instead. This resulted in the button detection being a D_TITLEHIGHT offset wrong. I will deal with this later.

Yes, when it comes to themes, I plan to not only to include the window's gadgets and title bar, but also the window frame, tab pages, bevels and a new control; collapsible groupbox.

I'm trying to think of portable devices as well with auto-collaps in several levels so the windows may fit a smaller screen. But this is further up the pipe...
Title: Re: [Project] GUI Theme
Post by: prissi on June 02, 2013, 10:12:08 PM
Imho please focus on scaleable dialogues. Do not try to do to much at the same time, i.e. introducing new controls and so on, or this project will be less likely to find a good ending.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 02, 2013, 10:15:04 PM
I'm sticking to my roadmap, still focusing on replacing magic numbers with defines and already available classes.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 02, 2013, 11:11:38 PM
 You should plan this in incremental steps in my oppinion. I'd say each of the milestones should be able to be submitted to subvrrsion..

The idea after this is making possible to get results committed to the game even if the project ends not being completed.  just plan one achiveable close and complete goal. we'll evaluate and refine it and incorporate to the game. once done, tou can for the next goal.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 03, 2013, 01:21:04 PM
This is what I do. I stick to the road map. If you guys think this is to big steps, I can create patches after each dialogue but since I'm going a bit forth and back in how things are implemented it would sometimes be more extra work for you guys to implement the same things while I changes some implementations...

Let me know how often you want me to send patches...

Another thought..
I noticed that the painting (zeichnen) is called every frame, even if the dialogue hasn't change. One thought would be to at the end of zeichnen save the dialogue as an off screen image.

Next time, if the dialogue hasn't change, paint the off screen image instead. This also applies when moving a dialogue, just move the off screen image instead.

As soon the dialogue is marked dirty, call zeichnen again to to get a new off screen image. This would speed up the frame time quite a bit.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 03, 2013, 01:29:33 PM
Another thought...

All resize stuff, aligning controls to an edge or stretching, is done in zeichnen. This calculations are only needed when the client area is resized.

Normaly a GUI system has a resize event handler that takes care of this, aligning controls. This will reduce the time spent in zeichnen and speed up the frame time a little bit more.

*** EDIT ***
To clarify the difference between set_groesse() and a resize event handler are the following:
set_groesse sets a controls size where a resize handler notifies all child controls that the client area has changed in size/position.

A notification takes out the alignment handling from the set_groesse() function. For example you could set a control to bottom and/or right alignment. Whenever it is notified that the parent's client area has changed, the control can adjust itself.

The notification will bubble down from set_groesse() to all child controls.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 03, 2013, 02:29:16 PM
This is what I do. I stick to the road map. If you guys think this is to big steps, I can create patches after each dialogue but since I'm going a bit forth and back in how things are implemented it would sometimes be more extra work for you guys to implement the same things while I changes some implementations...


Let me know how often you want me to send patches...



 I'd say a good moment to submit a patch here will be when you have replaced all the macro usage and dialog hardcoded values by variables, on all dialogues. I'd focus that first, just defining a set of default values for that variables, a "default" theme. It must be a patch that's ready for inclussion on the trunk code, that's expected to contain a few minor bugs (that's work-in-progress quality, ready for nightly and deveoper testing).

 Additional modification of dialogs (i.e. making them scalable or modifying the class hierarchy too much) should be done in a posterior iteration. I'd do it that way, but ofc, that's just my oppinion. ;)


Another thought..
I noticed that the painting (zeichnen) is called every frame, even if the dialogue hasn't change. One thought would be to at the end of zeichnen save the dialogue as an off screen image.

Next time, if the dialogue hasn't change, paint the off screen image instead. This also applies when moving a dialogue, just move the off screen image instead.

As soon the dialogue is marked dirty, call zeichnen again to to get a new off screen image. This would speed up the frame time quite a bit.

 See, you are about to grow the snowball here, and wide the amount of work you need to do. It's not a bad idea, but I don't personally think it's worth it, the perfromance increase whould be too low to justify this change, and adds complexity and mantainability problems. I'd refrain to do this, at least for now. If you want to experiment with this, I'd add as a project item, but leave it for later development iterations.

Another thought...

All resize stuff, aligning controls to an edge or stretching, is done in zeichnen. This calculations are only needed when the client area is resized.

Normaly a GUI system has a resize event handler that takes care of this, aligning controls. This will reduce the time spent in zeichnen and speed up the frame time a little bit more.
...

 I think this is a better idea, and it might be really worth implementing (whould be a "cache" of pre-calculated dialog vaules), but again, I'd pospone this for later. Take into caccount that GUI drawing it's *not* a performance problem in simutrans now, no need to code too much here, all changes should be focused on readibility, modularity, flexibility and mantainability of the GUI, performance is not critical.

 I'd say making pixmap-skinnable title bars or implementing partial transparencies it way more interesting to your project thatn this.

 Better to work and implement on things our players will be able to see and interact with, that teorical performance increases that might not be enough to make a difference.

 But ofc, all things I expressed so far are my thoughts, it's your project, do it as you wish. ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 03, 2013, 02:39:18 PM
My intention wasn't to do it myself right now, I stick to the road map.

I'm not comfy enough with the underlying graphic functions to be able to create an off screen map on the fly, but it should be fairly simple for someone comfy with it.

A resize handler routine relies on the client area concept and I can do it when I get to the resize part further up the road map.

I'm still on item 1 in the road map replacing magic numbers and direct drawn text and dividers with classes.
I leave shadow text as direct draw, but it should, in my opinion, be implemented in the label class later on (not now)...

An_dz is working on Item 2.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 03, 2013, 05:52:35 PM
okay. I'd say after phase 1&2 are finished,  you should post a patch here,  we can discuss a bit over it and we commit it to svn.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 03, 2013, 08:09:17 PM
I leave shadow text as direct draw, but it should, in my opinion, be implemented in the label class later on (not now)...

 btw, is this hard to do? Because you can maybe move it to phase 1, shouldn't be too hard to implement, no? No idea, as you wish. ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 03, 2013, 08:11:30 PM
I did move it in once but it got a little bit more than "just move" if we are to support other than LEFT alignment with shadowed text...
...so I removed it again to deal with it later.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 03, 2013, 08:15:42 PM
That makes sense, ok. :)
Title: Re: [Project] GUI Theme
Post by: prissi on June 03, 2013, 09:34:05 PM
About zeichnen:
Very few (only the very old) dialogues do calculation of positions on the fly. But for most stuff, it does not matter, as teh height of a line of text is anyway known, and the extra addition may be even faster than accessing memory.

About dirty stuff: Most dialogues contain a world windows, which is always dirty, and many contain some text (liek load o,porduction, statstics, text) which is frequently dirty. Very few dialogues are actually static. I am not sure that you could really save a lot by buffering the content. But such a patch would be independent from the resizing, so go ahead.

There is also a divider class, gui_divider_t Please go through the gui/components folder. YOu might find more surprises there ;)

I would even suggest to submit dialogue by dialogue. That way one would have a chance at discussion, and (imho) this is also more rewarding to see thing actually in the game.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 04, 2013, 05:54:04 PM
Prissi

I have merged the update from yesterday into my branch and it still works :)

How ever, I have made quite some rework on the tab control so it will draw its children in the client area below the tabs. The various elements of the tabs are parametric through defines. This to prepare it for themes. I will ask you to merge in my tab control to not interfere to much with my ongoing work.

There is one noticeable side effect. The client area of a tab was invisible before, now it defines the boundary. You will notice in some dialogues how the tab control isn't resized with the window and some lines may continue outside when resized.

Due to the fact that a tab's children are relative to the tab's client area, starting right under the tabs, all children are shifted down a bit because the old tab control didn't adjust for the tab area.


Another thing.
I was messing with the gui_scrolled_list because it was drawing outside its own bounding box. I noticed that you have began to do the same rework I had in mind too :) I will drop my changes until you are done with yours.

but I did noticed this from the previous version:

gui_scrolled_list.cc Line 236

Code: [Select]
      switch(type) {
        case list:
          break;
        case select:
          display_vline_wh(x, y+1, h-1, MN_GREY0, true);
          display_fillbox_wh(x,y,w,1, MN_GREY0, true);
          display_vline_wh(x+w-1, y+1, h-2, MN_GREY4, true);
          display_fillbox_wh(x+1,y+h-1,w-1,1, MN_GREY4, true);
          display_fillbox_wh(x+1,y+1,w-2,h-2, MN_GREY3, true);
          break;
      }
   
236  display_fillbox_wh(x,y,w,h, MN_GREY3, true);
237  display_ddd_box(x,y-1,w,h+2, COL_BLACK, COL_WHITE, true);

      PUSH_CLIP(x+1,y+1,w-2,h-2);

In the previous switch case the bounding box is drawn depending on the list type, but on line 236 it is always overwritten by a new bounding box starting outside the controls bounding box. This gives miss alignment when positioning the control.

I suggest to remove line 236 and 237, or move them into a default section in the switch case and keeping them inside the bounding box.

Code: [Select]
  switch(type) {
    case list:
      break;
    case select:
      display_fillbox_wh(x+1,y+1,w-2,h-2, MN_GREY3, true);
      display_ddd_box(x,y,w,h,MN_GREY0,MN_GREY4,true);
      break;
    default:
      display_fillbox_wh(x+1,y+1,w-2,h-2, MN_GREY3, true);
      display_ddd_box(x,y,w,h,COL_BLACK,COL_WHITE, true);
  }

May I also suggest that you create a list item class that is pure virtual and then derive one for a list item. In this way we can mix different type of items in the same list.
Title: Re: [Project] GUI Theme
Post by: prissi on June 04, 2013, 09:49:44 PM
Different types of items in one list is confusing the user; this will not happen in order to keep things simple.

I am not way finished with the scrolled list, as there will be a derived sorted_filter_list_t will incorporate the sort controls from the list dialogues.

You seem to derivate already a lot from the target, when changing tab controls and the like ... Anyway, we warned you. ;) More serious, look at the finance window. A client area for the tabs would look ugly.

I will go on a project meeting tomorrow, so I will not be able to look at your code before Friday night.

Title: Re: [Project] GUI Theme
Post by: Max-Max on June 04, 2013, 10:16:13 PM
I told you I don't mind to dig into the GUI stuff  ;D

Well, if no one has the time to look at it until the weekend, I will see if I can send a larger patch then...
I have already some dialogues converted but things are connected and will work best with a larger patch.

Well, one of the goals are to target portable devices. For this to happen the GUI must be able to rearrange itself and to do that the concept of client areas is in need. To get the alignment to work, I found that I need in some cases implement the client concept already now.

So I would say, no, I'm still on the very same path as intended...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 04, 2013, 10:36:04 PM
...regarding list items.

You can't say already now that it will be confusing for the user to mix different types of items in the same list, because we don't have anything yet where this will be applicable. We have to trust the developers that they have some sort of common sense when it comes to what to mix and not...

However, it is common praxis to use an ADT as a base item so further expansion will not impact on the already implemented system/behaviour.

Think of the scroll list as a scrollable container where each item is a container by itself. The scroll list can now serve as the list class independent of what it is displaying.

For example, you can make a vehicle list where you have one item type for each vehicle type showing different information. It could show a picture and some vital data in each list element. You can filter and mix these vehicle types in the same scroll list without the scroll list knows the type of each item.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 06, 2013, 03:05:33 PM
Some project progress updates...

The theme project has survived two trunk updates  :thumbsup:

One bigger impact of a theme is that we can't predict the size of each gui element. A check box might me larger than a button, or a edit field might be smaller than a button. When a dialogue/window builds it gui it can't rely on a fixed relation between the gui controls regarding size.

I have added a new function to the base gui class komponente_t that aligns a control to another control. The alignment can be made both vertical and horizontal in the same call. I will develop the alignment further as the project progress to have a control automatically realign itself if the alignment control moves or change.

I have also refined the number of control size constants and the list looks like this for now:

Code: [Select]
// theme system colours 
#define SYS_COL_HIGHLIGHT MN_GREY4
#define SYS_COL_SHADOW    MN_GREY0
#define SYS_COL_FACE      MN_GREY2

// default button width (may change with langugae and font)
#define D_BUTTON_WIDTH (gui_frame_t::gui_button_width)
#define D_BUTTON_HEIGHT (gui_frame_t::gui_button_height)

// default edit field height
#define D_EDIT_HEIGHT (LINESPACE+4)

// default square button xy size (replace with real values from the skin images)
#define D_BUTTON_SQUARE (LINESPACE)

// titlebar height
#define D_TITLEBAR_HEIGHT (gui_frame_t::gui_titlebar_height)

// statusbar bottom of screen
#define D_STATUSBAR_HEIGHT (16)

// gadget size
//#define D_GADGET_SIZE (gui_frame_t::gui_gadget_size)
#define D_GADGET_SIZE D_TITLEBAR_HEIGHT

// Arrow size (replace with real values from the skin images)
#define D_ARROW_WIDTH  (10)
#define D_ARROW_HEIGHT (10)

// Scrollbar params (replace with real values from the skin images)
#define KNOB_SIZE        (32)
#define D_SCROLLBAR_SIZE (scrollbar_t::BAR_SIZE)

// dialog borders
#define D_MARGIN_LEFT (gui_frame_t::gui_frame_left)
#define D_MARGIN_TOP (gui_frame_t::gui_frame_top)
#define D_MARGIN_RIGHT (gui_frame_t::gui_frame_right)
#define D_MARGIN_BOTTOM (gui_frame_t::gui_frame_bottom)

// space between two elements
#define D_H_SPACE (gui_frame_t::gui_hspace)
#define D_V_SPACE (gui_frame_t::gui_vspace)

// Divider element height
#define D_DIVIDER_HEIGHT (D_V_SPACE+2)

// The width of a typical dialoge (either list/covoi/factory) and intial width when it makes sense
#define D_DEFAULT_WIDTH (D_MARGIN_LEFT + 4*D_BUTTON_WIDTH + 3*D_H_SPACE + D_MARGIN_RIGHT)

// dimensions of indicator bars (not yet a gui element ...)
#define D_INDICATOR_WIDTH (gui_frame_t::gui_indicator_width)
#define D_INDICATOR_HEIGHT (gui_frame_t::gui_indicator_height)

#define TOOLTIP_MOUSE_OFFSET_X (16)
#define TOOLTIP_MOUSE_OFFSET_Y (12)

All these defines will be moved and replaced by the theme system later on, but are here for my convenience to test with different sizes.

I use the prefix D_ for global theme definitions and L_ if it is a local definition to tweak some dialogue specific properties. The L_ defines are in the dialogue source files where it is used.

Some controls will require new theme elements, such the tab control. This is why the client concept is so important. The hight of the tab will be decided by the theme, therefore it is important that, for example, a tab page's children (child controls) are positioned relative to the tab's client area. The client area is positioned relative to the tab control's position depending on the size of the tabs.

In these cases where a child control is placed outside the client area, it might also be an indication of that, maybe, it shouldn't be a child control of the tab to begin with. My goal is to maintain the the same structure and design of the current dialogues, but when we move away from a myriad of magic numbers, tweaking on pixel levels, it is inevitable that some dialogues will differ just a little in its layout when we replace them with the above constants.

Today I will prepare a patch with some dialogues and gui controls that I hope will go into the trunk soon.
Title: Re: [Project] GUI Theme
Post by: Ters on June 06, 2013, 05:53:35 PM
Aligning components of unknown size to each other is the biggest pain when laying out a GUI. I've seen far more unsuccessful solutions than successful. It might be better to tie all components to a common scale factor, like font size. However, even then there would still be problems matching scaled components to components that must be a fixed number of pixels no matter what (typically some raster image).
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 06, 2013, 07:27:27 PM
There are some techniques to handle alignment of some what arbitrary sizes. It will probably not work with ALL theme visions, but giving a flexible framework and the tools to test a theme, I think the artists will be able to produce quite amazing designs.

We should not say people are stupid just because you CAN abuse the system and make an impossible theme... What we can do is to provide a framework for artists to work with.

The Torque2D game engine have solved it quite nice and it works pretty well.
Title: Re: [Project] GUI Theme
Post by: Ters on June 06, 2013, 08:33:12 PM
It's not the themes I'm worried about, it's coding the layouts that can be themed. I have spent hours trying to get what seems like a simple layout to work in HTML. I have tried it in Java Swing. If I positioned and sized things with pixels, it would have worked, but only with the same fonts, DPI and screen size I have.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 06, 2013, 09:10:47 PM
I don't think we can compare this with HTML where a simple layout will look different in different browsers, no matter how x-compatible they claim to be :)

But I do see this as a great challenge to overcome... Rounding errors are always an issue that can accumulate in large and complex GUIs  ;)
Title: Re: [Project] GUI Theme
Post by: prissi on June 06, 2013, 09:51:32 PM
GEM (ok very obsolete by now) had its elements with two coordinates, one was font height/width dependent, and the other were just relative pixel (lets say one font height = 16 pixel). That would give your very much room for scaling without rounding errors (and I guess for most stuff the fine pixel will be zero). You might then change just get_pos() to something more elaborate and add a new set_pos() routine which takes two koords, with the second one defaulted to zero).
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 06, 2013, 11:43:22 PM
Okay, here is the first Theme patch. Things should look almost the same as before, unless you star to fiddle with the params in frame_t. As I said before the Panel is causing some offsets, but I will continue to update dialogues... Next patch, next Friday?

In this patch:

* checkbox height set to button square
* divider default inset, added set_width()
* Label_t height set to LINESPACE
* New control: Preview_map (experimental, may be removed later on)
* Banner color ramp defined
* Buttons using default sizes through defines
* frame_t Fall back if skin is loaded but no background defined.
* Banner buttons set to half dialog width
* Fixed tab panel to offset children correct in client area
* gui_image_t
 - Added enable_offset_removal() to draw the image without the offsets.
* gui.componente_t
 - Added align_to() to align a control with another
* gui_frame_t - Added GUI system color
 - SYS_COL_HIGHLIGHT
 - SYS_COL_FACE
 - SYS_COL_SHADOW
 - Added D_EDIT_HEIGHT for edit controls
* Divider using sys colors
* Language Dialog updated (flags drawn without offset)
* Map generation dialog updated (control alignment)
* Added gui_componente.cc to project

* Display Dialogue
* Player color dialogue
* Options dialogue
* Savegame dialogue
* Banner dialogue
* Language dialogue
* New world dialogue
* Sound dialogue

*** EDIT ***
I have removed the patch. It was released way to early and should never have been released in the first place.
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 07, 2013, 12:45:21 AM
Doesn't compile.
Code: [Select]
===> CXX gui/banner.cc
In file included from gui/savegame_frame.h:20:0,
                 from gui/loadsave_frame.h:12,
                 from gui/banner.cc:22:
gui/components/gui_divider.h:42:61: error: 'EDividerStyles' is not a class or namespace
gui/components/gui_divider.h: In constructor 'gui_divider_t::gui_divider_t()':
gui/components/gui_divider.h:40:36: error: 'EDividerStyles' is not a class or namespace
make: *** [/build/gui/banner.o] Error 1

EDividerStyles, fComponent, fAlignment, kALIGN_TOP, etc. Such camel case and strange prefixes haven't been the style used in Simutrans so far, not sure we want to go there...

Any dialogs where simply magic numbers were replaced could be committed straight away if they were seperated out...  A 8000 line patch takes quite a while to wade through - having 'simple' changes separate would help greatly.

There's many places where the TAB indents have been replaced with spaces. Please put the TABs back (and use TABs for added lines - initial indentation, spaces thereafter).
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 07, 2013, 08:48:34 AM
I merged, compiled and tested with 6534, non problems here... I'm not sure why you get compiler errors, did you do a clean solution and rebuild all? I have noticed that VC sometimes ignores a compile if only the header has changed.

Names such as EDividerStyles and prefix f is an old habit of mine, I just do it without thinking. However, having a parameter name that is the same as a member variable may cause hard to find bugs. The prefix f is just a way to make sure it isn't the same as a member variable.

Regarding tabs & spaces, I just followed what Prissi answered (http://forum.simutrans.com/index.php?topic=11943.msg117686#msg117686) on the question
Quote
I use 2 and 4 also sometimes. The beginning of a line should be tabs; after that spaces (i.e. when continuing if brackets).

Definitions should rather use spaces.

But that point again at reworking the dokumentation.

...and since Prissi seems to be the one working on the documentation, I followed his advice (or did I miss interpret it?)

I will change these names for you and chop it up in smaller pieces. I'm on my way to a 2 days music festival starting today, so I'm not sure if I have the time this weekend...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 07, 2013, 09:51:20 AM
Quote
"...and strange prefixes haven't been the style used in Simutrans so far, not sure we want to go there..."

What do you recommend to name params so they don't collide with member names?

A prefix is the easiest way to make it clear that it is a parameter and it will ensure it doesn't collide with a member. A parameter with a member name will silently override and cause hard to find bugs if you aren't familiar enough with the code.
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 07, 2013, 06:04:15 PM
Scoped enums is C++11 (and apparently a non-standard MS extension). Simutrans still uses C++98 - best to set your compiler to that (and disable MS stuff).

Scroll bars should be placed at the edge - no margin. Just look at the convoi info, halt info, and minimap post patch...
Default scrolly heights (and minimums) should be set for an integral number of entries - prevents ugly clipping IMO.
Chart sizes - the patch has shrunk them all to uselessness.
The savegame dialog was vertically sized to fill the screen before...
Linemanagement - scroll area is overlapping the filter text box.
Depot - divide ris overlapping the append/sell/front button.
Player List -  what happened ??
Title: Re: [Project] GUI Theme
Post by: prissi on June 07, 2013, 08:51:42 PM
IN order to have meaningful comments you need to make patch for one feature a time. I.e. one for new GUI elements, one dialogue at a time and so on. Otherwise we have a patch which turns a fully functional game into a very experimental agglomeration without much chances of testing. It means also taking everything or nothing; However, I feel that soem dialogues may be improved anyway. Thus any realistic realisation must be able to cherrypick things people like and will not like. Especially at this early stage, where we all have to find a route ourselves.

However, I am quite ill today, and will not have much time to comment on details until Monday I fear. Sorry, but TurfIt gave already some remarks.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 08, 2013, 01:49:25 PM
Since everything is connected, it doesn't make much sense to make any patches at all at this stage because not adjusted Dialogues and controls will be misaligned. This is exactly what I predicted would happen.

I will not make any patches until at least stage 1 is finished, then we can discuss how we can implement a huge patch, probably in chunks. But it will not really be usable until all chunks are in place.

Markohs suggested patches after stage 1 & 2, Prissi for each dialogue... I think it would make sense first after stage 1, no themes at that stages, but many theme params would be able to adjust through the defines.

If the project file isn't set up correctly, please update it in the trunk so we all work with the correct settings. The current version for download is VC 2012 Express and the update works fine but someone familiar with VC Express and the Simutrans' build process, needs to see if the conversion is changing any vital VC settings.

It would be good if some one could fix all the compiler warnings. I could do it myself, but I don't have enough knowledge of the code to decide if a type should be updated or type converted. When the warnings are fixed, it is easy to spot and fix your own warnings.

I have a clear vision of this project and maybe I didn't share it enough. I have updated the project description to give more details.
If there are some unpublished document for GUI design, please add them to the trunk for everyone to read.

When it comes to coding style I do read the style document and when I can't find what I'm looking for, I check the code. I have some habits that I do without thinking and I do go back and correct them when I see it.

I think the coding style can be improved to remove potential bug traps. One, for example, is to put a prefix on function parameters.

Consider this example:

void set_groesse(koord groesse) {

  this->groesse = groesse;
  groesse += koord(10, 10);
}

The code will compile fine but create a bug where the 10 pixel offset will be applied to the param instead of the class member. By using a prefix, this can be avoided.

void set_groesse(koord fGroesse) {

  groesse = fGroesse;
  groesse += koord(10, 10);
}

In the current code, I have seen the use of _ as prefix at some places, but _ or __ are usually used by compiler extensions and might be misinterpreted by some one used to work with this nomenclature. I strongly recommend that we use a prefix for params. if it is an f or something else, doesn't matter, just pick one, but maybe not the _ or __.

enums are not mentioned in the coding guide, I just copied what I already found in the code. If that is the wrong way, you need to put it into the coding guidelines.


Yesterday I was listening to some great artists like, La Fleur, Steve Aoki and David Guetta to mention a few. Today it will be Albin Myers, Alesso and Axwell to mention a few :)
Title: Re: [Project] GUI Theme
Post by: Ters on June 08, 2013, 04:36:36 PM
I suggest sticking to (one of) the current coding style(s) and discuss the coding style separately (there might be a thread somewhere). Waiting for us to agree about a coding style, especially when there is constantly new input like this, will just bog you down.
Title: Re: [Project] GUI Theme
Post by: prissi on June 08, 2013, 08:08:19 PM
Well, please break you patch down. Make one to get ride of the titlebar, and then we find about the rest.

About your overlaying groesse: You could easily name the function parameter gr. (Apart from the fact that your code will generate the warning of an assigned value which is not used.)

The f prefix in windows (or rather UPN?) stands for float. I would be deeply confused but this.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 09, 2013, 02:08:59 AM
Prissi,

That was just an example to show the problem when a parameter have the same name as a member. I have seen plenty of this in the code. Yes a warning is issued, but since there already are plenty of unresolved warnings, I would have to scan through them after each compile, to see if one of them is mine. Wouldn't it be better to just stick to some rules rather than relying on a compiler warning (or even better; fix the warnings)?

I have seen gr as parameter name in the code to. But even if the coding document don't state that a variable has to be meaningful, as you do for function- and class- names, I assume the same thing goes for variables and this is why we see the use of the this keyword.

f was also only an example, as in
Quote
...if it is an f or something else, doesn't matter, just pick one...
The message I tried to get through with, was to put a prefix or suffix so it will not collide with any member variables. Then we can actually call the params for what they are instead of cryptic short cuts and remove potential collisions.

Ters,
I did try to stick to one coding styles, but it was apparently the wrong one...  :-[

Okay, lets see if we can find a thread to discuss this, but it would be good to solve this ASAP so I don't have to rewrite everything again...
After a search on Coding style I found 2 of my own threads: Code indent and tab size (http://forum.simutrans.com/index.php?topic=11943.msg117682#msg117682) and Coding style (http://forum.simutrans.com/index.php?topic=11942.msg117676#msg117676).

The first one has started the subject but maybe I can change the name of the thread to "Coding Style Document". The second one has a good name for the thread but it has very little to do with the subject. Should I rename the first one so we can continue in there?

So, TurfIt, Prissi and Markohs, what about the other comments?

Updated project file with the correct settings?
GUI design document?
Fixed compiler warnings?

When can I expect to get this so I don't make more unnecessary mistakes again?

Now regarding the Theme project.
What is the point to replace only one of many magic numbers? Then I will have to do the same work again... and again... and again... for each magic number.
What if I do step one, dispatch one patch for the GUI controls, that will mess up some stuff, then one patch for each dialogue. After each dialogue patch, that dialogue would be okay again. Quite simple to detect errors in the dialogues when they are one by one.

In the later case, I can fix all the magic numbers at once for each dialogue.
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 09, 2013, 03:14:05 AM
Then we can actually call the params for what they are instead of cryptic short cuts and remove potential collisions.
For your example, I'd probably call the param 'new_size'. More descriptive than simply 'size' and avoids the aliasing.


After a search on Coding style I found 2 of my own threads:
Thread I started (in forum you don't see) to obtain a consensus on updating coding_styles.txt died a quick death... Guess it's a free for all.


Updated project file with the correct settings?
GCC is the primary environment. MS files are I think a courtesy, I have no idea how one would update them.


GUI design document?
No such hidden document exists.


Fixed compiler warnings?
GCC currently only warns of unused variables in asserts - annoyingly. I've heard MSVC goes rather even more overboard with its warnings. If there's something serious contained in one, maybe post it up in a different thread...


Now regarding the Theme project.
What is the point to replace only one of many magic numbers? Then I will have to do the same work again... and again... and again... for each magic number.
I think it was expected that the magic number removal in any particular dialog would have no effect on others. What is being changed in your patch that screws up dialogs you've not changed?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 09, 2013, 12:43:10 PM
Thank you TurfIt for your answers :)

There is not much use of continuing a discussion in a forum the whole community can't access. I have renamed the subject of my thread (http://forum.simutrans.com/index.php?topic=11943.0), maybe we can continue that thread or you can make your thread public to the community.

Regarding MS project file, this isn't my main development tool, so I'm not the right person to go through it.

If there is no GUI design document, there is no way I can know how things "should" be done. I guess, I'm free to use my own interpretation in this matter  :D

I will post the warnings in a new thread...

The magic numbers doesn't only contain the D_TITLEBAR_HEIGHT, it also contains all the Margins, pixel adjustments and other unknown dimensions. Depending on which container they are in, they also contains adjustment to its parent control, the tab control's children has the size of tab area hard coded. Some controls, like the chart, is drawing outside its bounding box. In short, it's an awful mess!

To fix all the magic numbers in each dialogue, some GUI components needs to get fixed so they a) draw inside their bounding box and b) reports the client area to its children so they can be laid out the same way even if the client area moves or change in size.

It doesn't matter how much we cut down the patches, in the end, as soon I change the GUI controls they will break the dialogues until each dialogue has been fixed.

To save work and not have to go through every dialogue multiple times for each stage in the patch creation, I would rather get rid of all magic numbers at once. This also gives me a chance to adjust and test my solutions before I submit the patches.

When stage 1 is finished I will en up with a huge patch. But I can create one patch for the GUI elements and then one smaller patch for each dialogue. After applying the GUI patch, things will be messed up, but for each dialogue patch, that particular dialogue will/should be normal again. In this way each patch will be much smaller and easy to test.

If you create a temporary branch to apply the patches, you can be several ppl working with them at the same time, dialogue by dialogue. Then when everything has been implemented and tested, merge it into the main trunk.
Title: Re: [Project] GUI Theme
Post by: prissi on June 09, 2013, 09:03:17 PM
Quote
It doesn't matter how much we cut down the patches, in the end, as soon I change the GUI controls they will break the dialogues until each dialogue has been fixed.

Why changing GUI controls? This is the last thing to do, as we have working dialogues. Also comboboxes needs to draw outisde their bounding box, that is part of their way. For charts, well changing it so it uses predefined spaces from the borders of its own bounding box (you me the size of the graph) can be done, and may affect different dialogues. First thing needs to be to make everything scaleable. Then there can be patches to change charts etc. Doing everything at once will be much more work for you, for us and unlikely leads to something good enough to everyone that I can integrate it.

Moving stuff within dialogues will not affect the overall code. Thus first priority should be moving dialogues. Best to start with those which are not scalable, i.e. not use any of the D_MARGIN_... When all dialogues use this, removing D_TITLEBAR... is just assigning one number.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 09, 2013, 10:53:54 PM
Quote
Why changing GUI controls?
I think you guys are making this a bigger issue than it is. I have already updated the Chart control to move inside its bounding box, it was already scalable. The tab control has already been updated to work with a client area and are already transforming events to the client coordinates.

The biggest issue TurfIt mentioned was when a chart was located inside a tab. That gives a double effect on unmodified dialogues:
1. The chart coordinate includes the tab heights as a magic number, but are positioned relative to the client. Meaning they get to far down in the client area.
2. Because the chart now rescale and draws inside its bounding box, instead of outside, the available client area has shrunk. In dialogues where I have not yet adjusted the components locations will display a very small chart.

I have already updated the buttons to work with the predefined sizes like D_BUTTON_HEIGHT, D_ARROW_WIDTH, D_BUTTON_SQUARE etc... These behaive exactly the same as before.

The edit control has been updated to use the new D_EDIT_HEIGHT, but if you define D_EDIT_HEIGHT as D_BUTTON_HEIGHT they look the same as before.

If all D_MARGIN_XXXX are set to 10, it will look as before, except for the fact that nothing will be the margin area, scrollbars are moved inside the margin. This is because the window border will be drawn in the margin and the margin will be decided by that border later on. A more realistic value might be in the range 3 to 5 later on.

Quote
Also comboboxes needs to draw outisde their bounding box
The edit control of the combobox is inside its bounding box, but as you know, the drop down list is placed on top of the GUI, as an independent layer. There are no controls that needs to be adjusted because of the drop down list. Therefore the bounding box is always only related to the edit control of a combobox. However the dropdown list has a bounding box (edit width and x items down) on its own "layer" on top of the GUI and a client area for the list items.

Quote
Best to start with those which are not scalable, i.e. not use any of the D_MARGIN_...
All dialogues I have seen so far are using margins as a magic number. Sometimes the magic numbers are separated and sometimes they are just a sum and I have to guess what's included.

I don't see the point in replacing one magic number with another to only remove one part of it. If I'm in each dialogue, why not fix all the magic numbers? When I see numbers that can be configurable I create a local define for easy configuration. For example, the file dialogue has a define deciding how many rows the dialogue should display. If you think they are to few, just increase the define and the dialogue is calculating the new dialogue height automatically.

Every time I notice a change in your trunk I merge it with my local theme branch, this means that the whole theme is already merged with the latest trunk code. If you prefer to get my, already merged, theme trunk I can zip the code and send it to you. No need for you to patch, only compile, run and test... If you want to see the changes, just run a diff against your trunk...

What you basically is asking of me is to revert 3 weeks of coding, replace a magic number with another magic number, then do the whole process again, and again, and again until all magic numbers are gone. If I notice that I should have done something different half down the road, I have to revert all code again and repeat the process and you will be frustrated that I'm send you new patches that makes the old ones obsolete. This only generates more work for all of us...

I see now that it was a huge mistake to send any patches at this early stage, before I had finished phase 1  :-X
Title: Re: [Project] GUI Theme
Post by: prissi on June 10, 2013, 10:08:18 PM
Actually, patches as early as possible. In the end I have to integrate a patch, whcih leaves me with such large patches in the position to either take all or leave it. (Which both is not desirable. As the deed is done, I will wade through your code slowly and then commit first stuff one by one.

So some initial remarks:
In banner you are redefining LINESPACE as LINESPACE_EXTRA_2: Why add this confusion? Also you defines of LINESPACE_EXTRA_5 and ..._7 are not helpful if I see them later.

Imho you better keep the existing stuff there, and sum them up. It is a long term anyway. Or, even better, do the resizing during construction of the dialogue, as in some many dialogues.

The comments about the strange naming of constants was already given ... Simutrans uses Uppercase for those usually. (Actually my MSVC complains that "EDividerStyles::kIn" is non-standard, which is using in virtual init in gui_divider_t". Also, why is this a virtual function?)

Also the enum is dead ugly. Especially since it is shared, I would rather have something global like the ALIGN_LEFT|MIDDLE|RIGHT for display_... too.

Furthermore I fail to link:
1>gui_map_preview.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual class koord __thiscall gui_komponente_t::align_to(class gui_komponente_t *,enum gui_komponente_t::EControlAlignments)" (?align_to@gui_komponente_t@@UAE?AVkoord@@PAV1@W4EControlAlignments@1@@Z)".

You were also patching the MSVC project file to a number not working any more for me ...

I also explicitely reserved the list windows several time for rework. Really, no need to touch them at all, I am planning to write them more or less new from scratch (same for line management window).
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 11, 2013, 04:08:35 AM
As I said, it was an mistake to release that patch so early. The banner.cc was one of the first I "converted" and after a while I kind'a found e better work methodology.

Quote
In banner you are redefining LINESPACE as LINESPACE_EXTRA_2: Why add this confusion? Also you defines of LINESPACE_EXTRA_5 and ..._7 are not helpful if I see them later.
LINECPACE isn't redefined, LINESPACE is still defined as (large_font_total_height).
The banner used a lot of magic numbers instead of just LINESPACE. If I had replaced them all with LINESPACE the layout of the banner would have been different. I figured that I would probably get a load of complaints if it did, so I tried to map them to already defined dimensions. This is kind'a bad idea too because these distances might change in the theme later... But as I said, they are there for elaboration...

LINESPACE_EXTRA_2 replace the magic LINESPACE+2
LINESPACE_EXTRA_5 replace the magic LINESPACE+5
LINESPACE_EXTRA_7 replace the magic LINESPACE+7

The easiest would be to just use LINESPACE in all these places... But since I made defines for them you can experiment yourself. Just LINESPACE makes the dialogue a bit awkward to read because of the shadow text being larger than the ordinary LINESPACE.
Quote
The comments about the strange naming of constants was already given...
I did try to find information about the enum and I also asked about them without getting a straight answer.
Quote
Simutrans uses Uppercase for those usually.
Usually?!? It either do or don't. Usually means I can use whatever standard I like... The big fuzz about the enum naming made clear it was wrong, even if I had copied some of it from the source. But still not a straight answer on how it should have been done. Please decide how enum should be named and implemented.
Quote
Actually my MSVC complains that "EDividerStyles::kIn" is non-standard, which is using in virtual init in gui_divider_t". Also, why is this a virtual function?
In the early stage I had a vision to separate the gui controls a bit more, to derive and create a bevel/panel control. But when I realised that the whole gui would need an overlook in its oo design, I thought that it might be another project in itself.
Quote
Also the enum is dead ugly.
Yes, there is almost a whole thread telling me this, but no straight answers...
Quote
Especially since it is shared, I would rather have something global like the ALIGN_LEFT|MIDDLE|RIGHT for display_... too.
I thought about it too, but I had more functions in mind. The enums looks like this now:

Code: [Select]
enum control_alignments_t {
align_none       = 0x00,

align_top        = 0x01,
align_v_center   = 0x02,
align_bottom     = 0x03,
align_v_interior = 0x00,
align_v_exterior = 0x10,

align_left       = 0x04,
align_h_center   = 0x08,
align_right      = 0x0C,
align_h_interior = 0x00,
align_h_exterior = 0x20
};

Except for the dead uggly enum style I don't think it's such a good idea to combine them. The other are for text justification and should probably be in their own namespace so it can be developed further without interfering with other areas. These are for control alignments and not text justification.

If you want all enums to be public, sure no problems just tell me how to name them. If you want them all upper case, how do you tell a #define from a constant? A #define has no type checking, unless you include it in the definition, while const and enum does. The Taligent coding standard (http://root.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_1.html), developed by IBM and Apple suggests the prefix k infront of const and enums to show that they are just that. Here (http://root.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_63.html#0) is a quick table from Taligent's Guide.
Quote
Furthermore I fail to link:
1>gui_map_preview.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual class koord __thiscall gui_komponente_t::align_to(class gui_komponente_t *,enum gui_komponente_t::EControlAlignments)" (?align_to@gui_komponente_t@@UAE?AVkoord@@PAV1@W4EControlAlignments@1@@Z)".
You have probably forgot to add gui_komponente.cc to the project.
Quote
You were also patching the MSVC project file to a number not working any more for me ...
I don't know what version you are using, I'm using the latest available for download, VC 2012 Express. Maybe time to upgrade, free of charge! ;)
I included it because I had added some files to the project... If I'm not allowed to use that version or add new files to a project, or if there are any special procedures for this, you have to document this as well.
Quote
I also explicitely reserved the list windows several time for rework
I stopped the work immediately when you said so... Again this patch should never have been uploaded in the first place...

I really appreciate that you took the time to have a look, but I feel sorry for you that you have been looking at a patch that shouldn't have been uploaded in the first place. As I also mentioned earlier, some code will be rewritten and changed a number of times and become outdated.

I also appreciate critique and feedback, but I don't care much for comments that tells me; this and that is sooo wrong and stupid, without telling me how it should be done instead. It isn't easy to know what is considered good or bad by looking at a source code written in many different styles...

I think I know how we can proceed in smaller chunks, I just need to figure out in what order to release each part. I think the gui_button_t, gui_frame_t, gui_numberinput_t and gui_komponente_t can be quite safe to implement. I have updated these to use the predefined dimensions. I just need to do a test merge with your trunk to see if it creates any strange behaviours first...

After that I think I can send you some dialogues that has no, tab or chart controls in them. Ohh... and simwin + werkzeug_waehler_t where the main handling of D_TITLEBAR_HEIGHT modification are.
Title: Re: [Project] GUI Theme
Post by: prissi on June 11, 2013, 11:52:48 AM
Now discussion started. Usually there are not rules in stone, we try to be flexible. And you have already lots of code, so very good so far. I do not want to have put it as a bashing. I would just suggest to ask about some tiny bit first, as you may get negative feedback early on.

For naming convention:
Simutrans uses all uppercase for constant stuff (read for stuff you do not put into the left side of an assignment). It does not care whether is is a define or const.

If you are worried about assignments to font_height because of #define LINESPACE (fontheight) use simply #define LINESPACE (fontheight+0) You cannot assign this or pass it by reference.

About reusing alignments:
The only thing that currently uses alignments are labels. All other stuff does its alignment itself, which is fully intended. But ok, assume we need alignments.

Then one could easily define (or enum in the global! namespace)

H_ALIGH_LEFT=0, H_ALIGN_CENTER=1, H_ALIGN_RIGHT=2, V_ALIGN_TOP = 0, V_ALIGN_CENTER = 4, V_ALIGN_BOTTOM=8
and for convenience people may want (although I am not sure this should be done)
ALIGN_H_CENTER_V_CENTER = 5

Voila, free alignment for almost any stuff. (also for images and the low level display routines, I personally would ignore the vertical part.)

I still have to look through the code, because at the moment, between making thing skinnable and introducing a lot of changed gui_components is a difference, which probably confused me. Therefore, I still have to find out about you actual aim.

The gui_numberinput is anyway somewhat tainted, as it does not trigger sometimes instant renaming action and other times not. If you want to work on gui_numberinput_t, it would be a good time to have it consistent.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 11, 2013, 01:43:07 PM
When naming a group of constants I always try use a name convention that follow a group order. Like the D_MARGIN_XXXX defines do (I guess the D_ stands for dimension/distance?).

ALIGN_LEFT     = 0,
ALIGN_CENTER_H = 1,
ALIGN_RIGHT    = 2,
ALIGN_TOP      = 0,
ALIGN_CENTER_V = 4,
ALIGN_BOTTOM   = 8


The alignment bits can be combined, just as you assumed.

I'm not sure if we should put H and V in every alignment. There is no doubt what LEFT, RIGHT, TOP, BOTTOM means, while CENTER needs to distinguish horizontal from vertical. Personally I'm always confusing horizontal and vertical because different software interpret them different (like moving along the axes or rotating around the axes).

When I make these global, where should I put them? simtypes.h?
Title: Re: [Project] GUI Theme
Post by: prissi on June 11, 2013, 03:03:47 PM
Since they need to be read by display_xxx, simgraph.h seems reasonable.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 11, 2013, 04:59:49 PM
All right, considered it done  :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 11, 2013, 05:49:42 PM
Hmm, ALIGN_LEFT is already defined but as text justification.

A suggest the following mod to the text justification enum:

Code: [Select]
enum text_justifications_t {

  JUSTIFY_LEFT   = 0 << 0,
  JUSTIFY_MIDDLE = 1 << 0,
  JUSTIFY_RIGHT  = 2 << 0,
  JUSTIFY_MASK   = 3 << 0,
  DT_DIRTY       = 1 << 2,
  DT_CLIP        = 1 << 3
};
typedef uint8 text_justification_t;

I renamed them to justification instead of alignment. So far when I looked at it it was only used with text justification.

I added a namespace because some IDE will show this in the watch window and it gives you the information of where it comes from right away.

I also created a type for them of the following reason.

Code: [Select]
void foo(text_justifications_t  justification_par) {

  // do something
}

As long you use one of the values in the enum it compiles fine, but if you combine them, you will get an error/warning because the combined value isn't a member of the enum.

Code: [Select]
void foo(text_justification_t  justification_par) {

  // do something
}

(The difference is in text_justifications_t vs text_justification_t)
Now all combinations will be accepted and the IDE will show you that the param is of the text_justification_t type. No doubt of what you are expected to put there as a parameter.

This is only a simple renaming of the ALIGN_XXXX to JUSTIFY_XXXX in your current trunk. I can do the replacement and conversion as a separate patch and send you to update.
Title: Re: [Project] GUI Theme
Post by: prissi on June 11, 2013, 08:42:59 PM
Why should text alignment do something else? My suggestion was just use the existing modifiers.

I would also advise against falgeritis. A justify flag should not carry the clip or dirty meaning. I know is is done for embedded and so on, but this is neither memory critical nor will an additional parameter impact performance (compared to the drawing). Simutrans tarted as an excercise to make clear OOP code. As such we tried (not always successful) to keep the code as simple as possible. It results in easier understandable code, and less errors and usually helps often even the compiler's optimizer.

But back to the project as it is: Why do you feel the UI needs the alignment modifier? Any Object has already a bounding box and could decide itself how to scale with size changes. The labels have text, color and alignment, but those are reather put through to the actual drawing.

Forcing thing to scale from the "outside" feels a little against the thing of OOP, i.e. gui stuff as very independent objects.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 11, 2013, 10:50:41 PM
Why do we need alignment?
I'm not sure if you understand what I have done. I'm not talking about text justification. I'm talking about object alignments, aligning bounding boxes (controls) relatively to each other. There are tons of places where a label is centred around an edit field for example.

What is most clear to you?

foo.align_to(&bar,ALIGN_CENTER_V);

...or...

foo.set_pos(foo.get_pos() + koord( 0, (bar.get_pos().y - foo.get_pos().y)/2))

There are already a lot of cryptic formulas for control alignment. By having the alignment function built in to the object you can just simply tell it just align with another object. I do plan to create a group control that can distribute child controls in various ways.

Strange enums?
If you are referring to DT_DIRTY and DT_CLIP, that isn't my enum, it is the existing one and my proposal to rename it to JUSTIFY_XXX instead of ALIGN_XXX. Those flags where merged in by tron in version 1050. The comment say @author Volker Meyer, prissi So don't blame me for that enum :)

Sure I can change the numeric values of the existing to the ones in my enum, but I have no idea of what impact that might have on the current code. I don't know what to do with the DT_CLIP, DT_DIRTY and DT_MASK.

The alignment values I have are selected in such a way that you can combine them. You can in a single operation align object Foo's right side to object Bar's left side (exterior) with an offset of x and at the same time align Foo's vertical center to Bar's vertical center. That would look like this:

Foo.align_to(&bar, ALIGN_EXTERIOR_H | ALIGN_RIGHT | ALIGN_CENTER_V, koord(10,0) );

I plan to make it possible to have Foo now always follow Bar with this alignment relation. Whenever Bar moves, Foo will follow.

Why rename current ALIGN_XXX?
Because current ALIGN_XXX is only used to justify text within a text control, while my new ALIGN_XXX is aligning objects to each other. These are quite two different functions and it would be wise to separate them. The current ALIGN_XXX that is text related could be expanded with, bold, italic, column, underline etc... Maybe it should be called TEXT_ALIGN_LEFT, TEXT_ALIGN_RIGTH etc.. Then you could expand it with TEXT_BOLD, TEXT_SHADOW etc...

So to make it absolutely clear what my intention is:

CURRENT TRUNK CODE

Code: [Select]
/*
 * len parameter added - use -1 for previous behaviour.
 * completely renovated for unicode and 10 bit width and variable height
 * @author Volker Meyer, prissi
 * @date  15.06.2003, 2.1.2005
 */
enum
{
ALIGN_LEFT   = 0 << 0,
ALIGN_MIDDLE = 1 << 0,
ALIGN_RIGHT  = 2 << 0,
ALIGN_MASK   = 3 << 0,
DT_DIRTY     = 1 << 2,
DT_CLIP      = 1 << 3
};


PROPOSED CHANGE

Code: [Select]
/*
 * len parameter added - use -1 for previous behaviour.
 * completely renovated for unicode and 10 bit width and variable height
 * @author Volker Meyer, prissi
 * @date  15.06.2003, 2.1.2005
 */
enum text_attributes_t {

TEXT_ALIGN_LEFT   = 0 << 0,
TEXT_ALIGN_MIDDLE = 1 << 0,
TEXT_ALIGN_RIGHT  = 2 << 0,
TEXT_ALIGN_MASK   = 3 << 0,
DT_DIRTY   = 1 << 2,
DT_CLIP   = 1 << 3
};
typedef uint8 text_attribute_t;

/**
* Alignment enum to align controls against each other
* Vertical and horizontal alignment can be masked together
* Unused bits are reserved for future use, set to 0.
*
* @author Max Kielland
*/
enum control_alignments_t {

ALIGN_NONE       = 0x00,

ALIGN_TOP        = 0x01,
ALIGN_CENTER_V   = 0x02,
ALIGN_BOTTOM     = 0x03,
ALIGN_INTERIOR_V = 0x00,
ALIGN_EXTERIOR_V = 0x10,

ALIGN_LEFT       = 0x04,
ALIGN_CENTER_H   = 0x08,
ALIGN_RIGHT      = 0x0C,
ALIGN_INTERIOR_H = 0x00,
ALIGN_EXTERIOR_H = 0x20
};
typedef uint8 control_alignment;

I don't know what to do with the MASK and DT flags...
In this way you can continue to add stuff that are text related to the text_attribute_t.

Forcing thing to scale from the "outside" feels a little against the thing of OOP...
The alignment isn't resizing anything, it is moving the whole object. It is very OOP when you just tell an object to follow another with a set relation. But again, i think you have misunderstood the use of it. My ALIGN_XXXX is used in a call to a member function
Code: [Select]
align_to(gui_komponente *target_object, control_alignment alignment, koord offset )
Title: Re: [Project] GUI Theme
Post by: Ters on June 12, 2013, 08:38:13 AM
I'm not sure if you understand what I have done. I'm not talking about text justification. I'm talking about object alignments, aligning bounding boxes (controls) relatively to each other. There are tons of places where a label is centred around an edit field for example.

What is most clear to you?

foo.align_to(&bar,ALIGN_CENTER_V);

...or...

foo.set_pos(foo.get_pos() + koord( 0, (bar.get_pos().y - foo.get_pos().y)/2))

I think the idea is that the labels controls shouldn't be centered on the edit fields, the label should match the edit field. The text inside the label would instead center within the label control, and therefore appear centered on the edit field as well. The result looks the same, but only one level of alignment is needed, not two.

I am familiar with GUI frameworks with two levels of alignments, first of controls within the layout grid and then of text within the controls, but where it makes a difference, I think I have always used the fill alignment.
Besides, the align_to function seems to assume that the edit field is larger, which may not be the case. It is perhaps unlikely for an edit field to be smaller than just plain text, but what if it was a check box or an image instead of an edit field.
Title: Re: [Project] GUI Theme
Post by: prissi on June 12, 2013, 01:00:19 PM
About alignment: If you have control x aligned relative to control y, you need to align control y at a certain point.

And control_x.set_pos( control_y.get_pos() - koord(foowifth+D_SPACE_X,0) ), makes it easy to add stuff. (At a certain point you still have to set_pos():  If however, control x depends control a which depends on c and which finally is from control f: then how on earth adding stuff to it in a controlled position? Also rigth aligning stuff does not obey left borders at all. The D_MARGIN were specially introduced to have a uniform border.

So, I am not fully convinced. Such alignment will fail badly either in other languages (when width is taken automatically from the strings) or you have to specify a bounding box. But then it is trivial to align it anyhow.

So my idea for Labels next to controls
label.init( koord( D_MARGIN_LEFT, current_y ), koord( BUTTON_WIDTH,BUTTON_HEIGHT), text, color, alignment  )
button.init( koord( button_pos2, current_y), ...

If there is a very common control (which is not imho) then maybe the label and the next control should  be rather merged. Then also the controls tooltip (if any) could cover both.

Furthermore, using fixed X coordinates for buttons (as most the dialogues do now) means that a button is always at the same position relative to a dialogue.

I have to add, that I would only expect text to align itself within the bound box. As such an inner Alignment, which otherwise centers single line text inside the bounding box, and put multi line text into to left corner seems enough for simutrans.

But as this is my view I appreciate further discussion on this.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 12, 2013, 03:06:35 PM
The question wan't about the existence of an align_to() function. It was about naming and renaming enums. I wanted to distinguish between object alignment and text justification.

None of you have seen the function align_to(), how it is used, where it is used or what it can do.

My point is that text justifications are attributes to a text, more than only justifications. In that category you can also put shadow, bold, italic, underline etc..

My alignment enum has nothing to do with text.
Title: Re: [Project] GUI Theme
Post by: Ters on June 12, 2013, 05:13:42 PM
My alignment enum has nothing to do with text.

Exactly, and therefore I don't see the need, but that might be because I'm unfamiliar with this way of laying out a GUI.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 12, 2013, 09:17:17 PM
So what is the conclusion?

Rename the current ALIGN_XXX to TEXT_ALIGN_XXXX so we later can add more text related stuff and keep them separated from object alignment?
Title: Re: [Project] GUI Theme
Post by: prissi on June 12, 2013, 10:34:46 PM
I wrote I am not very comfortable with using other objects to align. The Alignment needs to be always left vertically center (with the execptions of multiline text), or things will look weird in several languages. It means to give labels a bounding box, yes. Otherwise I fail to see how a left margin can be consistently achieved.

But I have to further look at the design, I am still not fully recovered yet. But most important, three people discussing this there is no conclusion so far. Maybe the conclusion that, whatever will happens, labels need a size.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 12, 2013, 10:40:58 PM
I'm not talking about aligning text to controls or controls to text.
I guess I just do what I fit is needed and then you will probably see what I mean...

Get well Prissi...
Title: Re: Make world limits not forced to water level
Post by: Max-Max on June 13, 2013, 07:14:10 PM
While developing this, I noticed there are not much image creation and management routines in the game, just like the climate code does, this patch needs to create new images each time the world is created. kierongreen aproach to this was duplicating the image and rotating it if necessary. It's all implemented around bild_besch_t::copy_rotate.

 I need to create *new* images, with arbitrary size and recode them using them the RLE, do you think it's a good idea to place this routines in bild_besch_t , routines that accept a uncompressed buffer and compress it or it's not the right place to code this?

 Just asking, I'm doing it that way, but wanted to hear your oppinions for the case you point me to a better solution. We could maybe implement that in simgraph16.cc (rezoom routines are there), or in a new collection of routines called bild_tools::* or image_tools:: . Dunno.

I will also need to create images on the fly for the themes later on.

Since we already have functions to draw lines, boxes and text, one approach might be to create a canvas (image context). When calling any draw function we simply provide the canvas we want it to draw on. As default, if no canvas is sent, it uses the current screen canvas (as of today).

A canvas can be a simple structure with.

pointer to data (graphics) or other already defined way of managing images.
current forground color
current background color

This is a commonly used way to do it in most graphic systems.

I do remember seeing somewhere in the code that a 1pixel image was created on the fly if a requested image wasn't defined. But I don't remember the context where it was used :P
Title: Re: Re: Make world limits not forced to water level
Post by: Ters on June 13, 2013, 07:45:21 PM
I will also need to create images on the fly for the themes later on.

Since we already have functions to draw lines, boxes and text, one approach might be to create a canvas (image context). When calling any draw function we simply provide the canvas we want it to draw on. As default, if no canvas is sent, it uses the current screen canvas (as of today).

A canvas can be a simple structure with.

pointer to data (graphics) or other already defined way of managing images.
current forground color
current background color

This is a commonly used way to do it in most graphic systems.

I do remember seeing somewhere in the code that a 1pixel image was created on the fly if a requested image wasn't defined. But I don't remember the context where it was used :P


This is a very different graphics system from what Simutrans has now, and what Markohs is working with. Apart from the frame buffer itself, Simutrans revolves around images that are written once, and drawn millions of times (not 100 % true, but descriptive enough). Canvases for GUI should be discussed in a GUI topic.
Title: Re: Re: Make world limits not forced to water level
Post by: Max-Max on June 13, 2013, 08:05:58 PM
Quote
Simutrans revolves around images that are written once, and drawn millions of times
Yes, and this is exactly what I mean. But why invent the wheel again when there already are draw functions available?
However, I don't know how the underlying graphics stuff works, this was only a thought...
Title: Re: Re: Make world limits not forced to water level
Post by: Ters on June 13, 2013, 08:23:26 PM
There is nothing in the GUI that I am aware of that isn't loaded from disk and that doesn't scale with the window or change almost every time it is drawn. Avoiding to redraw parts that hasn't changed is or can be handled with mostly with the dirty rectangles on the frame buffer level, as moving windows shouldn't make much impact on overall performance. Images in Simutrans can't change size, have multiple storages for player coloring and zooming, and merge identical images into one, all of which is overkill for GUI stuff. The capacity is also limited, and once allocated, an image can never be freed.

A canvas concept for the GUI might make sense, as it could encapsulate some of the clipping and maybe dirty rectange updating, but trying to build it on to of the image storage sounds like unnecessary pain. It's that pain I'm warning against.
Title: Re: Re: Make world limits not forced to water level
Post by: Max-Max on June 13, 2013, 08:47:45 PM
This is probably the wrong thread to talk about this, but my thought was to create any missing image in the theme (by creating and drawing a standard image for the missing theme image). This would reduce the need to check if an image exist, because there will always exist one.
Title: Re: Re: Make world limits not forced to water level
Post by: Markohs on June 14, 2013, 12:13:51 AM
While it's true simutrans lacks code to do what you suggest, Max-Max, current routines are designed to be drawn on the framebuffer. As ters said, images are designed to be loaded just once and written often to framebuffer (scaled or not).

Also, the current code doesn't treat them in a dynamic-friendly way, simutrans basically loads all the pak images on memory (compressed) and assigns them a number. The only dynamic images implemented are the terrain ones and they are done in a somehow hackish way (imho). They are just created and the id of the first registered one is stored, if the map is re-created all images with an id greater than that one are deleted.

 What I'm trying to express is that simutrans images and routines are designed to be basically static. Is that a bad thing? No, it's the way this game was designed and the code is certainly robust and performs well enough.

 Do we need to modify this? I'm not sure, probably yes, when there is a need to (if they are really useful somewere and make a difference). Personally I think it would be a good idea implementing some new routines in the style you mentioned, but I'd do it as a complementary system, letting current routines unchanged, because they need to be lightning fast. But I kind of think your idea is not bad.
Title: Re: Re: Make world limits not forced to water level
Post by: Dwachs on June 14, 2013, 06:03:04 AM
The only dynamic images implemented are the terrain ones and they are done in a somehow hackish way (imho). They are just created and the id of the first registered one is stored, if the map is re-created all images with an id greater than that one are deleted.
... which is no longer true. These images are generated once on startup.

Max-Max, I do not know whether I understand your intent: Do you need to create dynamic images and want to use them? Ie use existing draw routines to modify your image buffer.
Title: Re: Re: Make world limits not forced to water level
Post by: Markohs on June 14, 2013, 08:51:48 AM
... which is no longer true. These images are generated once on startup.

 oooh I stand corrected, sorry. :)
Title: Re: Re: Make world limits not forced to water level
Post by: prissi on June 15, 2013, 10:21:49 PM
This gets slowly offtopic, but: In principle you can have easily a canvas by pointing textur to something else while drawing the dialogue. It will fail however with the allegro backend, as it uses a pointer to a screen area.

Nevertheless, most dialogues are dynamic (Speed of train, poduction of town, money, statistics, incomes, World view, ...) The only static ones are the option dialogue. Thus I am not sure the double buffering is useful. It would need a class of buffered and non-buffered dialogues. And I fear the class of the latter is very small compared to the maximum gain from it.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 19, 2013, 09:48:33 AM
I have managed to isolate the basics into one patch.

This patch will not make any visual changes (what I'm aware of), but implements the D_TITLE_HEIGHT in simwin and werkzeug_waehler.
I will try to make more patches, one for each dialogue.
Title: Re: Re: Make world limits not forced to water level
Post by: Max-Max on June 19, 2013, 03:27:06 PM
Hmm, I think we have different definitions of what an static/dynamic image is. I will try to illustrate what I mean. Consider this piece of code:

arrow_left_normal = skinverwaltung_t::window_skin->get_bild_nr( 8 );

If  image 8 isn't loaded (it is missing in the PAK file) I want to allocate a new blank image in its place. On this blank image I wan to draw a simple left arrow. Now after the creation of this missing image...

arrow_left_normal = skinverwaltung_t::window_skin->get_bild_nr( 8 );

...will use the image of my simple arrow. So the image is static in the sense that its image data is not changed, but created dynamic in memory if the skin image is missing in the PAK file.

I'm not talking about double or triple buffering used to minimize flicker. I think Dwachs is closest to my intention; Yes it would be nice if it was possible to use the current drawing routines like display_fillbox etc... to create this missing image.

The image 8 is only to illustrate an example, it could practically be any image loaded from a PAK file at load.
Title: Re: Re: Make world limits not forced to water level
Post by: Ters on June 19, 2013, 06:09:22 PM
I don't think the game should make images that are missing. It's easier to just draw simple placeholders than to code something that draws them anyway. In some cases, the size of the image is information the game needs, so it needs to have the image in the first place just to know what size it should be.
Title: Re: Re: Make world limits not forced to water level
Post by: Max-Max on June 19, 2013, 08:29:52 PM
Okay, now this has really become of-topic...

But the game is already doing it now (have a look in gui_button.cc). The sizes and images are already hard coded for missing skin images and redrawn using display_xxxx every frame, instead of simply replacing the missing image with the one it has already drawn.

By replacing the missing images (that you draw every frame anyway), you only have one scenario and less code to maintain. How on earth can that be a bad thing?!?
Title: Re: Re: Make world limits not forced to water level
Post by: Ters on June 19, 2013, 08:38:26 PM
I'm just saying it's a lot of work for little gain. I was also assuming that the game didn't fake missing images in any way whatsoever. Either they exist in some file, or the game won't start. (I have never really read GUI code, just seen some in passing. My studies have been in the besches, landscape data structures, and low level system and rendering code.)
Title: Re: Re: Make world limits not forced to water level
Post by: Max-Max on June 19, 2013, 09:20:13 PM
...I have moved this to the GUI theme thread (http://forum.simutrans.com/index.php?topic=11956.msg118733#msg118733).
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 19, 2013, 09:26:05 PM
This is a continued discussion.

Before we got completely of-topic, Markohs said...
Quote
I need to create *new* images, with arbitrary size and recode them using them the RLE, do you think it's a good idea to place this routines in bild_besch_t , routines that accept a uncompressed buffer and compress it or it's not the right place to code this?
...and I said I need it too. I only suggested to use a canvas/context device/what-ever so we could reuse the functions that are already in place.
This isn't really my area, but I had a quick look in simgraph16.cc and found that a few routines display_xx_internal are writing to a pre-calculated memory pointer...

PIXVAL *p = textur + xp + yp * disp_width;

Isn't it possible to add a parameter to these routines that is NULL by default. If NULL use the pre-calculated pointer, PIXVAL *p = textur + xp + yp * disp_width; other wise, use whatever type this extra parameter needs to be, a bild_t* ?
Title: Re: [Project] GUI Theme
Post by: prissi on June 19, 2013, 09:40:59 PM
There are routines in the simgraph16.cc, which does the trick (rezoom_img does unpack and repack images).

But again: What is the purpose? Buffering dialogues in simutrans does no make sense, since most dialogues can change very much between each update.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 19, 2013, 10:03:19 PM
No, this has nothing to do with buffering dialogues or render buffers. Read this (http://forum.simutrans.com/index.php?topic=10835.msg118716#msg118716) post for an example.

Today, the code is already drawing missing skin elements every frame with the display_xxx functions. I want to create the missing skin images after load so we can use the same code everywhere and not draw them every time, like we do in gui_button.cc for each missing skin element.

By creating the missing skin images after load, we can remove the fall back code in the GUI, because there will always be a skin image available...
Title: Re: [Project] GUI Theme
Post by: prissi on June 19, 2013, 11:17:13 PM
If you want images, just require all images or simutrans will not load?

Those are dated back from times when the central skin directory did not exist. Nowadays it is very easy to make sure using this that a skin with images exist.
Title: Re: [Project] GUI Theme
Post by: Ters on June 20, 2013, 04:19:45 AM
Maybe we should just trim the fallbacks from trunk? One less thing to maintain.
Title: Re: [Project] GUI Theme
Post by: prissi on June 20, 2013, 08:34:23 AM
Some pak still need them, as some symbols are taken from symbol.misc.pak Thus, as soon as the new system is ready, then this code can go at the same time.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 21, 2013, 02:44:57 AM
I have put up the two patches in the first post. These patches would make any difference, but they prepare the code with the basics to create one patch per dialogue.

By setting the THEME_TEST (in gui_frame_t.cc) to 1 you can switch between a test setting and "normal" settings.
At this point the test setting is of course not doing much more than screwing up the dialogues, but I will fix them one by one...
Title: Re: [Project] GUI Theme
Post by: prissi on June 21, 2013, 08:48:59 AM
Just attach them here next time; it save some scrolling. Otherwise also the discussion will be very difficult to follow as soon as new versions are released.

Short comments:
First, you are using spaces for indent. Please all indent until the first character are tabs, if possible. Only for ifs and for alignment of defs spaces are ok.

draw_roundbutton: You left the "if(h==14)" in there, despite the button now enforcing BUTTON_HEIGHT. Should this be either an magic enum or rather BUTTON_HEIGHT?

I am not happy about TEXT_ALIGN_xxx and ALIGN_xxx As discussed previously, those do the same, thus they should use the same name exactly. (It also blows out the patch size considerably.)

You still follow the idea of align stuff right or left to elements. In which situation this is needed? With very few exceptions, the only align used would be on a vertical position, since the horizontal line must be fixes or else the dialogues would be very randomly designed, depending on language an all. If you really want to do this, then all labels need an explicit groesse (which then also automatically would take care of the vertical alignment). Otherwise larger font or different language (and thus text) will mess up the alignment thouroughly. (Especially since it will affect groesse.x!) BTW: One of the few places, where left/right alignment make actually sence (in numberinput) you did not used it.

Also the offset is something different to alignment. Not too happy to combine everything there, but well.

What purpose should ALIGN_EXTERIOR_V serve? That could be easily passed as an offset. (Make make an offset only routine too?)

The D_GET_CENTER_ALIGN_OFFSET/D_GET_FAR_ALIGN_OFFSET should not be needed with the align routines and properly enforced bounding boxes for labels. Furthermore, they just high a subtraction (and a shift), thus are longer than their explicit writing down.

Shouldn't the BUTTON_X() take into account the left border of a dialog, i.e. D_MARGIN_LEFT?

Switching themes should be done by loading stuff. But ok, for testing rather include something into the gui_frame_i init.

SKIN_CELL_SIZE is imho not needed.

ALso why did you moved the button typ definition in welt.cc? Does you routine depend now on it? The changing button types must be avoided at all.

Sorry, I have to work now, but thanks for this. It is a good way to start.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 21, 2013, 01:42:04 PM
I did attached the first one of them in the same reply once, but it only got one download and no comments at all, so I figured no one saw it. But sure, I can attach them to the same reply from now on.

Quote
First, you are using spaces for indent. Please all indent until the first character are tabs, if possible. Only for ifs and for alignment of defs spaces are ok.
When I asked before I got the answer first indent as tab character with size 4 spaces, then spaces after that with size of 2. How about updating the document so there can't be any misunderstandings. Are you referring to block indents? I think the best would be if you just show an example.

Quote
draw_roundbutton: You left the "if(h==14)" in there, despite the button now enforcing BUTTON_HEIGHT. Should this be either an magic enum or rather BUTTON_HEIGHT?
If you read the comment after it "// Max: Replace 14 with the actual button image height". The routine assumes that the image for a button always is 14 pixels in height, so even if there is an image present but the button height isn't 14 pixels, it is drawn with the fall back routine. I plan a different solution in drawing the theme elements and don't want to do too many changes at this point.

Quote
I am not happy about TEXT_ALIGN_xxx and ALIGN_xxx As discussed previously...
...You still follow the idea of align stuff right or left to elements...
...Also the offset is something different to alignment...
...What purpose should ALIGN_EXTERIOR_V...
Maybe I should write a document with pictures to illustrate how it works. Again this has nothing to do with text at all. I have a plan with this alignment stuff and further down the road it will be used more frequently. Remember, one of the goals are targeting portable devices where the screen size is very limited. As I described earlier, I have a plan for how to handle this.
I'm not sure if anyone understands what exactly is aligned against what. I can replace the TEXT_ALIGN_XXX with the ALIGN_XXX if some one can solve the two other flags in that enum, DT_DIRTY and DT_CLIP (get them out of there). As you said yourself, they don't belong in there...

Quote
The D_GET_CENTER_ALIGN_OFFSET/D_GET_FAR_ALIGN_OFFSET should not be needed...
You are absolutely right here, this was actually what lead to the alignment routine in the first place, because I saw that the alignment need was quite big. It will be replaced and removed.

Quote
Shouldn't the BUTTON_X() take into account the left border of a dialog, i.e. D_MARGIN_LEFT?
It makes sense not not include the margin. If you are placing them in relation to something else than the border, you don't want the margin to be included. Secondly, the child object should not be depending on its parent's layout. I'm planing the concept of client areas further down the road.

Quote
Switching themes should be done by loading stuff.
I thought we agreed on doing this in very small steps... I haven't even started on the theme loading yet. Still only replacing magic numbers.

Quote
SKIN_CELL_SIZE is imho not needed.
I wasn't sure what this really meant. Does it mean that a skin image can't be smaller or larger than 64 pixels? I put it in there for further elaboration.

Quote
ALso why did you moved the button typ definition in welt.cc?
The set type function gives a default size to the control. I use to replace them with init() when I can. Unfortunately, for some reason, Init() isn't a member in the base class gui_komponente_t and can't be used for all components. I'm leaning towards to implement the Init in the base class. But as you said, I don't want to mess around to much with he classes now, I focus on the magic numbers.
In this special case it has been replaced with the more appropriate Init() function, but you wanted all dialogues, one by one, so I had to do something to fix the issue temporarily in this patch.

I was told to not release large patches and to release one dialogue at the time. To do this I can't implement all at once and as I said before, the same code may change many times on the road. So either you will have many small patches, some obsoleting old ones, or you can wait and get one stage at a time in a huge patch. Your call...
Title: Re: [Project] GUI Theme
Post by: prissi on June 21, 2013, 09:38:29 PM
Space instead tabs are on many places. Just open your file with notepad, and you will immeadiatly see ifs, that have tabs and three lines below spaces. For instance the case in line 187.

The DIRTY/CLIP flags with text could still be part of the alignment enums. Just use a higher number, 0x40 and 0x80 are not used.

Buttons were the oldest element; that is the reason they behave different and have an init. Also the world creation dialogue was (is) able to change its language on the fly; this is no longer needed. Hence a type changing the size of the element is really a nono. This is an unexpected side effects and should be really avoided. (As also said for the labels: Their size MUST NOT depend on the text it displays, but must be given on initialisation.) The only way for proper bounding boxes is, that those are set by the programmer (using the BUTTON_WIDTH and the like).

An init routine in gui_komponente does not make much sense or? It has to have different parameter for each component. One could however argue for an init routine to be present for any implemented gui_komponent_t.

The skin (i.e. dialogue background) should be able to cope with any size (and even allow for now skin with transparency, like the chat window.) Its being 64 is rather tradition and not really needed.

Why does the gui_frame_t needs to know the size of a gadget? Should this (and the titlebar) rather go to simwin.cc ultimatively?

Quote
It makes sense not not include the margin. If you are placing them in relation to something else than the border, you don't want the margin to be included. Secondly, the child object should not be depending on its parent's layout. I'm planing the concept of client areas further down the road.
Please elaborate. It seems you target are dialogues, which change their layout considerably when changing languages or switching sizes (instead just scale up). Or is this a misunderstanding?

But, all in all this patch is progressing in such a way that it can be tested and then integrated.
Title: Re: [Project] GUI Theme
Post by: Ters on June 21, 2013, 10:20:44 PM
When I asked before I got the answer first indent as tab character with size 4 spaces, then spaces after that with size of 2. How about updating the document so there can't be any misunderstandings. Are you referring to

Who wrote this? Having the first indent level twice as large as the rest don't make any sense at all. It's also a bit contradictory that it says use a tab character of four spaces. A coding style either uses tab character, or it uses spaces. Maybe it's meant to say that the editor should be set up with a tabulation size equal to the length of four spaces, but possibly the best reason for using tab in the first place is so that each can adjust indent width to their own preference.
Title: Re: [Project] GUI Theme
Post by: prissi on June 22, 2013, 08:45:35 PM
After some more thinking:

Many simutrans dialogs have row of objects. Meaningful alignmet therefore would be a function like:
align( GUI_komopnenete_t *h_pos, gui_komponente_t *v_pos, alignenum a, koord offset );

What do you think?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 03:41:04 AM
Despite the midsummer celebration here in Sweden, I have put together some of my thoughts around the new Theme system in this draft (http://simutrans-germany.com/files/upload/SimutransTheme_r28.zip).

Remember this is only thoughts and ideas, not the law :police:

Quote
Space instead tabs are on many places. Just open your file with notepad, and you will immeadiatly see ifs, that have tabs and three lines below spaces. For instance the case in line 187.
Line 187 in what file? Wouldn't be easier to just update the code document instead of pointing out all the errors, show how it should be done, not where it is wrong.

Quote
The DIRTY/CLIP flags with text could still be part of the alignment enums. Just use a higher number, 0x40 and 0x80 are not used
.
But they have nothing to do with alignment. Especially not GUI bounding boxes against other GUI bounding boxes. Imho I think these flags has less to do with my alignment, than my alignment has to do with text alignment. My routines don't use them at all. I still think that text alignment should be in its own enum, together with these flags.
There is 2 bits left and I do have a plan to use these two bits further down the road. That is why they are reserved.

Quote
Buttons were the oldest element; that is the reason they behave different and have an init. Also the world creation dialogue was (is) able to change its language on the fly; this is no longer needed. Hence a type changing the size of the element is really a nono. This is an unexpected side effects and should be really avoided. (As also said for the labels: Their size MUST NOT depend on the text it displays, but must be given on initialisation.) The only way for proper bounding boxes is, that those are set by the programmer (using the BUTTON_WIDTH and the like).
Almost all button init() sets the size to koord( D_BUTTON_WIDTH, D_BUTTON_WIDTH ). I made it possible to exclude the size and have the Init() to set them to the default size for that control. You can still override this in the init() by setting the size parameter. If this isn't still enough you can set a new size after the init() call.

Quote
An init routine in gui_komponente does not make much sense or? It has to have different parameter for each component. One could however argue for an init routine to be present for any implemented gui_komponent_t.
It makes all the sense in the world. All components has a position and a size, this can be set through the init() routine.
As you know, in C++ you can have more than one version of a function as long the number of parameters and types isn't the same as declared earlier. If you need more params to init a control, just make a new Init routine, call the old one and then handle the new parameters.
If you want to forbid calls to the older version of Init() you can move it to be protected or even private in the descendent class.

Quote
The skin (i.e. dialogue background) should be able to cope with any size (and even allow for now skin with transparency, like the chat window.) Its being 64 is rather tradition and not really needed.
Do we have support for transparent images now? The makeobj is complaining if it finds an alpha layer.

Quote
Why does the gui_frame_t needs to know the size of a gadget? Should this (and the titlebar) rather go to simwin.cc ultimatively?
I think I mentioned it earlier. I put some extra stuff in there so it would be easy to test, not having to open several files to tweak and test. This stuff will be moved later on...

Quote
Please elaborate. It seems you target are dialogues, which change their layout considerably when changing languages or switching sizes (instead just scale up). Or is this a misunderstanding?
Hmm, maybe. My alignment and window resize will not change the size of the GUI components other than outlined in the document I wrote. The collapse functions will be one of the last stages in this project.

Quote
Many simutrans dialogs have row of objects. Meaningful alignmet therefore would be a function like:
align( GUI_komopnenete_t *h_pos, gui_komponente_t *v_pos, alignenum a, koord offset );
To organise controls in rows, columns and grids will be handled by a layout control. The alignt_to() is the basic needs for the layout controls to work with. But who knows, maybe it changes down the road...

And for you Ters
Quote
Who wrote this?
Does it really matter? How would that information move this project forward?

Quote
Having the first indent level twice as large as the rest don't make any sense at all.
It might not make any sense to you, but it does to me and many others...

Quote
It's also a bit contradictory that it says use a tab character of four spaces. A coding style either uses tab character, or it uses spaces
In fact several IDE use tab characters as far as possible and then mix in with space to reach the intended indent.


Regarding this tab & space hickup...
If you guys had spent a few minutes to update the code style document, as I have requested several times, we wouldn't even have this discussion now...
I think you have spent more time, words and efforts to tell me how stupid my code is than it would have taken you to update the document.
Title: Re: [Project] GUI Theme
Post by: neroden on June 24, 2013, 03:57:34 AM
MaxMax: I think this project is great.  I have one strong worded piece of advice.

While you're rewriting the gui, do *not* use the koord class.  It is used (inconsistently) in parts of the existing gui, and it would be good if it were not used.  Koord should be for map coordinates.  Only.

If you need a similar class for (x, y) points in your gui, please make a new class and we can use that one for screen coordinates.  Rewriting the gui to stop interacting with the very complicated koord class would allow for:
(1) better debugging (gdb spews a lot of noise when dumping 'koord' due to all the static elements)
(2) better type-safety
(3) larger screens.  Koord is limited to roughly 2^15 by 2^15 bits, and we don't want to increase it (right now) because that would affect a lot of gameplay code.  However, there's no reason why the screen should be limited to that number of pixels.

----
On the topic of spaces vs. tabs and so forth: I have noticed that simutrans does not have a standard prettyprinting/indentation style.   It might be worth considering having *some* standards.

I like having loose standards, since some functions need to be indented differently from others.  And given the divergences between standard and experimental, and the number of outstanding patchsets, now is probably not a good time to establish a strict indentation style.

Does everyone have access to GNU indent or a program with similar options?  What is the equivalent on Windows?
Personally I like "Linux kernel style" (indent --linux-style) pretty well:
Code: [Select]
int x;
if (x) {
} else {
}
I don't like GNU style (wastes too many lines, too much whitespace):
Code: [Select]
int  x;
if (x)
{
}
else
{
}

I guess simutrans does have one rule: tabs for indentation, one tab per indent, no spaces.  I like this.  This would be equivalent to something like "indent  -ts4 -i4 -ci4 -cli4 -bli0 -cbi0"  (where all the numbers are multiples of the ts number).
---
Reading through the outdated coding styles document, I see that my preferred bracket style is preferred :-)  I really really strongly dislike the official simutrans preferred placement of pointer marks and I would suggest that the style recommendation be reversed.  char* x; is a good declaration, char *x; is a hard-to-read muddle.  I would however prohibit declaring multiple variables on the same line in order to avoid the problems related to that.
Title: Re: [Project] GUI Theme
Post by: Ters on June 24, 2013, 04:52:06 AM
Wouldn't be easier to just update the code document instead of pointing out all the errors, show how it should be done, not where it is wrong.
If it was easy, it would have been done by now. Reminds me of some guidelines on Wikipedia that "everybody" knows are not as they should, but for which they can't reach consensus on a new text, so the old text stays and they just disregard it.
Does it really matter? How would that information move this project forward?
Not this project, but it might help us put a stop to misinformation in the future.
It might not make any sense to you, but it does to me and many others...
In fact several IDE use tab characters as far as possible and then mix in with space to reach the intended indent.
I have never seen coding styles where indentation sizes are not uniform. As for mixing tabs and spaces, it's the worst possible way to indent, unless there is a clear separation between when to use tabs (to indent code) and spaces (to indent comments after code). I have seen it used so that the first indent level is say four spaces, the second is one tab, the third is tab plus four spaces, then two tabs and so on. Unlike the alternatives, it won't look right in other editors with different tabulation sizes. It can also interfere with search and replace operations including the indentation. An abomination in my opinion.
 
I agree with neroden that koord is for the map, not the GUI.
Title: Re: [Project] GUI Theme
Post by: kierongreen on June 24, 2013, 07:44:45 AM
Preferred coding style is
if(  x && y  ) {
}
else {
}
Title: Re: [Project] GUI Theme
Post by: prissi on June 24, 2013, 09:40:05 AM
About indentation, the simple rule (as enforced by most editors anyway): Use tabs

Only two expections come to my mind:
if(  bla && bla &&  ... very lonw
    && bla && blac )  <--- this line has spaces for indent!
{
<- here tabs again!

The second one is for the definitions of stuff.
sint16  a;
sint8   b;
bool  c;
very_long structure c;
although tabs may work here too, and no indentation is fine too.

I tried some code refactoring. Almost any program has some issues. I think there is a GUI for uncrustify or so, which near gave nice results. Especially the double space around logic operators is almost impossible to enforce, and many brackets are sometimes close (trivial) or open important longer clauses, which a software fails to rectify obviously. If one could live with this limits, we can set a date to run these over standard and experimental at the same revision and keep then synchronised that way. (Same can be obviously done to the patches).

About the topic of DIRTY etc.
But they have nothing to do with alignment. Especially not GUI bounding boxes against other GUI bounding boxes. Imho I think these flags has less to do with my alignment, than my alignment has to do with text alignment. My routines don't use them at all. I still think that text alignment should be in its own enum, together with these flags.
There is 2 bits left and I do have a plan to use these two bits further down the road. That is why they are reserved.
And I disagree. Those constant do alignment, it should not matter if the align text, images or whatever.

You can obvjously now have more than one display_proportional with different and default parameters without the ugly define, since simgraph16.cc is now C++ (since some time actually) and hence also get rid of these flags.

Quote
Almost all button init() sets the size to koord( D_BUTTON_WIDTH, D_BUTTON_WIDTH ). I made it possible to exclude the size and have the Init() to set them to the default size for that control. You can still override this in the init() by setting the size parameter. If this isn't still enough you can set a new size after the init() call.
Quote
Well, I already said, I could imagine a init for every version. If needed for the init to have more parameters, would hiding it in the derived classes will make it inaccessible for the public caller or not? The situation which must be avoided, it init( pos, size ) called on something which needs init( pos, size, stuff ); One could then pass a static size (-1,-1) which would be the default size.

Also some buttons are doing something else, like the pos buttons. Maybe those needs to be an own class.

Quote
Do we have support for transparent images now?
1 bit transparency since ages; but there could be a parameter in the theme tab (which for instance would define menu positions, tool sizes and so on) to draw the the background with xx % transparency. Such routines exist.

About alignment, I think we should have two align functions, one with one control, and one with two controls. Since most time you need the vertical only, we shoudl consider passing NULL then for the first parameter.

EDIT:
I forgot, I could not download your zip file.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 12:53:14 PM
Thank you Prissi for the clarification of tabs & spaces, lets move on...

Quote
I could not download your zip file.
Strange, the url is http://simutrans-germany.com/files/upload/SimutransTheme_r28.zip Maybe you can browse manually to get it? The link and zip archive works fine from here  ???
Does any one else have a problem to get the document?

Regarding my smaller patches, what is the plan in your end?
To receive ALL the patches before a trunk merge or to merge them one by one? I'm trying to create patches that will not break the current GUI, so we can merge them "silently". If your plan is to wait for all the patches, I will have quite difficult to keep my main trunk (your trunk) up to date with my patches.

Quote
You can obvjously now have more than one display_proportional with different and default parameters without the ugly define, since simgraph16.cc is now C++ (since some time actually) and hence also get rid of these flags.
I do not know how these flags are used, but I will do my best to fix this. If the flags are to be removed, I have no objection at all to share alignment enum :)

For the hidden Init() function, it depends on the pointer type. If the pointer is of the base class type, all it knows is the init(pos,size) and that will be use. This makes sense because if you do use the base class you don't know what type of control it is, unless you do a dynamic cast that will give you the correct pointer. If you use a pointer of the correct type the Init(pos,size) will stay hidden and not be accessible. This makes sense because now you know the interface and how to use the extra params.

Quote
Quote
Do we have support for transparent images now?
1 bit transparency since ages; but there could be a parameter in the theme tab (which for instance would define menu positions, tool sizes and so on) to draw the the background with xx % transparency. Such routines exist.
Yes I know about the transparent mask (1bit) and I have seen some Alpha drawing stuff in the code. The themes could really benefit from drawing with an alpha plane (24bit png). This would make it possible to do overlays and hence keep down the number of images. The question is, would it be to slow to draw?

To make window backgrounds semi transparent sounds like an excellent idea! There could be one transparent level for inactive windows and another setting for active windows  :D

Quote
About alignment, I think we should have two align functions...
It might be very useful if I implement anchor points support further down the road. I think this would come naturally when needed. I will keep it in mind...

Quote
While you're rewriting the gui, do *not* use the koord class.
I was told to use it, but I think you are right. It feels a bit awkward to use the koord type.

I'm a bit used to Windows and they use a POINT (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx) type for x,y screen positions and a RECT (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx) type (x1,y1,x2,y2) to place a rectangle on screen.
I have seen a similar type for clipping regions in the code.

I might suggest a screen point class (SIMPOINT) similar to Win32 POINT and maybe a Rect class (SIMRECT) like (x1,y1,x2,y2) with helper functions like get/set width(), height().
Should a screen coordinate be of the type sint32 or sint64?

Quote
char* x; is a good declaration, char *x; is a hard-to-read muddle.
I totally agree with you.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 01:48:17 PM
I'm trying to figure out how to remove the DT_CLIP and DT_DIRTY flags.

Code: [Select]
int display_text_proportional_len_clip(KOORD_VAL x, KOORD_VAL y, const char* txt, text_attribute_t flags, PLAYER_COLOR_VAL color_index, long len);
/* macro are for compatibility */
#define display_proportional(     x,  y, txt, align, color, dirty) display_text_proportional_len_clip(x, y, txt, align | (dirty ? DT_DIRTY : 0),           color,  -1)
#define display_proportional_clip(x,  y, txt, align, color, dirty) display_text_proportional_len_clip(x, y, txt, align | (dirty ? DT_DIRTY : 0) | DT_CLIP, color,  -1)

How would you propose we deal with it? Why where they moved into the enum in the first place?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 02:13:09 PM
Regarding coordinate types.

After some thinking there are 3 kinds of coordinates:

1. Map coordinates x,y,z
2. Screen coordinates x,y
3. Client coordinates x,y

Map coordinates are a virtual system placing map objects in a 3D space.
Screen coordinates doesn't need to have a negative representation because they are mapped 1:1 to the screen device. These can be unsigned.
Client coordinates are relative to their parent client area or other GUI objects. These needs to be signed.

It might be a good idea to separate these 3 types, not only because of their range, but also for type checking and guide the programmer what type of coordinates are expected in a call.

What are your thoughts?
Title: Re: [Project] GUI Theme
Post by: kierongreen on June 24, 2013, 04:33:55 PM
The alpha image code that is in trunk does not support 32bit images. It takes the current 15bit images and plots using a 5bit alpha channel which is either the red, green or blue channel of another image.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 04:56:47 PM
More alignment enums...

Found this one in gui_label_t

enum align_t {
  left,
  centered,
  right,
  money
};


It will be tricky to replace this with he now global alignment enum. Now MONEY, DT_CLIP and DT_DIRTY don't belong in there.

But again, this still looks like TEXT_ATTRIBUTES to me... What happen if we add Shadow (very likely since we need this in the gui_label_t), Bold and Italic?? They don't have to do anything with Aligning objects.
One way would be to distinguish text attributes such as; money, justified, shadow, bold, italic as a second parameter in the text draw call. Having one parameter for alignment and one for text attributes.
Title: Re: [Project] GUI Theme
Post by: Ters on June 24, 2013, 05:40:28 PM
Money can actually be a valid alignment, though I haven't checked if it's used that way. Numbers in general have special alignment rules, which may vary between locales. Some of it can be done when formatting the text, some can be done by splitting the label into different parts, but I can imagine having the label control itself do some trickery is easiest. Especially if there is no way to split the label so that it works for all languages.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 06:37:31 PM
I manage to get around the enums for now.
I will deal with the label stuff later when I get deeper into the GUI classes.
Title: Re: [Project] GUI Theme
Post by: prissi on June 24, 2013, 10:23:52 PM
Going backwards:

Labels should get a proper format parameter, if ever bold etc is added. As such, money could be also a formatting option.

Most of the simutrans code use "char *str" which I personally also prefer. Again something to do, when tweaking a beautifier.

Screen coordinates can be negative. You can move a window out to the left (and it is fully intended to allow this, especially on small screens).

I would keep only one screen koordinate class for points or rectangle size. Very often you only need to touch xy or size.

Btw, now the download works. In the end the interface should be kept as simple as possible. Otherwise we could just convert it to QT (or any other cross platform GUI) and then use these libaries instead. I am impressed, as this is the most visually appealing documentation simutrans ever had. It would be nice, if the interface at the very end is not more complex than now.

I will include patches, as soon as they are ready, or else they get bitrot too quickly.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 24, 2013, 11:11:01 PM
Thank you Prissi. Well writing documentation was one of my many task at the office :)

I have managed to "solve" the enum "problem" ;) and order is restored. This goes also for Tabs and spaces...

Regarding coordinate systems, well you are right and that I believe is usually called world coordinates in game engine terms, while screen coordinates is the physical screen. However we shouldn't over complicate this, so I agree with you.

Screen coordinates as sint32?
typedef sint32 screen_coord_t;
or
typedef sint32 sc_coord_t;
or
typedef sint32 coord2d_t;
...

I have also considered QT or other GUI framework, but I think this GUI will be less complex when we get the classes sorted out a bit.

Since I have corrected all the issues, I will put up a new patch that obsoletes the previous. I just saw that the trunk got updated so I need to merge, test and generate new patch files.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 25, 2013, 01:47:10 AM
Okay, here is the new patch.

This implements the frame work changes needed for the dialogue patches.

welt.cc is temporarily modded to behave as usual. It will get its own patch later.
Don't forget to add gui_komponente.cc to the project.

After applying this patch right out of the box, it should look just as usual. Set the define THEME_TEST to 1 (in gui_frame.h) to test the new stuff. This patch would mess up all dialogs (in THEME_TEST)  but the title height should be working everywhere.

It would be great if you could get this into the trunk so I can create the dialogue patches from there... I have already done a few that I can prepare right away when this is in the trunk.

Time for some sleep :P
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 08:02:43 AM
I just read all the above comments lightly (I'm sorry if I say something already discussed), but reading your patch:

gui_divider: Documentation is in german, translate it please.

+   enum divider_style_t {
+      kOut  = 0,  //@< 2px divider out
+      kLine = 1,  //@< 1px divider higlight line
+      kIn   = 2   //@< 2px divider in
+   };

 kOut this hungarian notation it's not conformant to simutrans names. Not that I really care much (I really think we tend to focus too much in style and things like char *p vs char* p are equivalent and irrelevant to me), but pointing it.

 About the screen coorditates, a sint32 type should be enough, and yes, screen coordinates should not be KOORD_VAL, agree with neroden and many others thgat expressed so before and after.


 gui_komponente.h

align_to documentation names are not consistant with the code.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 25, 2013, 10:39:53 AM
I don't speak German but I will do a try to translate...

The divider_style_t  and align_to() documentation must have slipped through. I was up all night, you can truly call this a night build :)
Prissi, I have made the changes, is it okay if you get them in the next patch (first dialogue)?
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 11:41:20 AM
I don't speak German but I will do a try to translate...

 Do as I do, translate.google.com , zeichnen is "draw", "bild" is image, "besch" is "descriptor", "welt" "world", "wasser" "water", "mit" is "with", "groesse" is "width" or "dimension". Also germans like to use "k" instead of "c". Easy language! ;) (not at all, even it looks it was not so hard for Guardiola. ;) )
Title: Re: [Project] GUI Theme
Post by: prissi on June 25, 2013, 02:01:11 PM
groesse is rather best translated as size ...

Since everything that draw on the screen is ultimatively a KOORD_VAL (in simgraph) I am for s_coord_t( KOORD_VAL, KOORD_VAL )
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 02:43:24 PM
why not extending it to 32-bit? 32.000 pixels wide can be achieved maybe some day, on multi monitor, and yound 32-bit aritmetics should be fast enough today.
Title: Re: [Project] GUI Theme
Post by: Ters on June 25, 2013, 04:08:32 PM
At such resolutions, the lack of memory in a 32-bit process will likely be another limiting factor, not to mention trying to push all those pixels through the bus. I don't think switching KOORD_VAL to 32-bit will hurt, since I can't remember seeing enough of them for the memory savings to be significant, but I don't think Simutrans will gain much from a change either, unless 16-bit operations are becomming seriously slow on modern processors.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 25, 2013, 04:18:36 PM
Well, a 16bit signed type would represent about +/-32 700 pixels and a 32bit signed around +/-4 147 000 000. I think we will do fine with 16bit even on multi display system. I have dual system and even if I where to use 3 of my hires monitors I would still only get up to 7680 pixels. So there is quite a bit to 32000.

However, I do strongly recommend to keep the two types apart. One type for map coordinates and one for screen coordinates. Not only to give any programmer a hint about what coordinate system he works with, but also to be able to change the type independently in the future.

If the code would run better on 16, 32 or 64 bit, it is very easy to select and adjust.

I made an s_coord_t, point_t and rect_t. s_coord_t is just a type while point_t and rect_t are structs with member functions and operators.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 04:23:00 PM
The other day a workmate of mine was testing a triple monitor configuration and he was at a around 6.000 pixel wide configuration, that's still far from 32.000 but who knows what will technology bring us in the future, being the cghhange so simple and carrying so little performance downsides, I'd just change to 32-bit and forget about the problem forever.

 Yes, the bus can be a problem at 32.000 wide pixels, but when that time comes we maybe render that with OpenGL or the buses will be fast enough. Maybe.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 04:29:00 PM
I have dual system and even if I where to use 3 of my hires monitors I would still only get up to 7680 pixels. So there is quite a bit to 32000.

 Yes, but for example multiplying or making mean of screen positions (fore example (2*x0 + 2*x1)/2 ) can get us closer to the overflow when we get closer to 16-bit limit. Why risking ourselves to get close to that limit when we can just use 32-bit that all modern CPU treat as a default size.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 25, 2013, 04:31:41 PM
Agree, sint32 then :)
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 04:45:59 PM
btw, Max-Max, I just opened your documentation and well, as you know we programmers don't read documentations much, because that's well, too boring. ;)

 But I have to agree with prissi it's the best documentation related to simutrans code I've ever read.  Congratulations and good job.  I wish we all programmers whould document things like you, things whould be way easier. :)
Title: Re: [Project] GUI Theme
Post by: Ters on June 25, 2013, 05:00:43 PM
Since multiplying 16-bit values yields a 32-bit value on x86, and a division with 16-bit result takes a 32-bit dividend, such calculation may actually be safe if the compiler is smart enough.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 25, 2013, 05:36:20 PM
you can also say that could be a unexpected behaviour and that the multiplication should overflow since you didn't explicitly cast to 32-bit. Well, I don't know, but you can't really depend on that, I guess.
Title: Re: [Project] GUI Theme
Post by: prissi on June 26, 2013, 12:58:42 PM
IF any screen related coordnate is from the KOORD_VAL, then the size could be increase quite easily afterward or whenever needed by jsut changing KOORD_VAL.

I still have to look at the patch, I was too busy yesterday.
Title: Re: [Project] GUI Theme
Post by: Markohs on June 26, 2013, 01:11:36 PM
But it we are talking about making screen coordinates differ from in-game coordinates, doesn't make more sense to name them differently? Maybe rename KOORD_VAL to SCREEN_COORD  (finally translating it ) and MAP_COORD (maybe not necesary since we have already koord and koord3d) when appropiate.

 I don't understand why are we respecting this old code so much, with this attitude we'll never make significant progress in code translating and improving.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 26, 2013, 04:01:44 PM
I have prepared a point_t and a rect_t (not included in this patch).

Should we translate KOORD_VAL to SCREEN_COORD_VAL and point_t (new type) to SCREEN_COORD.

The point_t have these members:

tag_point_t()
tag_point_t(s_coord_t x_par, s_coord_t y_par)
bool operator ==(const tag_point_t& point_par) const
bool operator !=(const tag_point_t& point_par) const
tag_point_t operator +(const tag_point_t& point_par) const
tag_point_t operator -(const tag_point_t& point_par) const
tag_point_t& operator +=(const tag_point_t& point_par)
tag_point_t& operator -=(const tag_point_t& point_par)
void add_offset(s_coord_t delta_x, s_coord_t delta_y)
void set(s_coord_t x_par, s_coord_t y_par)
void set(const tag_point_t& point_par)


s_coord_t would be the SCREEN_COORD_VAL and point_t would be SCREEN_COORD.

So KOORD_VAL would be refactored to SCREEN_COORD_VAL when used in Screen operations.
koord would be refactored to SCREEN_COORD (the new point_t) where appropriated.

Correct?
Title: Re: [Project] GUI Theme
Post by: prissi on June 26, 2013, 09:35:15 PM
Actually, I thought that s_coord( KOORD_VAL, KOORD_VAL ) (or maybe renamed by search and replace throughout the code to SCREEN_COORD_VAL) should behave like you new point class. Actually, point_t is imho no a good name; we have koord. Thus it make sense to have screen_koord. I can like with scr_coord or even s_coord. By point brakes this logic completely.

Furthermore, I think it would make more sense to work on the gui component stuff first. If you want to try to make everything at the same time, nothing will be done.

About the patch: It certainly gets there.
Code: [Select]
+ /**
+ * Pre-defined divider line styles
+ * Values > 2 creates an inset bevel
+ * @author Max Kielland
+ */
+ enum divider_style_t {
+ kOut  = 0,  //@< 2px divider out
+ kLine = 1,  //@< 1px divider higlight line
+ kIn   = 2   //@< 2px divider in
+ };
is not explaining to me. What is an "inset bevel"? Also the diver style need to be addressed as gui_divider_t::xyz, so the should be meaningful names: LINE_DIVIDER=0, SHADED_LINE_DIVIDER=1, and INSET_BEVEL_DIVIDER=2 (whatever this is). The are only called a few time, and hence a meaningful lang name is useful there.

The code has still "fOffsetRemoval" a very non-simutransish variable name. Almost any name in simutrans is is lower case with "_" in it. (And secondly I though the prefix f is for float ??? ) Why anyway the offset removal of images? Those usually have an offset on purpose. Having it removed is against the intentions of the artist.

Why has the divider class a get_groesse? It set its size itself correctly and hence the base class could return the size?

Overall, mostly minor issues. If you want I can fix those.
Title: Re: [Project] GUI Theme
Post by: TurfIt on June 26, 2013, 09:59:47 PM
Also the diver style need to be addressed as gui_divider_t::xyz,

That's a scoped enum which is not legal C++98 (which I pointed out before...).
Are we moving Simutrans to C++11?

EDIT:
clarification - it's the divider_style_t::kIn references within gui_divider_t that are the problem.

EDIT:
reading comprehension issues...  I think you're saying divider_style_t::kIn should be changed in the patch to gui_divider_t::kIn (but with better names) which solves the scoped enum. So forget this whole post...
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 27, 2013, 01:16:20 AM
Quote
Actually, I thought that s_coord( KOORD_VAL, KOORD_VAL ) (or maybe renamed by search and replace throughout the code to SCREEN_COORD_VAL) should behave like you new point class.

I my previous post I asked what we should call them. I also suggested to call them SCREEN_COORD_VAL and SCREEN_COORD. So to make it even more clear. My suggestion is:

KOORD_VAL becomes SCREEN_COORD_VAL where appropriated.
koord becomes screen_coord where appropriated.
KOORD_VAL is renamed to MAP_COORD_VAL
koord is renamed to map_coord

This will give us in the end:

SCREEN_COORD_VAL
screen_coord( SCREEN_COORD_VAL,SCREEN_COORD_VAL )
MAP_COORD_VAL
map_coord( MAP_COORD_VAL,MAP_COORD_VAL )


The koord class do behave similar, but has a lot of map related functions, it's not a pure class for arbitrary coordinates.

Quote
...is not explaining to me. What is an "inset bevel"?
A bevel is a graphical element in many GUI. A one line border bevel is also called a Panel in GUI terms.
(http://docs.oracle.com/javase/tutorial/figures/uiswing/components/BorderDemo1.png)
A bevel with larger borders is usually used for buttons.
My intention was to have a bevel class because a divider is nothing else than a very thin bevel. I realised, as stated before, that the GUI needs to be overlooked and I will do this in a later stage.
The way the divider is drawn (originally), a height larger than 2, gives a lowered bevel. I will not do any further work to fix this one until later, but I at least made it a bit easier to work with than before...

Quote
Furthermore, I think it would make more sense to work on the gui component stuff first. If you want to try to make everything at the same time, nothing will be done.
I have not even started on the GUI yet :) I have my plan, but when I'm in every dialogue to fix the margin, height control spacing etc... I do use the divider and label class to replace the directly drawn directly element. This is why a few gui classes had some minor modifications.

Quote
Why has the divider class a get_groesse?
The D_DIVIDER_HEIGHT is the double size of D_V_SPACE to give a more relaxed spacing. The normally 2 pixel graphical representation of the divider line is centred in the D_DIVIDER_HEIGHT space but the divider component's bounding box is either the divider pixel height or D_DIVIDER_HEIGHT, what ever is the largest of them.

Quote
The code has still "fOffsetRemoval" a very...
As I stated earlier, I have already corrected these few things that slip through and asked if it was okay to include them in the next patch.

/**
 * Pre-defined divider line styles
 * Values > 2 creates an lowered bevel
 * @author Max Kielland
*/
enum divider_style_t {
  DIVIDER_RAISED  = 0, //@< 2px divider raised etched
  DIVIDER_LINE    = 1, //@< 1px divider line (SYS_COL_HIGHLIGHT)
  DIVIDER_LOWERED = 2  //@< 2px divider lowered etched
};


So the bottom line is, again: Is it okay if you get these changes in the next patch? Or should I make a new one again?
Title: Re: [Project] GUI Theme
Post by: prissi on June 27, 2013, 10:08:15 AM
Two thing to clarify:

Why has the divider a virtual get_groesse() method? It should make sure that groesse is always correct, then get_groesse of the parent class shoudl work fine.

I would leave koord for the moment and just focus on screen koord and screen_coord or scr_coord() (as they are used at many places) and SCREEN_COORD_VAL.

And why do you need to display an image without an offset. Usually it is an artists decision to have a small element with an offset.

And as said, I can integrate this today evening.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 27, 2013, 01:04:42 PM
Quote
Why has the divider a virtual get_groesse() method?
As I explained, I had in mind to divide this into more controls... You can remove the virtual since I will not do this rework now anyway. The overloaded  get_groesse() is not returning groesse, it is a calculated value. Trust me, it is needed to correctly draw and space the divider as I explained before.

Quote
And why do you need to display an image without an offset.
In the "old" skin system, the artist had to include left and top margins in the image. This was the only way to center an image inside a button because all buttons where of the same size. With this new system the buttons size can be of an arbitrary size and margins are defined in other ways. To properly display today's skin, the margin must be removed from the image. Other wise you can't centre an image inside a button properly. You will see this especially for a window's gadget buttons. By doing this you can still use the old skin files and the new theme files (without margins) and still show them correct.

This is what happend if you don't remove the image margin (look at window's the gadget icons).
(https://dl.dropboxusercontent.com/u/30024783/Untitled86.png)

This is how it looks when you do remove the image margin (look at window's the gadget icons).
(http://forum.simutrans.com/index.php?action=dlattach;topic=11914.0;attach=21600;image)

Would be so kind and do the modifications for me:

gui_image.h
void enable_offset_removal(bool offset_removal_par) { set_image(id,offset_removal_par); }

gui_divider.h
Code: [Select]
class gui_divider_t : public gui_komponente_t
{
public:

/**
* Pre-defined divider line styles
* Values > 2 creates an lowered bevel
* @author Max Kielland
*/
enum divider_style_t {
DIVIDER_RAISED  = 0, //@< 2px divider raised etched
DIVIDER_LINE    = 1, //@< 1px divider line (SYS_COL_HIGHLIGHT)
DIVIDER_LOWERED = 2  //@< 2px divider lowered etched
};

gui_divider_t(void) { groesse.y = gui_divider_t::DIVIDER_LOWERED; }

void init( koord xy, KOORD_VAL width, KOORD_VAL height = gui_divider_t::DIVIDER_LOWERED ) {
set_pos( xy );
set_groesse( koord( width, height ) );
};

/**
* Set the divider's width
* @author Max Kielland
*/
void set_width(KOORD_VAL width) {

set_groesse(koord(width,groesse.y));
}

/**
* Get this component's bounding box size.
*/
virtual koord get_groesse() const {

return koord(groesse.x,max(groesse.y,D_DIVIDER_HEIGHT));
}

/**
* Paint method
* @author Markus Weber
*/
void zeichnen(koord offset) {

KOORD_VAL h = (groesse.y == DIVIDER_LINE) ? 1 : ( (groesse.y == DIVIDER_RAISED) ? 2 : groesse.y );
KOORD_VAL align_y = D_GET_CENTER_ALIGN_OFFSET(h,D_DIVIDER_HEIGHT);

display_ddd_box_clip(
pos.x + offset.x,
pos.y + offset.y + align_y,
groesse.x,
groesse.y,
SYS_COL_SHADOW,
SYS_COL_HIGHLIGHT
);
}

};

Thank you Prissi...
Title: Re: [Project] GUI Theme
Post by: Markohs on June 28, 2013, 07:49:36 AM
While doing this patch, that is deep enough to break any patch that was related to the gui.... Doesn't make sense to finally translate get_groesse to get_size and zeichnen to draw?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 28, 2013, 11:57:43 AM
Yes it does, but should we not make this in small steps?

I really want to refactor the German names in the GUI. But I think we need to make it as a separate patch.
I'm planning to go deeper into the GUI, maybe the refactoring would be a good start.
Title: Re: [Project] GUI Theme
Post by: prissi on June 29, 2013, 09:22:19 PM
Whole family had caught a bug. I will start now, so you are not forgotten.

EDIT:
- Should not the gadget size be taken from the actual gadget?
- Should not gui_image_t also get an alignment parameter; in this case even ALIGN_CENTER_V and ALIGN_CENTER_H makes sense? It would then align the element in the middle.
- editfield and normal button different height will almost certainly lead to ugly dialogues. Furthermore, if too small to be caught be finger for switching, it will be also too small for editing, or?
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 01:24:34 AM
- Should not the gadget size be taken from the actual gadget?
Yes it will even be its own button type, for now it is only there for test purpose.

- Should not gui_image_t also get an alignment parameter; in this case even ALIGN_CENTER_V and ALIGN_CENTER_H makes sense? It would then align the element in the middle.
Good point! I will have a look at it.

- editfield and normal button different height will almost certainly lead to ugly dialogues. Furthermore, if too small to be caught be finger for switching, it will be also too small for editing, or?
No, the dialogues looks beautiful with larger buttons and smaller edit fields :)
If you create a theme targeting touch devices you can of course configure it to be a large edit field. The point is that the edit field can now have its own size.

Thank you for the trunk update.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 02:54:06 PM
I saw that you had changed the default divider style from lowered to raised. I know that the raised was the previous, but the lowered is more discreet and doesn't clutter the GUI as much as the raised version does. I'm especially thinking when it is between buttons.

Have a look in my sample picture above this post to see what I mean.
Should we change it to default lowered?
Title: Re: [Project] GUI Theme
Post by: Ters on June 30, 2013, 03:32:55 PM
Smaller edit fields works as long as they're not on the same line as buttons. But in that last screen shot, I find that the edit fields, arrows and check boxes are a bit too small compared to the buttons and the title bar.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 03:52:38 PM
I'm breaking the relation between the elements sizes. All element types can have an individual size for maximum customisation.

If you want everything to be of the same size, no problem. If you want everything to be in different sizes, no problem either it is up to you how you customize your GUI interface. Above is my test case for the moment, so I can spot if I have converted each dialogue correctly.

Back to the last question, dividers, lowered or raised as default?
My argument is that a divider is a subtile GUI element and a raised divider makes the GUI cluttered.
Title: Re: [Project] GUI Theme
Post by: kierongreen on June 30, 2013, 05:08:26 PM
Raised/lowered makes no difference as far as I'm concerned. I've seen both styles in different GUIs so I'd stick with what we have.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 10:18:27 PM
Here is the adjusted Banner dialogue.

Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 11:08:17 PM
Here is the adjusted Option dialouge.

I did some minor rearrangement to group them a bit better; One column with settings and one with game related files.
(see attached picture).
Title: Re: [Project] GUI Theme
Post by: prissi on June 30, 2013, 11:10:01 PM
I just put the changes to the divider you proposed previously. So what init do you want?

And while smaller edit fields than buttons work on this dialogue, they look simply ugly as anything to me. Hence if all elements have custom sizes, designing a good and visual pleasing dialogue becomes almost impossible.

Looking at the banner patch:
At which state this dialogue was not scaleable previously? Just exchanged some magic numbers with some local defines. I am somewhat confused I admid. Also why removing the right alignment (according to the comment) of the image?

The Option should better become just a toolbar, it would be more Simutransish now. Thus I am ok with this layout anyway.

EDIT: Maybe one should change the dimenasion of banner too, so it gets as close as possible to the standard simutrans dialogue size.

EDIT: Your patch messes up convoi dialogues, station dialogues, depot dialogues. So far the slow transition is not working. Or you have to fix the scrolling regions.
Title: Re: [Project] GUI Theme
Post by: Max-Max on June 30, 2013, 11:58:07 PM
Quote
At which state this dialogue was not scaleable previously?
I'm not sure I follow you here... As far I have been playing Simutrans, this window has always been of a fixed size without possibility to scale it. Or have I misunderstood you... Did I step on someone's toes?

Quote
Just exchanged some magic numbers with some local defines. I am somewhat confused I admid.
As the comment state, these are there for tweaking and should be replaced when we have solved linespace vs shadow text "issue".
By replacing them with defines you only have to make the changes in one place, not every row where it is used. It will also make it easier to find % replace with the proper solution later.

The same goes for the banner scroller. With the defines you can set how many lines of text you would like to display and as the comment says, this should be a control on its own.

Quote
Also why removing the right alignment (according to the comment) of the image?
I'm confused too... I can't find any notes on removing right alignment in banner.cc or banner.h
The image is right aligned, so I don't know what you mean here.

Quote
The Option should better become just a toolbar, it would be more Simutransish now. Thus I am ok with this layout anyway.
I agree with you, it is not optimal as it is now. For example, you have to press "New Game" twice before you actually can start a new game. I think we are missing a main menu, as the most games have, where you can set options, load and start a new game. Then in game you can load/save, change options and quit to main menu (also called retire in many simulation games).

But first thing first...

Quote
Your patch messes up convoi dialogues, station dialogues, depot dialogues.
Do you run with the THEME_TEST setting or not?
Do you mean the scroller margin tot he dialogue border? Strange, I will look at it right away.

Quote
So far the slow transition is not working. Or you have to fix the scrolling regions.
Have you tried a "Clean solution" and build all? The scroller works fine here...
I have noticed that the graphic update (dirty areas) is not updated quite right. This issue has been there before I started to poke around in the code, so I don't think I'm to blame there...

EDIT: Oups, the last two answers got mixed up with the wrong questions, fixed now...
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 01, 2013, 12:51:22 AM
- messes up convoi dialogues, station dialogues, depot dialogues

I found it. I was a bit ahead of my own time :)
in gui_frame.h you will find

koord get_client_windowsize() const {
  return groesse - koord(
    D_MARGIN_LEFT + D_MARGIN_RIGHT,
    ( has_title()*D_TITLEBAR_HEIGHT ) + D_MARGIN_TOP + D_MARGIN_BOTTOM
  );
}


This returns the true client area of the window (inside the margins).
If you would be so kind and change it to:

Code: [Select]
koord get_client_windowsize() const {
  return groesse - koord(0, ( has_title()*D_TITLEBAR_HEIGHT ) );
}

This will fix it.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 01, 2013, 01:00:10 AM
Quote
I just put the changes to the divider you proposed previously. So what init do you want?
I would prefer DIVIDER_LOWERED as I mention earlier. Just change the divider.h back to as it was in my patch.

It will only be visible at places using the divider class (very few for now), but as I update the dialogues, I'm replacing the direct drawn dividers (raised) with the divider class (default lowered). Meanwhile you will experience a little bit of a mix between dialogues, but I guess we can survive that... :)

EDIT: Yea that's right, I gave you instructions... Just change the constructor and init from DIVIDER_RAISED to DIVIDER_LOWERED Thank you.

EDIT: I attached the divider.h
Title: Re: [Project] GUI Theme
Post by: prissi on July 01, 2013, 11:41:48 PM
Ok, now it hits the pakselector: The lowest pak is not selectable. Maybe treat this dialogue next?

And for elements, which exist only once (like the scrolltext in banner) I would not bother with a control.

Title: Re: [Project] GUI Theme
Post by: Max-Max on July 02, 2013, 12:09:25 AM
I saw that I have already fixed that in the pak selector dialogue (in my end), but this was an early conversion. I will run through it again to make some minor adjustments.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 02, 2013, 08:56:05 PM
I have fixed the Load/save dialouges.
They are now a bit more coherent. The Load Scenario dialouge's indentation is fixed.
The patch selector sets the button sizes to the needed text size. The Addon button will now always fit the text.
Title: Re: [Project] GUI Theme
Post by: prissi on July 02, 2013, 09:15:23 PM
At this point we probably need some discussion: The aim of the last (on glacially ongoing effort) was to have all simutrans dialogues initially with the same dimensions for practical (tileability) and beauty. Buttons that scale their size with the containing text will break this.

For loading an saving, there may be very long savegame names, even wider than the screen; Hence they need a sensibly maximum. But then, those dialogues does not needed to be tileable.

EDIT: With variable font sizes, we probably rather need also a variable with of that area. Like to Linespace a equivalent if the width of the Capital M/W or a Kanji (if there).

EDIT2: Also the divider is now over the button/label at the bottom.
Title: Re: [Project] GUI Theme
Post by: Ters on July 03, 2013, 04:33:47 AM
I agree that buttons should have a uniform size. (Toolbar buttons are considered distinct from normal buttons.) This is a rule in the vast majority of GUIs I have seen. The only exception I have seen are some confirmation dialog boxes where the safe button is larger than the unsafe button.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 06:36:37 AM
We are doing this in small steps, as requested. In the drafted specification I presented a solution of collapsing the GUI element when the space got cramped up. To be able to do that we need the client concept. At this point I'm only preparing for client step and later on the button text can adjust itself to the button.

When it comes to dialogue/window size, we can elaborate with them when the GUI can handle the collapse function.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 06:59:01 AM
Quote
Also the divider is now over the button/label at the bottom.
This can easily be adjusted through D_DIVIDER_HEIGHT in gui_frames.h

EDIT:
Hmm, where is it over the buttons? Is this in THEME_TEST mode or "normal" mode?

EDIT
I saw it in the pack selector now. It is only behaving like that in your trunk version. My local looks fine so something isn't merged right.
Since I'm a bit ahead of you it is difficult for me to compare my version with your trunk. If we can live with it for now we can continue until your and mine trunk are in synch, then I can investigate what is wrong here.
Title: Re: [Project] GUI Theme
Post by: eipi on July 03, 2013, 07:38:13 AM
It happens both in normal mode and in THEME_test mode, with and without the patch applied (at least for me).
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 07:39:06 AM
Where? What dialogue?

EDIT:
Have you applied the divider.h from (in SaveLoadDialogue.patch) and made a clean build?


Never mind, I started fresh and applied the patch, I can see it clear now... I have my suspicious...
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 08:20:59 AM
Okay, found it.

The gui_komponente_t serves as the base class for all components, but all members aren't virtual. The get_groesse() wasn't virtual and the divider's overloaded get_groesse() was never called.

As I'm a bit ahead of you, I had changed this in my end. You will find my gui_komponente.h attached here. Apply this path ontop of the previous one and it will fix the divider.
Title: Re: [Project] GUI Theme
Post by: prissi on July 03, 2013, 08:38:24 PM
Maybe you should use the OVERRIDE directive for the derived virtual get_groesse ?
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 08:49:37 PM
Isn't override a C++11 keyword? I got the impression (http://forum.simutrans.com/index.php?topic=11956.msg118278#msg118278) that we shouldn't use C++11 at all.

Quote
Scoped enums is C++11 (and apparently a non-standard MS extension). Simutrans still uses C++98 - best to set your compiler to that (and disable MS stuff).
Title: Re: [Project] GUI Theme
Post by: prissi on July 03, 2013, 09:11:20 PM
There is OVERRIDE, which is defined of used and otherwise without function.

Back to the patch: The divider is fixed, but the scrollbar is not at the right window border. This makes the dialogue look very strange. Furthermore, while you at it: It would be nice if the scrollbar is hidden, if there is nothing to scroll.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 03, 2013, 09:24:00 PM
Quote
...but the scrollbar is not at the right window border.
This topic has already ben up and commented here (http://forum.simutrans.com/index.php?topic=11956.msg118351#msg118351)

...scrollbars are moved inside the margin. This is because the window border will be drawn in the margin and the margin will be decided by that border later on.

When the windows border is drawn with the theme images, the client area will be right next to the drawn border, and the margins you see now will be no more. When the client concept is in place, we can discuss if controls should move in one by one or if a padding inside the client should be applied. But that is further down the road...

EDIT:
Regarding override. Is it a praxis in this project to always use OVERRIDE after functions overriding virtual functions? As I understand, the keyword override is of none technical use other than telling sloppy programmers that they have done a mistake  :::)

EDIT:
It would be nice if the scrollbar is hidden, if there is nothing to scroll.
I have in fact already modified the scrollbar to hide the knob if it shows 100% of its content and I was thinking to disable the arrows as well. I can implement an auto scrollbar mode, meaning in auto mode the scrollbar is hidden completley, and in non-auto mode the scrollbar is empty and disabled. Sounds good?
Title: Re: [Project] GUI Theme
Post by: prissi on July 04, 2013, 09:40:22 PM
Sorry, the scrollbar not at the dialogue corner is really a show stopper. No one will expect a scroll bar at a random position without a visible box. This just breaks user expectation. (And just using the margin only for scrollbars makes some sense. Then would the useable area without a scrollbar (because everything is visible) be nearly the same as with a scrollbar.

Since we obviously disagree on this point, I would like to postpone any scrollbar repositioning until other commented too.

Following up my above comment: I would go for a completely hidden scrollbar, if the knob size is 100%. But also for this additional comments for others are highly welcome.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 05, 2013, 04:19:26 AM
The scrollbar position inside the margin is not a permanent solution. It is one phase towards the theme implementation. When the client concept has been implemented, the scrollbar will end up line-by-line with the window border, just as it is now. If you want to wait for the client and border theme phase to finish, you will get a hell of a patch to implement later :)

I made a mock-up (Mockup.png) of what it would look like with Prissi's request. The scrollbars are drawn over the window's border.
With my final implementation the scrollbars will end up just inside the yellow border (Client.png) where the window's client area is.

So what do you want; Mockup or Client?

Quote
No one will expect a scroll bar at a random position without a visible box
I don't get it? What is at a random position and what box is missing?
Title: Re: [Project] GUI Theme
Post by: Markohs on July 05, 2013, 12:54:40 PM
Client looks way way better than mockup imo.
Title: Re: [Project] GUI Theme
Post by: Fabio on July 05, 2013, 12:57:21 PM
Client looks way way better than mockup imo.

+1
Title: Re: [Project] GUI Theme
Post by: Ters on July 05, 2013, 02:12:34 PM
Client looks way way better than mockup imo.

The light brown frame rules out any ability to disagree with that. With a frameless look like Simutrans has now, mockup might have a slight lead.
Title: Re: [Project] GUI Theme
Post by: IgorEliezer on July 05, 2013, 02:19:26 PM
*faints*

Dear! What a nice UI we've got there.

It seems Simutrans 2.0 on the way.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 05, 2013, 03:45:09 PM
Quote
With a frameless look like Simutrans has now, mockup might have a slight lead.

That is the whole point with a theme, if you want a window without a border, you just design it with a 0 pixel border in the theme image. The look and size of the border is not fixed at a built in size, it is decided by the theme. The "border less" look we have to day is in fact a 1 pixel border.

What Prissi is referring to as a show stopper, is that before we get to the point of a client concept, all controls are moved in from the border, as a preparation for the client concept. This looks a little bit ugly because there is no theme to paint yet.

Why not implement client concept right away?
In the client concept a parent translates the coordinate system to its own client area and passes this down to the children. All GUI controls needs to be adjusted to work with the fact that the coordinate system has already been translated.

I did that at first but was told it was unaccepted because the GUI was really screwed up. I could do it all at once, but then the patch would be to big to implement. It doesn't matter how much we debate about the implementation as long we want small patches, we do get some "ugly" phases before it is fully implemented.

To get an understanding of what Prissi actually is referring to, I have attached the picture "Ugly.png".
This can already now be less Ugly by just changing the D_MARGIN_XXXX and D_DIVIDER_HEIGHT to something more balanced like 5 or 3 for D_MARGIN_XXX and D_V_SPACE+2 for the DIVIDER as in this picture "LessUgly.png"

EDIT
Later D_MARGIN_XXX will be replaced by the client area, where the client area's origin and size is defined by the theme's border.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 05, 2013, 04:03:56 PM
@Max-Max (http://forum.simutrans.com/index.php?action=profile;u=10153)

impressive work ... :thumbsup:
Greetings....!!
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 05, 2013, 06:09:27 PM
Thank you for all the response. I just want to make it clear that both the Mockup.png and Client.png are Mockups. This is the vision of the theme system and we aren't there yet.
Title: Re: [Project] GUI Theme
Post by: prissi on July 06, 2013, 09:41:30 PM
I think you concept of simutrans windows got something wrong. The border of a window should not matter. I.e. get_groesse is the CLIENT area. Almost any elements but scrollbars should not extend (for VISUAL reasons) into a margin D_MARGIN_RIGHT. Scrollbars must extend there, as the posters above stated and you showed in the lower mockup.

Simutrans has a 1 pixel surround theme by the way: If you enable simutrans active window borders in simuconf.tab, you get already the look of number 2. So there is not much of a discussion, that was the place where the scrollbar was before your patch.

Less ugly image is actually more ugly for me. With an editbox (save window) it would be EvenMoreUgly ;)

I.e. scrollbar right at the right border of the window get_groesse size (which is the windows CLIENT area). Scrollbars without any offset. Because any window border would be window manager and theme dependent and must not affect the position of the client elements. They should not even know about the corder. (Like X windows: The interior of a dialogue does not change when changing the window manager.)

As a sidenote: from an ergonomical standpoint (and not from the window brainwashed GUIs) scrolling is much more often done than resizing. As such, a scrollbar at the border (especially with maximized windows) would be ergonomically preferred. They were actually also on the first, more research driven GUIs before MS had to reinvent the wheel to circumvent patents.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 06, 2013, 11:43:23 PM
First of all, the majority of the gui komponents are returning their bounding box on get_groesse(). I have found one exception and that is the chart_t control.
The window's get_groesse() (actually called  get_fenstergroesse) is returning the bounding box and get_client_windowsize() is returning the window's bounding box - title bar, so the gui isn't consistent.

I think we all agreed on that the GUI needs a deep overlook, this will also mean that some things will change. If we want everything to be like before, their isn't any point in remaking the GUI  ???.

What I have seen is that we need to make the GUI consistent:

get/set groesse deals with the bounding box.
get/set client size deals with a components client area. This has to be implemented in all gui controls, not only in the window.
The frame_t needs to be a more like a Window class, an aggregation of basic gui components to build the window.

Most of the gui components are derived from the base class komponente_t, even in cases when it is clear that they would benefit more from being derived from another gui component. There are also some very common component combinations that could be a component on its own. I have already sketched on a gui class hierarchy that would reduce code and take more advantage of OO Design.

The "active" border option in simutrans has always made me a bit puzzled... What is it good for? The active window changes colour anyway and it makes the tool menus look silly if the rows are of different length. I think we can let this one go to the history and instead improve the look of the active window. This thin line is also drawn outside the window's bounding box, it draws over the neighbouring window when snapping.

Now when we are targeting small screens as well (portable devices), all windows must be able to handle the given bounding box in the best way it can. If a windows border is thin, thick or borderless, the whole project would have failed if the window cant handle that :)

I have Google both BeOS, KDE, Mac OS and GTK, the majority of themes have a window border. In those rare cases where the scrollbar has been at the very edge, it was a borderless theme.
If MS screwed things up or not isn't really relevant. Today we are used to see things in a certain way and we have become to accept this as the "standard". You asked for the community's view in this subject and the few who left a comment where in favour for scrollbars inside the border.

I think this isn't really the time to argue about this because what it becomes at this stage is only temporary. I think it is more important that we can move on with the project and as I have explained several times; as long you want small patches, there will be some phases that looks a bit odd, this is one of them.

I will go through all the dialogues several times to slowly update them with the new gui stuff and structure, this isn't the final look and behaviour. I first need the tools to work with (client concept, gui components and structure) before we can get into details if a scrollbar should be placed a few pixels here or there. The best would of course be to make even this configurable :thumbsup:

I think I have spent more time to create mockups, write specifications and explain myself then I have been coding. So can we please move along?
Title: Re: [Project] GUI Theme
Post by: prissi on July 07, 2013, 09:17:57 PM
Sorry, the D_MARGIN_... is introduced as the space of an UI element from the border of the dialogue for esthetic reasons (balancing left and right borders).

Where the UI returns its bounding box? The only exception I can think of is the combobox, all other rather return their client area (and the chart is broken in this regard, agreed). Otherwise the internal event handling would not work. Thus for Simutrans I rather want to avoid the bounding box/client area altogether. It is simply not needed, and I see no sense in wasting time and adding complexity to add this to all controls.

gui_frame_t is not the place for drawing the border! Otherwise tool bars (cannot have meaningful border, as their size depends on the elements within) and banner could not be based on gui_frame_t. Simutrans is rather build like XWindows, where it is hard to get actually the size of your outer window. Thus window drawing is done by simwin.cc, and I see nothing to gain in changing it. Instead applying themes could be easily done by simwin (it must be anyway done by it through event handling requesting a resize of all windows).

Back to topic: Even in your mockup you drew the scrollbar with zero margin to the right. Same as all comments in this thread: Scrollbar margin is zero. D_MARGIN_ is not the margin to the outer window border, it is a border for the esthetics of the dialogue. You may want to introduce something like outer area for the window handler, but all simutrans dialogues were meant to deal only with client area.

The titlebar is a historic relic, since from the three original window classes one drew its titlebar itself, and not in simwin.cc. I am happy to set D_TITLEBAR_HEIGHT to zero at a certain point, I said this before. Then you have all get_groesse client area. No window should need to care about its outer diameter in simutrans, so please let us not add this to gui_frame_t. The window's outer extends belong to simwin.cc.

When you set a theme, the button and the sizes will change. The window has no need to find screensizes and the like. Dialogue layout (not just sizes) changing on screensize is imho neither realistic, nor feasible for simutrans, as such would void the existing documentation and the efforts to have ergonomically designed dialogues.

So lets get_groesse return the client area, and lets simwin.cc worry about drawing and overlapping borders and the like. Keep it simple and easy.
Title: Re: [Project] GUI Theme
Post by: Markohs on July 08, 2013, 12:28:33 PM
Keep it simple and easy.

 I think it should be easy for the user/theme designer, it doesn't really mean the code has to be simple. Sticking to simple solutions in code is not a good idea always and should not be a sacred design dogma.

 imho.
Title: Re: [Project] GUI Theme
Post by: prissi on July 08, 2013, 09:11:41 PM
It is not a dogma, but I still am not fully convinced that the concept of client area is helping for the relatively simple simutrans GUI. Especially since it did quite ok the last 13 years, and for scaling inside the dialogue I am not convinced the extra work is helpful. But again, you know I am slow to bent but can be convinced by arguments that the gain outweights the costs in complexity.
Title: Re: [Project] GUI Theme
Post by: Markohs on July 08, 2013, 09:19:03 PM
ofc, you both know about the issue more than me. :)

I just pointed we should not follow simplicity at any cost. Just simplicity against the user, not internally when it's going to cut out features. ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 12, 2013, 05:18:46 PM
I know this is a bigger patch but it is my trunk up to date.

* Theme Colours configurable through the theme/themes.tab file.
* Button's size are actual skin image size.
* Buttons, labels, text area use the new theme colours for Text, disabled text and static text.
* Various gui controls use the sizes set by button_t::gui_xxxx_size (set by skin image size).
* Fixed a bug where a pressed button was drawn in the same size as the normal button state, even when the images differed in size.

Prissi take your time with this one, I know it is bigger than expected but it updates quite a lot of skin/theme related functions.

I have to admint that I had forgot all about SimWin and was thinking that gui_frame was the Window class, so it was all my mistake. gui_frame_t is the client of SimWin :) They do go into each others terrotory and it is a bit confusing.

I know the scrollers aren't where you want them, but I will get right on to it as soon this patch is implemented. I think thw GUI needs to be cleaned up first before I move on with the theme.

So next up; bring some order in SimWin and gui_frame...

PS. Not all dialogues are converted yet, so other sizes than the defult will screw some things up. But at least, you can play around with colours ;)

I have attached a picture of actual implemented theming.
Title: Re: [Project] GUI Theme
Post by: Ters on July 12, 2013, 05:28:34 PM
This is looking good, though the old style title bar sticks out. The small line near the top of the language selection window seems a bit odd, though that might be how it is today.
Title: Re: [Project] GUI Theme
Post by: Dwachs on July 12, 2013, 05:50:55 PM
Looks great! I do not have time to participate in the discussion :/
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 12, 2013, 06:11:37 PM
I agree that the divider line in the language dialogue looks odd, but it is there in the original, it isn't simething that I have added.
I have not come to the title bar yet, that will be a bit further down the road...

I added the picture to show where we stand at this point, still a lot of work to do, but at least yu can configure some the colours now.
Title: Re: [Project] GUI Theme
Post by: kierongreen on July 12, 2013, 07:36:39 PM
Well done :) New theme certainly looks more modern (also important step to getting it working properly on tablets with larger buttons) although one thing I'd say that looking at the size of some of these dialogues I'm doubting that 640x480 will be that playable now. How easy is it for a user to configure simutrans to look how it does at present with the patch applied - to cater for players with old computers or who for whatever reason want smaller windows still?
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 12, 2013, 08:06:25 PM
The button size is adjusted to the theme, just use the old skin file and it is all as before.

You can control various elements (only buttons so far) in the new themes.tab file.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 12, 2013, 09:24:38 PM

ok I know I'm off topic
but I wondered if the button of "fixer  (http://img545.imageshack.us/img545/2638/g4b.gif) " has some function.
I think it does nothing  ???


this button  should keep the windows at the top in my humble opinion


view this example


(http://img546.imageshack.us/img546/1942/mq4v.png)

Title: Re: [Project] GUI Theme
Post by: Max-Max on July 12, 2013, 09:34:19 PM
I have been puzzled about that one too. I found out that it only works on vehicle info windows and has the same function as the "follow" button.

I had an idea earlier about to be able to pin a window in a "geo-stationary" position on the map. This would be very helpful when displaying stop and factory information (to pin the window near the stop or factory).

I guess the first step would be to just remove the pin where it isn't applicable for now.
Title: Re: [Project] GUI Theme
Post by: prissi on July 12, 2013, 10:24:35 PM
I think for the themes to work, some more special images has to go into themes skins. I can work on that too. I will try to get this in at teh weekend, as this is very nice progress.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 12, 2013, 11:19:26 PM
Take your time Prissi, I'm studying the SimWin and frame_t  right now...

This is my first thought in the matter from what I have seen so far.

A window can be owned by another window and thereby automatically be closed when the owner window close. It would be natural to derive the window from an appropriate komponente_t descendant and it will share the same code for message handling, hit testing, set and get size etc... as all the other components.

I'm aware of the magic number and the "class factory" that produce them. I will try to collect the relevant functions into a class.
The frame_t class is more like what is called a panel in GUI terms. The window class is simply a collection of a panel, a toolbar and a label. By using components for this we nicely get all the hit test in their resp. objects.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 13, 2013, 12:03:23 AM
Quote
I think for the themes to work, some more special images has to go into themes skins. I can work on that too. I will try to get this in at teh weekend, as this is very nice progress.

Actually I haven't added any new images yet, only implemented the use of the current skin definition. The current skin system wasn't fully implemented, I have only made it to respect the image size.

To make it work the dialogues needs to be updated so the buttons are align in relation to each other ;) ...and not to a fixed position. But I feel that we are missing the layout class to make this align nice and tidy, even for an arbitrary sized theme.

...and to do the layout class I feel that we need to clean up the current GUI structure a bit. Now code is repeated for the same thing in some gui classes.
Title: Re: [Project] GUI Theme
Post by: Ters on July 13, 2013, 09:34:13 AM
I have been puzzled about that one too. I found out that it only works on vehicle info windows and has the same function as the "follow" button.

I had an idea earlier about to be able to pin a window in a "geo-stationary" position on the map. This would be very helpful when displaying stop and factory information (to pin the window near the stop or factory).

I guess the first step would be to just remove the pin where it isn't applicable for now.

You're confusing the pin-button with the eye-button. The pin-button pins a window open so that it isn't closed by the close all windows function. A case where a sub-feature of a feature is more visible than the feature itself. Backspace is the hotkey for closing all non-pinned windows for me. As such, the pin is useful everywhere.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 13, 2013, 02:24:05 PM
Thank you Ters, yes, I remembered it wrong.

So the mystery has finally been solved :)
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 13, 2013, 05:57:19 PM

it can be make better use of this
because normally this is used to keep a window always visible, even if we are working with other



The majority of inexperienced players have no idea how to use that button
Would it not be wise to make this option more practical?
Title: Re: [Project] GUI Theme
Post by: Ters on July 13, 2013, 09:36:35 PM
The majority of inexperienced players have no idea how to use that button
Would it not be wise to make this option more practical?

That can be said for a lot of things in Simutrans, even the very basics like signals. The pin-button works more or less like any other pin-button I've seen. I must admit that I have never used the pin-button in Simutrans, but that is because I have never memorized the hotkey for closing all non-pinned windows.

it can be make better use of this
because normally this is used to keep a window always visible, even if we are working with other

I have never seen a pin used for this. Nor do I see much use for it, because it is hard to use a window you can't see. Perhaps the only window big enough to be interacted with even when partially covered is the minimap. One thing I have seen pinning used for is to prevent a window from being reused, but Simutrans always opens new windows.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 13, 2013, 10:48:48 PM

as you can see in this example, the video window this fixed
(http://img546.imageshack.us/img546/1942/mq4v.png)
this means that I can do something else while I watch the video


 is can take advantage advantage of this, especially when working with many windows
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 14, 2013, 01:59:30 AM
Prissi,

I saw that you got map_frame.cc by accident. It isn't finished yet and looks a bit odd. Don't update that one if possible.
Title: Re: [Project] GUI Theme
Post by: Ters on July 14, 2013, 06:57:08 AM
as you can see in this example, the video window this fixed

this means that I can do something else while I watch the video

is can take advantage advantage of this, especially when working with many windows

I haven't seen a pin used for this, and to me a pin is a non-intuitive icon for this, as they make things stick not float. (A binder perhaps, but that could also imply that a window should stay on top of a specific window and move along with it.) Having windows floating on top is sometimes useful on the OS level (Windows is lacking this as a general window feature), but I can't see which windows benfit from it in Simutrans. At least not useful enough that it can ursurp the pin, it would have to be another button or I can imaging people complaining about losing a feature. It would mean a lot of buttons in the title bar.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 14, 2013, 11:56:21 AM


I haven't seen a pin used for this, and to me a pin is a non-intuitive icon for this, as they make things stick not float. (A binder perhaps, but that could also imply that a window should stay on top of a specific window and move along with it.) Having windows floating on top is sometimes useful on the OS level (Windows is lacking this as a general window feature), but I can't see which windows benfit from it in Simutrans. At least not useful enough that it can ursurp the pin, it would have to be another button or I can imaging people complaining about losing a feature. It would mean a lot of buttons in the title bar.


I thought you could use the pin button for both functions


anyway this is just an idea ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 16, 2013, 07:05:04 PM
How is it going?


I'm leaving for a 2 week vacation this Friday. I was hoping to get a fresh trunk with me to code while I'm away :)

I have translated

get_groesse() to get_size()
set_groesse() to set_size()
koord groesse to koord size
zeichnen() to paint()
set_fenstergroesse() to set_window_size()
get_fenstergroesse() to get_window_size()
getroffen() to is_hit()


The question is if I also should translate gui_komponente_t to gui_component_t ??
Title: Re: [Project] GUI Theme
Post by: Markohs on July 16, 2013, 07:31:34 PM
I'd prefer "draw" instead of "paint"
Title: Re: [Project] GUI Theme
Post by: prissi on July 16, 2013, 09:38:09 PM
The simutrans way would be rather display instead paint, as there are so many display routines in the code.

Some comments:
Scrolltext is not a gui component to have it harder to modify. Also one off stuff does not need to be a component imho.
Clipping of buttons in a scrollpane was not working for too long button texts
The convoi filter is all entries oon the same line now. But do not bother too much filter dialoges. They will be anyway make by the new list control, as almost any of them has waytype, name and some other common filters.
Title: Re: [Project] GUI Theme
Post by: Markohs on July 16, 2013, 10:17:33 PM
Precisely because "display" is usually associated to routines that display images, I'd use "draw", that gives the idea that it might not use just one image, but lines and other artifacts too. Anyway if display is choosen, I don't mind, just not "paint".
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 16, 2013, 11:14:05 PM
I'm just guessing here, but I think the majority has some experience of Windows nomenclature. WM_PAINT is the message that does exactly what zeichnen does. In VCL and FireMonkey (C++ and Delphi) there is a callback named Paint(), doing the same thing.

Draw is more like shapes, such as DrawLine(), DrawPolygon(), DrawElipse() etc...

Regardless of what we all think about Windows, a lot of people have experience from Windows and would easily understand the concept if we use the same nomenclature for their equivalent. This might speed up the learning curve for new coders...

What does other in the community think?

What about renaming gui_komponente_t to gui_component_t ?
Title: Re: [Project] GUI Theme
Post by: prissi on July 16, 2013, 11:21:10 PM
In simutrans everything that draw something, no matter if texts convois or whatever uses display. As such I still vote for display. display_line, display_proportional_ ...

EDIT:
why did you change the "else if" to "else\n\n if" This is not the way it was used everywhere else and also inconsequental, because if you seperate those, you would need to indent.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 16, 2013, 11:23:30 PM
Just display() or display_<something>()
Title: Re: [Project] GUI Theme
Post by: isidoro on July 16, 2013, 11:24:20 PM
[...]
What about renaming gui_komponente_t to gui_component_t ?

If the German name is so clearly similar to the English name, is it worth the effort of translating it?  Besides, it gives an exotic touch to the code and make clear the origin of ST...
Title: Re: [Project] GUI Theme
Post by: prissi on July 16, 2013, 11:26:56 PM
I think just display().

But the way, in halt_list_frame.cc you use the button directly. Wouldn't it make sense to use the defines, sicne any further changes could be better followed by this (and it make also the code clearer).

EDIT:
Help frames scrollbars are almost gone.
The text in numberinput was 1 too high in new world.
Player list is very unbalanced now. I think this requires additional spaces between lines.
Minimap is also draw wrongly.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 17, 2013, 01:01:05 AM
Quote
why did you change the "else if" to "else\n\n if" This is not the way it was used everywhere else and also inconsequental, because if you seperate those, you would need to indent.

An old habit to write...

// comment
if(...) {
} else

// comment
if(...) {
} else

// default
{
}

...to make it look more like a switch case.
Is it on many places or can you manage to "correct" it if it is unacceptable?

Quote
Help frames scrollbars are almost gone.
My bad, replace resize with:

void help_frame_t::resize(const koord delta)
{
   gui_frame_t::resize(delta);

   KOORD_VAL generalwidth = 0;
   if(  scrolly_generaltext.is_visible()  ) {

      // do not use more than 1/3 for the general infomations
      generalwidth = min( display_get_width()/3, generaltext.get_preferred_size().x ) + button_t::gui_scrollbar_size.x;
      scrolly_generaltext.set_groesse( koord( generalwidth, get_fenstergroesse().y - D_MARGIN_TOP ) );

      koord general_gr = scrolly_generaltext.get_groesse() - button_t::gui_scrollbar_size;
      generaltext.set_groesse( general_gr );
      generaltext.set_groesse( generaltext.get_text_size() );

      generalwidth += D_H_SPACE;
      scrolly_helptext.set_pos( koord( D_MARGIN_LEFT + generalwidth, D_MARGIN_TOP) );
   }

   scrolly_helptext.set_groesse( get_fenstergroesse() - koord( generalwidth + button_t::gui_scrollbar_size.x - D_H_SPACE, D_MARGIN_TOP ));

   koord helptext_gr =  scrolly_helptext.get_groesse() - helptext.get_pos() - button_t::gui_scrollbar_size;
   
   helptext.set_groesse( helptext_gr );
   helptext.set_groesse( helptext.get_text_size() );
}


(I figure it is easier to just copy paste than explaining exactly where to change).

Quote
The text in numberinput was 1 too high in new world.
I have not touched that one yet, that is probably why... It will be al right as soon I update that dialogue. Is this really a show stopper, one pixel?

Quote
Player list is very unbalanced now. I think this requires additional spaces between lines.
They are spaced D_V_SPACE vertically and D_BUTTON_WIDTH in size.
I think the best would be to have them resized with the window.

Quote
Minimap is also draw wrongly.
I notified (http://forum.simutrans.com/index.php?topic=11956.msg120071#msg120071) you about this. It was added by accident. If you would be so kind and not update the minimap (if possible).

Do we have any show stoppers, or can we live with this until next patch?
Title: Re: [Project] GUI Theme
Post by: prissi on July 17, 2013, 09:47:42 PM
Actually I submitted your code with those problems (as you have probably noted). I would be just grateful for a correction patch whenever you have a simple solution, especially for dialogues more or less severely misaligned as mentioned in the postings above.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 19, 2013, 08:49:25 PM
I am in Bulgaria right now on vacation. But I have everything in my laptop. I will send you an emergency fix as soon I get the time and internet connection...
Title: Re: [Project] GUI Theme
Post by: Fabio on July 19, 2013, 08:54:15 PM
enjoy your vacation! have fun!!!
Title: Re: [Project] GUI Theme
Post by: prissi on July 19, 2013, 09:34:45 PM
Do not, enjoy your vacation. SImutrans can wait.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 24, 2013, 03:00:46 PM
Today it is my birthday so I will give you a fixed map dialogue as a present :)

You have to add the new scr_coord.h and gui_map_preview.h/cc to the project.

Is there another way to display the relief map? I started to break out the code in welt.c into a gui_map_preview class, but Isn't it possible to use the same code used in the mini map?

The default static text color is a bit light, please feel free to find a better colour.

Still in Bulgaria, home in 12 days :)

EDIT
Removed the patch after I found some bugs. New patch coming soon...
Title: Re: [Project] GUI Theme
Post by: Fabio on July 24, 2013, 03:40:19 PM
Today it is my birthday so ...

Happy birthday Max! :cake:
Title: Re: [Project] GUI Theme
Post by: kierongreen on July 24, 2013, 03:44:11 PM
Indeed - Happy Birthday :) Also good on you for working away on this while away from home!
Title: Re: [Project] GUI Theme
Post by: isidoro on July 25, 2013, 12:02:07 AM
Happy birthday, Max-Max!  But you should be the one to receive the presents, not the one to give them...  :D
Title: Re: [Project] GUI Theme
Post by: prissi on July 25, 2013, 12:21:08 AM
Happy birthday, enjoy your holiday!
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on July 25, 2013, 12:31:10 AM
Happy birthday @Max-Max
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 25, 2013, 02:14:49 PM
Thank you every one.

I'm having trouble to apply my own patch... :(
The file gui/components/gui_map_preview.h and gui/components/gui_map_preview.cc is not created. I can see them in the patch file but when I apply the patch (TortoiseSVN apply patch -> all) they aren't created...

What have I done wrong?
Does any one else have the same problem?

EDIT:
I noticed that the depot dialogue got mixedup a bit due to my changes in gui_label_t. I thought it wan't used. I will make a new patch shortly...
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 30, 2013, 08:44:18 PM
Well, here is a patch that will fix all the trouble I caused so far :o ...and some more.

* Map dialouge done
* Fixed help dialogue
* fixed depot image miss alignment
* fixed scrollbar auto hide
* fixed better string cap routine in Label and button
* Added THEME debug macro
* Fixed edit width in climates (themed)
* Fixed so an opened combobox follows the control when moved.
* gui_image_t got an alignment mode and an auto size mode.
* Added SYSCOL_BUTTON_TEXT

I fixed the annoying image miss alignment in the depot dialouge and implemented an auto hide scrollbar function (now default).
There is no previous way to handle a hidden scrollbar, so I draw a place holder instead. The best would be if the parent's client area where expanded instead, but we aren't there yet.

I had as usual trouble to get the new added files into the patch so I have attached theme separately. If the patch doesn't create:

in gui/components folder:
gui_image.cc
gui_map_preview.cc
gui_map_preview.h

in project folder:
scr_coord.h

please add them from the zip archive manually. Don't forget to add these files to your project as well.
It feels like I'm back on track again...

Title: Re: [Project] GUI Theme
Post by: prissi on July 30, 2013, 10:25:41 PM
Thank you, I have commited most of the code. As for the calculation og button sizes from their graphics, I have not yet submitted the define, as this will change anyway when doing it porperly after reloading from files defined in themes.

Soem further comments:

I have my doubts on the implicit conversion from  scr_coord to koord. If scr_coord is made 32 bit as discussed, it will silently produce errors.

Also I am not so keen of a default constructor for scr_coord. It shoudl have rather none if possible. Or when, then one which set them to some undefined value, imho.

And should rect be rather x,y and width and height? I though that was the consent form the other thread? Most UI elements have a size (which they care for) and a position (which often somebody else cares for). But I will submit it without this for the moment.

scr_coord is also defined unusually. Imho it is better anyway a class to define operators. (I have at least one compiler who does not like structs with operators.) Apart from the tag_... definition. Form me this file would be expected either in gui/ or into dataobj/? Also the set method and copy constructor is no needed, as it will be done right be the compiler anyway.

At the moment in buttons koord and scr_koord are happily mixed. But this is certainly a temporary state, or?

"size_mode_stretch" will most likely never come. It will be most ugly too.

A question of style is your par for your parameters. If you are afraid of changing them, you can make them cost; but the par is ugly in my eyes. But other may think different on that.

And finally, please no client rectangles. This is not needed, or please give an example where get_groesse is not sufficient. It will rather introduce new errors, and is another thing which needs to be initialized. A function for a contianer like GET_minimum_rect os so would be ok something much more useful and descriptive.

Autosizing buttons: How should you design a nice balanced dialogue with such buttons? I would rather add a function like for the flowtext, i.e. recalc_groesse() or so. Or resize_to_minimum() which resizes to smallest rect or so.

About gui_map_preview: What is this good for? It just draw the array, so why must it be done this way?

The autohide scrollbars is something I have to get used too; but it is certainly innovative. (Actually, is the autohide graphic smaller than the previous scrollbar?)
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 30, 2013, 11:58:41 PM
Quote
I have my doubts on the implicit conversion from  scr_coord to koord. If scr_coord is made 32 bit as discussed, it will silently produce errors.
Hmm, are you referring to the code that is commented out in scr_coord? I tried to make a conversion routine so we could start to migrate slowly froom koord to scr_coord. I got caught in some cross reference problems and commented out the code. I would be happy if you could fix that routinefor me. This is temporary so we can do the update of koord to scr_coord more slowly. It would be a heck of a patch if we where to change all of this at once. When koord is replaced by scr_coord we can remove this the conversion (and the one in koord).

We can't do a search replace because not all koord should be updated to scr_coord. Those used as map coordinates should still be koord as I understood from the previous discussion.

Quote
Also I am not so keen of a default constructor for scr_coord. It shoudl have rather none if possible. Or when, then one which set them to some undefined value, imho.
Why not?!? To have uninitialised members is to beg for strange bugs...

Quote
And should rect be rather x,y and width and height? I though that was the consent form the other thread? Most UI elements have a size (which they care for) and a position (which often somebody else cares for). But I will submit it without this for the moment.
In the code we quite often use pos.x + groesse.x etc... The beauty of OOP is that we don't need to care for the internal representation. We do need to define a rectangle and its sides, both as absolute and relative values.

Quote
scr_coord is also defined unusually. Imho it is better anyway a class to define operators
I have no objections here. In fact both scr_coord and scr_rect could be classes. Maybe next patch?

Quote
At the moment in buttons koord and scr_koord are happily mixed. But this is certainly a temporary state, or?
My guess is that you refer to scr_coord_val and koord? These are very different. scr_coord_val replaces KOORD_VAL,while scr_coord will replace koord. Yes it is temporary...

Quote
"size_mode_stretch" will most likely never come. It will be most ugly too.
Well, as the remark says, it's not implemented yet and I don't see where we should use it anyway. It's only an enum on the drawing board... you (or I) can remove it.

Quote
A question of style is your par for your parameters. If you are afraid of changing them, you can make them cost; but the par is ugly in my eyes. But other may think different on that.
Well, I'm not so keen of_par either, but I want to use a postfix (or prefix) on parameters so they don't collide with member variables.
If you have a shorter or better way of a prefix/postfix I open for suggestions. Just don't use _ or __ because these are usually internal or extended C/C++ names.

Quote
And finally, please no client rectangles. This is not needed, or please give an example where get_groesse is not sufficient. It will rather introduce new errors, and is another thing which needs to be initialized. A function for a contianer like GET_minimum_rect os so would be ok something much more useful and descriptive.
The concept of client area is a widely used term and it is passed to a control's all children call of zeichnen() so they can position, update or do whatever they do, without the concern of what the parent look like.
Think of the client rect as a boundary for the children to stay within. A container on the other hand, owns other controls, where the client rect only is a boundary.
For now, the controls outer boundry rect (pos and groesse) happen to be the same as it's client rect. When we apply a theme this might not be the case. A button with a fat border wants the text to stay inside that border, here the client rect is different from the controls size. In my document I published earlier, I touched the client concept briefly.

Already now, the tab panel is an excellent example where a client rect would begin below the tabs. Okay why do we not  only use a client rect for controls that really use it? Because of simplicity and polymorphism. If we can treat all components the same, we don't need to build in specail cases for those who use or don't  use a client rect. If all parents pass their client rect to their children, it is a quick and simple process.

When it comes to maintaining and initialisation, this is again OOP. The object is handling it. As you can see, set_groesse and set_pos does the handling and both pos and groesse could infact beprivate to force the use of set pos/groesse.

zeichnen(koord) will migrate to display(scr_rect client). The scr_rect makes it easy to move, add, substract, expand, contract the area.
If you want a margin, just contract the client rect and, voila, all children automatically moves in.

Quote
Autosizing buttons
What do you refer to here? Do you mean the auto size mode for gui_image_t? This is how the gui_image_t always has worked. The size is set to the size of the image. I made it possible to set the image area to a fixed size and then have the image to align inside it (as you suggested in an earlier post)

Quote
About gui_map_preview: What is this good for? It just draw the array, so why must it be done this way?
I started to make a component to display a relief map, but got a bit unsure of how the graphics was stored. Then realized that the minimap and city info dialogue also shows a relief map. I did ask if it was possible to use this for the welt dialogue but I got no answers...

If it is possible to reuse the minimmap or city information I think this will be better. If they all use their own code, it would be a good thing to break it out as a separate gui control.

To answer your question: I started on a new control, but got interrupted and then didn't know what to do. Pleas give me some advice if we can reuse something else...

Quote
The autohide scrollbars is something I have to get used too; but it is certainly innovative. (Actually, is the autohide graphic smaller than the previous scrollbar?)
I mentioned it before and you(?) said it would be best to hide the whole control. I did that but it looked odd if the client area wasn't expanded to fill out the space, so I tried a place holder (proxy) instead. Yes it is slight smaller, it was too eye catching when it had the same size. However it is configurable as, always hide (still responds on mouse wheel), always show or autohide (drawing a proxy when full).

We will see how this evolves... The best would be to have the client area ( :police: ) to expand and completely hide the scrollbar.

So some questions...
Why can't I add new files to a patch? Or did the patch work for you?
Title: Re: [Project] GUI Theme
Post by: Ters on July 31, 2013, 07:32:30 AM
The problem with conversion operators is that you can get a much faster conversion to scr_coord than you expected. You could make them explicit though, unless there are compiler issues with that. That still allows for comparatively easy conversion, but only when you explicitly ask for it.
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 31, 2013, 08:49:30 AM
The scr_coord.h seems to be missing in the trunk. Is this intentionally?
Title: Re: [Project] GUI Theme
Post by: prissi on July 31, 2013, 10:38:15 PM
No the missing scr_coord.h is an accident. It seems I submitted in the wrong directory anyway, and also omitted a lot of other changes. Here comes the corrected version. It also features an eclipse string from translater as those are quite language dependent (there is even an Unicode character for japanese).

You can easily have a constructor for scr requiring explicit parameters. That way not scr_coord() is possible. Or just do not initialized the parameters at all and let the program/debugger complain when using them.

BTW: the patch works for me (i.e. adds the new files).
Title: Re: [Project] GUI Theme
Post by: Max-Max on July 31, 2013, 11:28:20 PM
Thank you Prissi...

For the next patch I will transform scr_xxx_xxx to classes. As you suggested, I can hide the default constructor :)

Should I move scr_coord.h to the same folder as koord and koord3d?
Title: Re: [Project] GUI Theme
Post by: captain crunch on July 31, 2013, 11:42:02 PM
I had to make some changes to the Makefile and gui/components/gui_map_preview.cc
to successfully compile this.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 01, 2013, 12:07:00 AM
I have applied your patch into my working copy. But maybe Prissi should do a quick fix in the main trunk too.

I'm on VC++ 2012 Express so I can't really test on other systems or modify the VC++ solution file (VC++ 2010). Unless we make the decision to upgrade the VC++ 2010 project file to VC++ 2012 Express.
Title: Re: [Project] GUI Theme
Post by: kierongreen on August 01, 2013, 08:09:22 AM
Actually came up with the same modifications as in the gui_theme_8aca7d54 patch to get Linux compile working before seeing this thread! Have committed them in r6608 anyway :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 01, 2013, 11:11:15 AM
Splendid!
Title: Re: [Project] GUI Theme
Post by: prissi on August 01, 2013, 12:41:09 PM
the scr_coord.h should be maybe go into gui folder, as it only affects display and not the map. Or maybe all drawing stuff should go to a display folder, including simview and the like.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 02, 2013, 11:39:42 AM
It sounds like a good idea to make a display folder to collect all the drawing stuff.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 02, 2013, 02:32:00 PM
Prissi,

Have you removed all my client stuff from the gui?

Think of the client rect as a margin for a controls children. the macros D_MARGIN_XXXX is a client rect, but instead of 4 variables you have a rect class that can be added, subtracted, compared etc... I don't see how this can be more confusing than the current system. By sending a client rect the children don't need to know anything about their parent's dimensions.


Sorry, disregard this... My fault... :)
Title: Re: [Project] GUI Theme
Post by: prissi on August 02, 2013, 10:28:46 PM
About the client: Perhaps a routine like "set_size_to_contain_all" or so coudl achieve what your wanted to to the client rectangle so far.

And still, I am not opposed to a rectangle class. I would rather prefer x, y, w, and h, but I would also live with top_left.x, top_left.y and right_bottom.x and right_bottom.y or simple top, left, bottom, right. I would like to avoid x, y, xx, yy which are confusing.

And yes, as display folder will help. The only thing is, what to put in there. Simwin.cc maybe belong ratehr into the gui folder? Or putting it there, next to the ticker?
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 07, 2013, 06:40:48 AM
This patch (http://simutrans-germany.com/files/upload/ClassMove.zip) has some adjusted label widths and the some moved files to a new folder /display/ as discussed earlier.

Since we moved some files this patch is very big because all #includes "xxx" had to be updated in a looot of files.

I haven't included my VC++ 2012 project and solution file, but I tried to update the make file (without being able to test it).
Title: Re: [Project] GUI Theme
Post by: TurfIt on August 07, 2013, 09:43:37 AM
Committed r6624 (in a fit of insomnia...)

Note: files cannot be moved by patch, must be done directly by svn move or else all history will be lost.
Also: your patch contained two copies of several of the moved files - applying patch appends these two to the same file, pain trimming. Something wrong with whatever program you used to diff...
I unreverted your reversion to dwachs r6616 commit. Why revert this...
Not all references to moved files were updated - e.g. all the simsys_* variants.
Const cast warnings in scr_coord.h, I added extra consts to suppress the 38482284332 warnings that came out., check if this still works as you intended.
Patch had files with trailing whitespace on lines - cannot commit like this - svn rejects.
Patch had files with trailing LFs - cannot commit - rejects.
Patch had files with no LF on last line - cannot commit - rejects.
Patch had files with lines containing only whitespace - cannot commit - rejects.

Please watch those svn rejected items on future patches. It's a pain fixing afterwards...
Done griping.  8)


Title: Re: [Project] GUI Theme
Post by: kierongreen on August 07, 2013, 09:51:25 AM
Brilliant - well done TurfIt (and Mad-Max of course). I'd just started looking at the patch when I luckily ran svn update and saw someone had beaten me to it!
Title: Re: [Project] GUI Theme
Post by: Ters on August 07, 2013, 10:08:54 AM
What's up with tag_scr_coord_t? Some crazy compiler compatibility? This is C++, structs are first-class datatypes.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 07, 2013, 12:48:15 PM
I'm not an expert on SVN and for some reason I can't merge your trunk with my branch directly.
First I have to manually copy the trunk to a local "master trunk" and check that into my local repository before I can merge it with my local Theme copy.

I do everything in SVN (adding, removing, renaming etc...) and then copy my working copy to my copy of your trunk manually. Now I have your version number so I can create a patch.

I did go through all files to manually clear all moved files, check that files where added and removed properly, compile and test.

This is of course a pain for me too, because if your trunk has been updated in between I have to repeat the whole procedure and merge it with my Theme test copy again etc...

For some reason not all my SVN operations makes it into the patch file...

Regarding scr_coord and scr_rect, I just forgot to change them to classes in this patch... They will be classes...

Thank you TurfIt for your work, I can imagine it must have been a lot.
Title: Re: [Project] GUI Theme
Post by: kierongreen on August 07, 2013, 01:03:21 PM
Quote
This is of course a pain for me too, because if your trunk has been updated in between I have to repeat the whole procedure and merge it with my Theme test copy again etc...
I know from experience how it's a pain keeping a local branch with a large number of modifications up to date with trunk. Remember it'll be worth it in the end though :)
Title: Re: [Project] GUI Theme
Post by: Ters on August 07, 2013, 03:49:31 PM
Using a distributed VCS like Git or Mercurial on your own machine at least gives you proper branches to work with locally. They can both be set up to pull from SVN. But I don't know how it is to take out patches from a branch, have someone commit them to SVN, then get them in via pull from SVN and then merge over to branch again, where the changes already exists. Git probably has better support, while Mercurial is more familiar to those who know SVN.
Title: Re: [Project] GUI Theme
Post by: TurfIt on August 07, 2013, 09:15:48 PM
Thanks dwachs, kierongreen for fixing things back up. text_pixel.c was strange, it worked fine here showing it moved, and the file was definitely intact in its new spot, but now 'svn up -r6624' sets it to 0 bytes. Hiccup with my checkin maybe??

svn file additions, deletions, moves, properties, etc. don't survive the diff/patch process. Best to avoid when doing patches...

A simple 'svn up' should take care of it. However, if the update is expected to produce some conflicts, I save my work into a diff first. 'svn diff > blah.diff', then open blah.diff in an editor and make sure it makes sense/has all the files, then 'svn revert -R ./' to blow away all my changes. Then 'svn up' against the virgin older trunk. Then 'patch -p0 < blah.diff' to put my work back - and deal with any conflicts (.rejs) that result. This procedure gives me backups of my work by keeping the .diffs, and a way to keep projects separate while only using a single working copy, and makes merging the right way around IMHO. Merge your changes (which you should know) into the new trunk, rather than trying to merge somebody elses unknown code into yours (why the git process makes no sense to me).

---
The proxy for the autohiding scrollbar is rather ugly. IMHO if the skin doesn't provide appropriate images for the disabled/hidden state (not really hidden when something's drawn???) the old behaviour should be retained. The old behaviour should also be easily selectable by the user IMHO - autohiding like this is another of those strongly love it/hate it things.
Title: Re: [Project] GUI Theme
Post by: kierongreen on August 07, 2013, 10:45:34 PM
Quote
A simple 'svn up' should take care of it. However, if the update is expected to produce some conflicts, I save my work into a diff first. 'svn diff > blah.diff', then open blah.diff in an editor and make sure it makes sense/has all the files, then 'svn revert -R ./' to blow away all my changes. Then 'svn up' against the virgin older trunk. Then 'patch -p0 < blah.diff' to put my work back - and deal with any conflicts (.rejs) that result. This procedure gives me backups of my work by keeping the .diffs, and a way to keep projects separate while only using a single working copy, and makes merging the right way around IMHO. Merge your changes (which you should know) into the new trunk, rather than trying to merge somebody elses unknown code into yours (why the git process makes no sense to me).
I use exactly this method to maintain branches on my computer (the new landscape patch was like this for a year). I also can't get the hang of git...
Title: Re: [Project] GUI Theme
Post by: prissi on August 07, 2013, 11:07:15 PM
I did a lot of work on scr_coord class to remove the tags and make a readable class. Why has this been reverted?

I am also still against having client rects with containers as variables, as stated various times before. Also using containers for the sole purpose of grouping labels is very hackish. Well, I left it so for the moment (with a little change, since I did not quite understood the align procedure. Imho now there is too much in align, as it influences size too, if I got this correctly.

I am not convinced to make gui_frame a part of gui_component. Those are very different, since frame have help files, owner and so on.

Please comment what these ALIGN_INTERIOR_... are doing. I have no good idea, and your calls to the align_to procedure produces more crytic code than the explicit calcualtion before. Please, mroe comments to align_to.
Code: [Select]
ALIGN_INTERIOR_V = 0x00,
ALIGN_EXTERIOR_V = 0x10,
Title: Re: [Project] GUI Theme
Post by: TurfIt on August 07, 2013, 11:35:23 PM
I did a lot of work on scr_coord class to remove the tags and make a readable class. Why has this been reverted?

Too many cooks... I'll return to my hole now.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 08, 2013, 12:03:17 AM
I haven't reveretd anything (what I'm aware of). I can't remember I have seen it as a class. scr_coord.h was missing from the trunk the first time because you had check in the wrong folder, remember? Maybe you checked in the wrong version the second time?

If it was reverted, it should be in the trunk some where. Maybe you can pull it out and check it in again?
Title: Re: [Project] GUI Theme
Post by: TurfIt on August 08, 2013, 12:11:06 AM
The file moving patch had significant changes to scr_cooord.h - from 55 to 478 lines. I assumed that was intentional as part of the patch. What should this file look like? Also, now I wonder if there's any other stowaway reversion in there... I'd already found the r6616 reversion...
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 08, 2013, 01:19:22 AM
Quote
Please comment what these ALIGN_INTERIOR_... are doing.
The whole alignment is described in the draft I published. I have uploaded rev 47 of the draft (http://simutrans-germany.com/files/upload/SimutransTheme_r47.zip) (work in progress)
I added a code example with each alignment operation.

Quote
I am not convinced to make gui_frame a part of gui_component. Those are very different, since frame have help files, owner and so on.
If you compare a window with a component they have a lot in common. Both have a size, a position, can own other components, respond on events, create events, be themed to mention some. Several of these are now duplicated code.

some components are unique while some are an aggregation of several components. A window is nothing more than an aggregation of a container, gadget buttons and a label. Then you can add unique features, like a help file.

Most of the gui components do not use inheritance or aggregation and are derived directly from gui_komponente_t instead of nearest existing gui control. Or simply drawn directly instead of being a component.

Quote
Also using containers for the sole purpose of grouping labels is very hackish.
The purpose of containers are just to group other controls, there is nothing "hackish" about it. What would you use a container for other wise, if not containing other controls?

See the containers as objects, controls inside the container doesn't need to know anything of the outside, nor does the outside need to know anything about the controls inside the container. The minimap dialogue use containers to group the three information sections. Instead of updating each control individually, the whole container can be shown or hidden. One only need to know the containers size, not every control inside it, to recalculate the position of the map area.

So far all controls, regardless of grouping or not, they need to be aware of how their parent control is organised to add margins that lies outside their interest. A client rect solves this! A control only needs to relate to the client rect, passed down by its parent.

A good example is a scrollbox. If the scrollbars are visible the  scrollbox knows this, because it is a part of the scrollbox control. When updating the child controls these has already been subtracted from the client rect that is passed down and the child controls doesn't need to know if they are visible or not. In fact they don't even need to know that they exist at all.

If the scrollbox don't need to show them (scrollbars), the client rect is adjusted before it is passed down. Any child control, pending on the client's area size will automatically claim that area, again without the knowledge of its parent.

By setting the clip rectangle to the client rect, all child controls will automatically be clipped and not overflow the client area.

The client rect also serves as a margin for all children and doesn't need to be the same all the way around. With the current system ALL margins are affected, but sometimes you want a smaller or larger margin, or a margin not affected by the "global" margin.

Since the scr_rect has members we can quickly calculate needed space for a set of controls, expand/contract borders or just move around a group of controls at once.

Remember that the scr_rect only defines a rectangular area, there is nothing magic about it, it doesn't do anything as a component does, it only defines a boundary that can be manipulated.

After digging in the gui for quite a while now, I realise that I need to restructure this first. There are some new controls needed and the last days has been focusing on fixing what is already there. I need a bunch of new components to transform the dialogues in the way I intended where themes are a central part. Because a theme not only redefines images and colours, it also redefines gui element size. We will have a GUI that isn't fixed any more, we can't rely on number of lines, buttons in a row etc. We need the GUI to reorganize itself.

What we do is that we design the GUI in such way that we tell it HOW it can reorganize. Containers, alignment and resizing is an essential key here, because we define the relations, not the absolute positions. From the container we will derive layout controls that takes care of organizing the child controls.

The collapse level is another thing to control how components will be resized. It is basically needed for portable devices or very small screens where we can reduce unimportant gui features in favour for interact able gui controls that needs to be unaffected in size as long as possible (it is explained in the document).

I hope this sheds some lights over what alignment, containers and client rectangles are used for ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 08, 2013, 02:46:45 AM
I get a compiler error in your trunk because you have renamed the call: client_bound.make_union() to client_bound.merge() without changing the name in scr_rect.

I also noticed that you renamed .calc_client() to .get_min_boundaries(). A boundary is the most outer limit of a control, nothing is drawn outside this boundary. A theme border (it might be a window, a button or other control with a frame) is drawn from the boundary and inwards, so the boundary remains the control's outer limit. The client rect begins next to the themed border, inside the boundry rectangle (the themed border is drawn between the boundry and the client rect). Hence, the child controls are all inside the client rect and the proper function name would be something with client because it referees to the containers client area and returns a rect that is intended for a client adjustment.

I also noticed that you had changed the display dialogue so it now overflows (see attached pictures).
You also removed the .set_children_width(); so all the labels in the container isn't of the same size as the container width (now of some arbitrary size).

If my debug code had been left in there, it had been easy to enable it and spot this.
But I understand your good intention...

I feel more and more the urge of starting the gui restructure (I need the layout controls) and don't want to put too much effort on the dialogues now because the layout controls will handle the most of the child control resize.
Title: Re: [Project] GUI Theme
Post by: Ters on August 08, 2013, 07:40:13 AM
The purpose of containers are just to group other controls, there is nothing "hackish" about it.
I agree.

See the containers as objects, controls inside the container doesn't need to know anything of the outside, nor does the outside need to know anything about the controls inside the container. The minimap dialogue use containers to group the three information sections. Instead of updating each control individually, the whole container can be shown or hidden. One only need to know the containers size, not every control inside it, to recalculate the position of the map area.
I wish it was that easy, but I have often found myself in the situation where control inside the container need to know about the outside, or even a control inside another sibling container. This typically happens when you have one big panel made up of smaller sections, where these smaller sections are either reusable, or perhaps made as a container to allows them to be individually hidden. Yet all fundamental controls in the panel should align to the same columns, and the columns' widths is autocalculated from preferred width of each control in every container (which again is based on the length of the text the control needs to show).
Title: Re: [Project] GUI Theme
Post by: prissi on August 08, 2013, 12:22:43 PM
Perhaps I committed from the wrong folder again, since I compiled and test before committing. A mismatched function call would have not been compiled then. I will check at the evening. The SVN seems down at the moment, so I am not sure what is in the repo right now.

The function of the different alignment parameters (if not trivial) should be commented at the definition in the program. And external file is nice, but it bears an even higher risk of being out of date when the code is changed.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 08, 2013, 12:42:33 PM
Quote
Yet all fundamental controls in the panel should align to the same columns, and the columns' widths is autocalculated from preferred width of each control in every container (which again is based on the length of the text the control needs to show).
You forget that the container itself can have logic. I will derive layout objects from the container with the logic to rearrange child objects. A controls size can be set either by client area and have the bounding area to adjust outwards, or set the bounding box and have the client area to adjust inwards. The collapse system can ask a control what size it needs and then make a decision about the layout depending on the needed space.

I know at least one scenario referring to your mentioned problem. If you have a column of buttons it would be nice the have a weighted centre alignment of the button's text, depending on the button with the widest text. Because the container can collect the information from each button it can then make a decision and notify the children about any layout adjustments.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 08, 2013, 01:49:59 PM
Perhaps I committed from the wrong folder again, since I compiled and test before committing. A mismatched function call would have not been compiled then. I will check at the evening.
I always count on that every one is doing their best and we all do honest mistakes sometimes... No big deal :)

The function of the different alignment parameters (if not trivial) should be commented at the definition in the program. And external file is nice, but it bears an even higher risk of being out of date when the code is changed.
I will see what I can do :)
Title: Re: [Project] GUI Theme
Post by: Ters on August 08, 2013, 02:07:01 PM
You forget that the container itself can have logic. I will derive layout objects from the container with the logic to rearrange child objects. A controls size can be set either by client area and have the bounding area to adjust outwards, or set the bounding box and have the client area to adjust inwards. The collapse system can ask a control what size it needs and then make a decision about the layout depending on the needed space.

I know at least one scenario referring to your mentioned problem. If you have a column of buttons it would be nice the have a weighted centre alignment of the button's text, depending on the button with the widest text. Because the container can collect the information from each button it can then make a decision and notify the children about any layout adjustments.

As I understand this, then you are no longer using containers to wrap a group of controls that should be hidden and displayed together, which was your argument for having containers. There is just one container level with everything, that uses another mechanism for grouping controls. I did not forget that containers have logic, typically a layout manager, but this manager needs to know internal state of other containers (or perhaps rather their layout manager) to work sometimes. Unfortunately, I have never seen any that are able to do this.

The only solution I've heard (for Java), is to not make nested containers, but builders of sorts. You only make one window/dialog/panel, set up a global layout, and then recursively call the builders, which are passed offsets so that they put their controls (and sub-builders) at the correct place in the layout. However, although the nested builder is ignorant about the layout it is put into, parent builders must know how the builders they nest arrange their controls.
Title: Re: [Project] GUI Theme
Post by: prissi on August 08, 2013, 11:23:25 PM
Since the SVN is still down, here the missing changes.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 09, 2013, 11:07:52 AM
I will wait for the SVN server to get back up. I don't want to risk messing up things when applying a patch... Does anyone know why it's down?

I'm on a 3 day music festival again (back in Sweden) :)
Title: Re: [Project] GUI Theme
Post by: Leartin on August 10, 2013, 08:34:39 AM
I'm sorry to intrude into a thread I don't understand at all, but I realized something in the nightly which probably has to do with the GUI overhaul - the active toolbar now has an orange border. With the new toolbar design we made for pak192.comic recently, that looks really ugly, as you can see on the attached picture. I'd like to ask if this border is something that can be removed by pakset settings later (or already), or is here to stay, as in the latter case we'd redo the design to be a rectangle again. Thank you in advance :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 10, 2013, 10:52:58 AM
It's configurable under "settings" -> "Window frame active"
or in the simuconf.tab file -> "window_frame_active", set it to 0.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 18, 2013, 10:55:24 PM
I just want to give you guys a head up on what's going on.

I haven't been so productive the last weeks due to the unresponsive SVN server and then I got sick, just bad timing. Anyway I doing some "thinking" around the theme manager and experimenting a bit.

I have not digged beyond the call to display_image() and have no clue on how each image is stored internally or how the colour mapping is done.

When we switch theme I need to unload all theme images and load the new theme images. Can some one please explain in the big context of how this works?
Title: Re: [Project] GUI Theme
Post by: kierongreen on August 18, 2013, 11:20:30 PM
Look at simgraph16.cc. I would suggest changing register_image(struct bild_t* bild) and adding new functions replace_image(unsigned bild, struct bild_t* new_bild) and register_image(struct imd* image). You'll also need to load the new images from pak files or whatever so that there's a valid struct bild_t* new_bild.

Code not tested:
Code: [Select]
void register_image(struct bild_t* bild)
{
   struct imd* image;

   /* valid image? */
   if(  bild->len == 0  ||  bild->h == 0  ) {
      fprintf(stderr, "Warning: ignoring image %d because of missing data\n", anz_images);
      bild->bild_nr = IMG_LEER;
      return;
   }

   if(  anz_images == alloc_images  ) {
      if(  images==NULL  ) {
         alloc_images = 510;
      }
      else {
         alloc_images += 512;
      }
      if(  anz_images > alloc_images  ) {
         // overflow
         dbg->fatal( "register_image", "*** Out of images (more than 65534!) ***" );
      }
      images = REALLOC(images, imd, alloc_images);
   }

   bild->bild_nr = anz_images;
   image = &images[anz_images];
   anz_images++;

   register_image(bild, image);
}

void register_image(struct bild_t* bild, struct imd* image)
{
   /* valid image? */
   if(  bild->len == 0  ||  bild->h == 0  ) {
      fprintf(stderr, "Warning: ignoring image %d because of missing data\n", anz_images);
      bild->bild_nr = IMG_LEER;
      return;
   }

   image->x = bild->x;
   image->w = bild->w;
   image->y = bild->y;
   image->h = bild->h;

   image->base_x = bild->x;
   image->base_w = bild->w;
   image->base_y = bild->y;
   image->base_h = bild->h;

   image->len = bild->len;

   // allocate and copy if needed
   image->recode_flags = FLAG_NORMAL_RECODE | FLAG_REZOOM | (bild->zoomable & FLAG_ZOOMABLE);
   image->player_flags = NEED_PLAYER_RECODE;

   image->base_data = NULL;
   image->zoom_data = NULL;
   image->data = NULL;
   image->player_data = NULL;   // chaches data for one AI

   // since we do not recode them, we can work with the original data
   image->base_data = bild->data;

   // does this image have color?
   if(  bild->h > 0  ) {
      int h = bild->h;
      const PIXVAL *src = image->base_data;

      do {
         src++; // offset of first start
         do {
            uint16 runlen;

            for (runlen = *src++; runlen != 0; runlen--) {
               PIXVAL pix = *src++;

               if (pix>=0x8000  &&  pix<=0x800F) {
                  image->recode_flags |= FLAG_PLAYERCOLOR;
                  return;
               }
            }
            // next clear run or zero = end
         } while(  *src++ != 0  );
      } while(  --h != 0  );
   }
}

void replace_image(unsigned bild, struct bild_t* new_bild)
{
   if(images[bild].zoom_data!=NULL) {
      guarded_free( images[bild].zoom_data );
   }
   if(images[bild].player_data!=NULL) {
      guarded_free( images[bild].player_data );
   }
   if(images[bild].data!=NULL) {
      guarded_free( images[bild].data );
   }
   register_image(new_bild, image);
}

If the number of theme images isn't fixed then you would probably have to reload all pak images as well - you'd be as well off restarting simutrans.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 18, 2013, 11:36:38 PM
So far we have decided that theme related images will be in its own single pak-file, so there will not be any need to reload other pack files when changing the theme.

Why are we "registering" each image? Is it here we unpack them from the PAK file format? (recode?)
Why are the registered images stored with realloc and not in a std::vector or other stdlib container (or is this code from the C version of Simutrans)?
Title: Re: [Project] GUI Theme
Post by: kierongreen on August 19, 2013, 12:10:33 AM
When you load a pak file you will end up with a number of besch structures. These will contain image data however this then needs to be registered with the drawing routines. Look at the code that runs when simutrans starts up to see how this works.

note that it is REALLOC not realloc. Simutrans doesn't use some std functions because they weren't around when it was first coded, or are still not available on some platforms. This might be one.

I realise it's going to be in one pak file but depending on assumptions regarding images and so on you might have difficulties just reloading one pak.
Title: Re: [Project] GUI Theme
Post by: Ters on August 19, 2013, 04:39:22 AM
Reloading pak files is not something Simutrans supports. I think it would be better to get theming working before starting on implementing reloading pak files while a game is running. There are a couple of potential gotchas.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 21, 2013, 12:33:42 AM
Okay, I'm well enough to do some coding and I have updated everything and can now have a look at the scr_rect that Prissi rewrote completely. I thought we would discuss things before we change the whole design of some one's else work?

I do remember that you made a comment before regarding left,right,top,bottom instead of x,y,w,h. I agree that x,y,w,h makes more sense for a geometrical figure such as drawing a rectangle. but if scr_rect is used as a padding or margin, x,y,w,h makes no sense at all.

In my original design left,right,top and bottom where all public because updating them doesn't need to recalculate something. This gives fast and easier access to them.

Because height and width was a function call, they where calculated when needed from the left,right,top,bottom variables and always gave a correct result.

There are countless of places where we add get_pos().x and get_groesse().x to get the absolute position (right edge of the rectangle) and working with my original design makes the code less cluttered because we already have that information in the rightmember.

compare the trunk code...
foo.get_bounds().get_pos().x + foo.get_bounds().get_width()

with my original design...
foo.get_bounds().right

Can we describe a rectangle, margin, padding, clip region with only x,y,w,h? Well, we can but it makes absolutely no sense for margins or padding.

Can we describe a rectangle, margin, padding, clip region with only left,right,top,bottom? Well, we can and it does make sense in the cases (you can describe a rectangle with left,right,top and bottom positions).

We need a getter and setter to access the bounding box, client area, margins etc... for a component because the component needs to be aware when these are changed. But scr_rect doesn't need any getter or setter because it doesn't need to be aware if any of the left,right,top,bottom (or x,y,w,h) variables changes.

I included the get/set_width() and get/set_height() to for easy access when needed, as helper functions.

Further, all setters are calling normalize() and that makes sense if you want to draw a rectangle, but not if you actually want a negative offset, such as in a margin or padding. A negative result can also be used to check if something is before or after the scr_rect.

Why do we need to mark a scr_rect as invalid? Just hide the default constructor if you want to force a size on creation. However a margin or padding would make a lot of sense to be initialised to 0, but is still valid.

Your version of expand doesn't work in the same way as my original version. Your version works as my add_offset (which you have removed).

make_union() is renamed to merge() and I did put some thought behind this. Merging two rectangles would result in a non rectangular shape (unless both rectangles are of exact same shape and location). After more thinking it would probably be more suitable with a name such as bound() because it creates the bounding box around two rectangles.


If you had asked me how I intended to use it, started a discussion before you rewrote almost everything I did, we could have saved us both some work.

The scr_rect was planned to be used as bounding box, client area, padding (inside client area) and theme clip frames. We can easily add some display_xxxx functions accepting a scr_rect as a parameter as well.

I can do the job to restore the class to function as I intended (with left,right,top and bottom, or just short l,r,t,b if you think it suits better). I will try to keep as much of your code as possible, but I need to know if you are going to rewrite it again if you don't like it...

But, I do see some good optimisation in some places, good work there :thumbsup:
Title: Re: [Project] GUI Theme
Post by: prissi on August 26, 2013, 09:28:09 PM
Well, the only reason to use OOP instead of structures is to hide private members. At least this is the proper way. get_rest().right is against the spirit of simutrans (at least as originally concieved) to be able to change internal later.

As such it is also important to initialise rectagles properly and avoid use with a default behavior. A private constructor would require to pass all rectangles as pointers, and forbids also the use of arrays of reactagles (or similar structures).

However, if you want to do further optimisations, you can also add a bottom right to this structure, and return this by get_right() That is the beauty of OOP, isn't it?

About the functions: Aparently I misunderstood the purpose of expand from the name. The merge is properly rather split into merge_outline and merge_overlap.

Rectangles should not be used for margins: By definitions a position will not make sense for margins. As points will be still used for offsets, I see no wil be introducing a new class for margins. Rather more important the margins should be stored in variables containing the word "margin" ...

That my input so far. I will be still away from home until the 5th, so do not expect fast responses until then. Sorry.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 27, 2013, 01:24:01 AM
The original design was a type with helper functions operating on the type, it doesn't need to be a class more than an int or a double does.

As I said, there is no need for private members because nothing needs to be updated when these variables change. Since there was no need for private members I originally designed it as a struct, but because of the member functions, you wanted it to be a class. I'm fine with that, but just because it is a class, it doesn't need to have private members.

If the class needs to be aware of access to one of its members, getter/setters are used, but if there is no need for this it is perfectly all right to make the member public without getter/setters. Just because it is a class doesn't mean that you have to use getter/setter (if that was the case there makes no sense to be able to declare public variables to begin with).

The use of getter/setter creates a load of unnecessarily function calls because scr_rect doesn't need to be aware of access to the variables. This adds up to unnecessarily CPU time because we do this several times every frame. You might say that it is so little that it doesn't matter, but you could use that time on other things instead, such as improved graphics, animations, more complex AI, path finding etc... All small things adds up in the end...

One of the main functions of a constructor is to initialise the object, I have never, in my whole career, meet someone that thinks this is a bad idea.
If you really don't want to have a default initialisation, I proposed to hide the default constructor so you would be forced to use another public constructor accepting parameters for initialization. On the other hand, if the default is 0,0,0,0 (as it was in my original design) you could use is_empty() to check if it is initialized/invalid.

Your new design initialize x to an integer value to mark an "invalid" rectangle. This doesn't work because some setters use the x value to calculate internal stuff, resulting in really screwed up rectangles. A rectangle with width or height 0 isn't really a rectangle, it's a line or a dot, so is_empty() would work fine to check if it is invalid.

Defining a rectangle by its sides isn't something I have just grasped out of the blue. It is a proven concept used in Win32, OWL ,VCL, FireMonkey, DirectX,  and Android to mention a few. The benefit of using the sides is just that it can be used to anything with 4 sides, such as a rectangle, margin, padding, clipping etc...

Some frameworks also define a position and a size type, both having the same content, but under different names; position(x,y), size(width,height). I did suggested a separate size type before and got the answer that a scr_coord did the same thing and in this case there is no problem to call it x,y instead of width,height.

Since you are not concerned by all the function calls to access the members, one way would be to use my original design (as a class if it feels better, with left, right, top and bottom as public members). Then we can add a get_pos() and set_pos(). Now you can still use foo.get_pos().x and I will get my direct access to left, right, top and bottom.

I have used your class in my theme_manager to see how it is to work with (I thought I would give it a try), but it got complex to do some very simple operations:

void foo (scr_rect frame, bild_t part) {

scr_coord(frame.get_pos().x+frame.get_width()-part.w,frame.get_pos().y+frame.get_height()-part.h);

or
scr_coord(frame.get_bottomright().x-part.w,frame.get_bottomright().y-part.h);

compared to my original design...

scr_coord(frame.right-part.w,frame.bottom-part.h);
}


If we define margins and padding with 4 members, we can't pass these definitions as a single parameter, or use them in operations on rectangles (bounding boxes), especially if you want to access all 4 of them through getter and setters (in the spirit of Simutrans).

A margin declared as:

scr_rect Margin;

can be accessed by:

Margin.left;
Margin.right;
Margin.top;
Margin.bottom;


...and this makes a lot of sense.


What exactly is the spirit of Suimutrans? To not change anything? To code C with a C++ compiler? To always code classes just because it is a C++ compiler? I really don't get the logic sometimes in how you reason regarding the "spirit of Simutrans".

Should we refuse a solution just because it isn't the "spirit of Simutrans"? How can we thinking outside the box if we are restricted to "this is how it always has been done"?
Title: Re: [Project] GUI Theme
Post by: Ters on August 27, 2013, 05:39:05 AM
The use of getter/setter creates a load of unnecessarily function calls because scr_rect doesn't need to be aware of access to the variables. This adds up to unnecessarily CPU time because we do this several times every frame. You might say that it is so little that it doesn't matter, but you could use that time on other things instead, such as improved graphics, animations, more complex AI, path finding etc... All small things adds up in the end...

Although it is more typing, always using methods is the safest bet. There is after all a reason getters and setters are recommended. While it doesn't seem to matter for a plain old simple, stupid rectangle, in the future, it might not be so simple or stupid. Maybe something has proven that it's a good idea to have a rectangle interface, with several implementations. Maybe you want a rectangle that validates whether it's coordinates are within some bounds.

Getters and setters that are defined in the header file will be inlined, ending up with the same machine code as a direct member access (if that's all the setters and getters do).

What exactly is the spirit of Suimutrans? To not change anything?

That goes for every system with lots of users and low capacity for maintenance. The current trend in software development methology encourages throwing old code aside, writing and rewriting code, and continously pushing these changes into production, all with impunity. However, all this depend on things like test driven development and CI servers running unit tests on every single commit. Simutrans has nothing of this. There is no safety net. A screw-up can go unnoticed until hundred player have had their save games corrupted.
Title: Re: [Project] GUI Theme
Post by: prissi on August 27, 2013, 02:41:54 PM
Simutrans was concieved as a teaching project for OOP. Furthermore, one of the priorities is stability before speed. Therefore the rule of get/set functions, as Ters described. You could put the same argument onto almost any other private variable, which is not overlaid.

The are several tastes of OOP. For simutrans the style of mostly private members and get/set access was the one where it finally settled. Even more, since a simple access is without an penalty in speed, but allows for very easy debug checks (which helped a lot). And rectangle are very unlikely performance critical compared to the actual drawing.

And believe it or not: I can understand your thinking; I came without any OOP experience to Simutrans (and a lot of my code still tells of this). But slowly I got convinced of some OOP features, like get/set. The same is with an implicit initialisation with invalid state of stuff. Like pointers with zero, arrays without any members and so on. Lazy initialisation is a recipe for errors later on. If you want a rectangle then use it as a rectangle. Using it as an array of four margins is not a rectangle object. OOP (object with methods) is violated. It is very C-ish, but margins are not reactangle, they are four offsets.

And my understanding of a rectangle a geometric object: A rectangle is defined by the length of two sides, which both have to be positive and 90° to each other. Cornerpoints does not define a rectangle without an implicit rotation, and negative areas of rectangles do not make sense. (Just look at wikipedia.)
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 27, 2013, 04:22:00 PM
The OOP purists, usually fresh students applying all the text books and professors without any real world experience propagate for using all the OOP feature just because in theory it looks nice. Under my 20 years experience of real world OOP I discovered that you need to use some common sense and apply OOP where it does something good, not because you can. It is not practice to always use setter/getter, there are two sides of it, the purist that do it of Principe no matter what, and the other side that use it when needed.

I don't see why code would be more buggy without a getter/setter if it doesn't do anything else than just pass a variable.
Something that produces buggy code is to have several getter/setter for the same variable (functions that read/write directly to the private member). If you need to update the behaviour to a set operation, you also need to go through the whole class to make sure no one else is using that variable directly. In these cases there should only be ONE getter/setter that also is used internally. Then you only need to update one pair of functions.

With your arguments, why does scr_coord, KOORD or other classes with public members not have getter/setters? Why do we have structures at all and not classes for everything with private members with getter/setter?

I proposed a size type before and got the answer that we have KOORD (scr_coord), but why are scr_coord used for size? a size is a width and a height, not x,y point (to refer to your own arguments for a rectangle only being a geometric figure and nothing else). So why is it that we in some cases use OOP even if it isn't really needed and in some cases we don't?

Regarding the use of types, you have to think outside the box and not hang up non nomenclature. My original rect type described 4 sides. This can be used for anything with 4 sides, like a margin inside a rectangle. Being of the same type you can easily adjust an rectangle with a margin object. It makes sense and feels natural to be able to subtract a margin from a bounding box.
Title: Re: [Project] GUI Theme
Post by: Ters on August 27, 2013, 05:00:33 PM
We're not arguing that code is more buggy without setters and getters. At least I am not. However, with direct access, you can't easily add code to be run every time a field is written or read. It also gives you a consistent interface, whether you're asking for left edge, right edge or width, no matter which two of them are actually stored.

As for existing code, some of it was written by people who didn't know OOP yet, as prissi admitted. They were coding C in C++. Knowing how to code Simutrans is difficult, as you have to know which code was written after the developers figured out how to write it.

As for types, a rectangle has four sides, and a margin (for a rectangle) has four sides, but a margin is not a rectangle. Also, a rectangle plus or minus another rectangle is only in special circumstances another rectangle. Simutrans code is hard to read as it is, with its mixture of languages. With scr_coord we tried to make things clearer, but using rectangle for margins feels like two steps back after one step forward. You need to operate differently on a "rectangle" depending on the context.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 27, 2013, 05:28:34 PM
But size is store in a scr_coord wich is a point, not two sides, so you aren't consistent in your argumentation.

You are using the name of the declared variable, not the type.


I think

scr_rect Margin
Margin.left
Margin.bottom

...is very clear of what is does.

you are not writing scr_rect.left to get left margin ;)
Title: Re: [Project] GUI Theme
Post by: Ters on August 27, 2013, 06:03:34 PM
But size is store in a scr_coord wich is a point, not two sides, so you aren't consistent in your argumentation.

Have I argued for using scr_coord for size? But I must say I'm not 100 % sure what coordinate even means. I've always though of it as having to do with any numeric value along an axis (and whatever the equivalent term is in spherical coordinate systems), but according to Wikipedia, the definition is a bit narrower.

You are using the name of the declared variable, not the type.

I think

scr_rect Margin
Margin.left
Margin.bottom

...is very clear of what is does.

you are not writing scr_rect.left to get left margin ;)

You don't always have the informatively named variable's name at hand. Inside member functions, you only have the meaningless name "this". You also don't get compile errors when passing a margin to something expecting a "rectanglerectangle" and vice-versa, or if you mix up the parameters to a function accepting one of each. I prefer having errors brought to light as soon as possible, not after starting the game and performing lots of interactions to bring me to the part I was coding on.

Furthermore, I could also interpret scr_rect Margin as the rectangle formed by each of the four margins. It certainly doesn't come naturally to me to see the four values (left,right,top,bottom) as insets rather than coordinates (by Wikipedia's definition of it).

The cost of introducing all these types to maintain strict typing is high here and now, while the costs due to confusion caused by types that can be used for anything remotely similar is low. But the latter sums up over a very long time.

It also becomes ambigous what one means when saying/writing rectangle. Does it mean scr_rect or "rectanglerectangle"?
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 27, 2013, 06:16:45 PM
I didn't say that you (Ters) was against it. I meant it was down voted when I brought up the question in this thread (http://forum.simutrans.com/index.php?topic=12140.0).

...and if we are going to look up everything on Wikipedia, nothing will make sense in the code... ;)
Title: Re: [Project] GUI Theme
Post by: Ters on August 27, 2013, 06:26:15 PM
...and if we are going to look up everything on Wikipedia, nothing will make sense in the code... ;)

I'm OK with that, for coordinate at least.
Title: Re: [Project] GUI Theme
Post by: prissi on August 27, 2013, 07:11:00 PM
We should avoid to be stuck in details so much ...

Lets conclude: scr_coord is probably not the best name choice when it comes to extend/sizes. Rect is probably not really margins.

Lets make three types: scr_coord, scr_extend (or named scr_size), and scr_rect, which is made from scr_coord and scr_extend and always have an extend >=0. conversions between scr_coord and scr_size would be automatically.

margins would be derived from extends, and could be positive, negative or whatever obviously.

It would allow for invalid rects, sizes, and coords, as well as keep those types properly for their intended purpose. Declaring something like resize( scr_size new_size ) seems quite straight forward.

Title: Re: [Project] GUI Theme
Post by: prissi on August 29, 2013, 09:53:27 PM
I had some ideas on drag working for rail construction on tablets: i.e. drag updated via click and building via doubleclick as simuconf.tab option. That could make simutrans more playable on tablets.
Title: Re: [Project] GUI Theme
Post by: TurfIt on August 29, 2013, 10:22:41 PM
SDL2 appears to have some sort of support for touch/gesture events. They're disabled in the current testing SDL2 backend, but might be worth investigating if someone wants better tablet support...
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 31, 2013, 05:38:15 PM
Some project update info!

I have created a theme manager that prepares all the GUI images. In this first version it assembles the current skin-PAK images into the 9 needed images (theme parts) for drawing a rectangle. These new images are registered in the system with register_image().

The theme manager also have a member function theme_frame(scr_rect, theme_id) to draw a rectangle with the requested theme component (theme_id).

So far it looks promising, but I have to handle if the theme parts (9 images for a specific theme id) don't have the same size. I will do this by extending them  until they line up with each other.

Of course not all themes are rectangles, such as symbols or icons. These only have one Theme part (or as many they need). Whit this said, not all Theme ID have 9 Theme Parts...

The thought is that the Theme manager also will fill in missing images so we always have images for all theme components. This can be done by a number of fall backs. First we can let several Theme ID share the same set of Theme Parts and as a last resort just create a new very simple image as replacement. But this will come further down the road...

Definitions:

Theme ID
A specific theme component as a button, check box, gadget, label etc...
The Theme ID is a constant (enum) to identify a specific GUI control, such as THEME_ELEMENT_BUTTON_UP, THEME_ELEMENT_BUTTON_DOWN, THEME_ELEMENT_CHECKBOX, THEME_ELEMENT_CHECKBOX_CHECKED etc...

Theme Part
To draw a rectangle such a button, 9 images are needed; TopLeft,Top,TopRight,Left,middle (face), Right,BottomLeft,Bottom,BottomRight. One of these images is a Theme Part.
Title: Re: [Project] GUI Theme
Post by: Ters on August 31, 2013, 05:56:18 PM
So far it looks promising, but I have to handle if the theme parts (9 images for a specific theme id) don't have the same size. I will do this by extending them  until they line up with each other.

Just let it fail fataly for now, with a understandable message. I more desire to see this working in all it's glory, on the assumption that every input is correct. Besides, Simutrans isn't know for correcting the artists' mistakes. Maybe the correct adjustment would have been to crop rather than extend anyway.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 31, 2013, 05:57:26 PM
SDL2 appears to have some sort of support for touch/gesture events. They're disabled in the current testing SDL2 backend, but might be worth investigating if someone wants better tablet support...

To handle this as transparent as possible I think the best would be to translate these events into Simutrans events, like swipe_left, swipe_right. A long press could be translated to a right_click etc...

In an embedded project I wrote a GUI system where all sensors (encoder and a button) was scanned and translated into several messages. This allowed me to create virtually controls.

The button produced:
button_down
button_up
button_click
button_repeat
button_long_click

After the button_up message the button_click or button_long_click was sent depending on how long the button had been down.
button_repeat was sent periodically as long the button was down.

The encoder produced:
button_right
button_left
button_forward
button_backward

On each clock wise turn the button_right message was sent and on counter clock wise turns, the button_left.
If the encoder was turned fast, it sent forward and backward messages instead.

So here I could create 5 buttons from only 2 available controls.

You may ask why button down/up was sent, even if a click message was sent right after?
It is not up to the translator to decide what the system should trigger on. It was each individual GUI component that decided what messages to react on. Some needed just the button_up or button_down messages, other only listened to a button_click message.

By using the same technique in Simutrans we can simulate gestures on a desktop system or a mouse on a tablet.
Title: Re: [Project] GUI Theme
Post by: Ters on August 31, 2013, 06:09:38 PM
A challenge with programs portable across different systems is dealing with the different standards for each platform. Simutrans clearly has its own look, but should it have its own rules for input or just rely on higher level input from the OS?
Title: Re: [Project] GUI Theme
Post by: Dwachs on August 31, 2013, 06:26:25 PM
Maybe you figured the answer for these questions already...
Why are we "registering" each image? Is it here we unpack them from the PAK file format? (recode?)
Images are stored internally as 16bit numbers to reduce memory footprint of map structures. Registering generates the id from the pointer (and fills internal structures for further use).
Quote
Why are the registered images stored with realloc and not in a std::vector or other stdlib container (or is this code from the C version of Simutrans)?
The realloc is only used for the growing list of pointers to image structures.

As to the getter-setter discussion: Did not read much of it, but I would prefer public member variables for trivial members instead of get/set methods (just for code brevity).
Title: Re: [Project] GUI Theme
Post by: Fabio on August 31, 2013, 09:24:27 PM
A challenge with programs portable across different systems is dealing with the different standards for each platform. Simutrans clearly has its own look, but should it have its own rules for input or just rely on higher level input from the OS?
A challenge with programs portable across different systems is dealing with the different standards for each platform. Simutrans clearly has its own look, but should it have its own rules for input or just rely on higher level input from the OS?

Maybe it's time for Simutrans to virtualize mouse gestures. Gestures (and key presses) could be registered and associated to commands at runtime, as mapped in a tab file.
click, ctrl-click, right click, long press, drag, ctrl-drag and so on could be mapped to Simutrans GUI events in a simuevents.tab file so that it can be OS consistent or player customized.
Even individual tools could have custom settings for their behavior: base, ext1 (ctrl), ext2 (shift), ext3 (ctrl shift). They could be custom mapped according to the device or player preferences.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 31, 2013, 11:34:33 PM
Maybe it's time for Simutrans to virtualize mouse gestures. Gestures (and key presses) could be registered and associated to commands at runtime, as mapped in a tab file.
click, ctrl-click, right click, long press, drag, ctrl-drag and so on could be mapped to Simutrans GUI events in a simuevents.tab file so that it can be OS consistent or player customized.
Even individual tools could have custom settings for their behavior: base, ext1 (ctrl), ext2 (shift), ext3 (ctrl shift). They could be custom mapped according to the device or player preferences.

You described exactly what I meant :thumbsup:

With a layer in between translating mouse/keyboard/gestures into "standard" Simutrans events would take care of the platform differences.
Title: Re: [Project] GUI Theme
Post by: Max-Max on August 31, 2013, 11:59:00 PM
Maybe you figured the answer for these questions already...Images are stored internally as 16bit numbers to reduce memory footprint of map structures. Registering generates the id from the pointer (and fills internal structures for further use).The realloc is only used for the growing list of pointers to image structures.
Yea, I figured that out. How ever, by storing the bilt_becht_t as an array makes it cumbersome to delete images and I guess this is why we keep adding them at the top. One "simple" solution would be to replace the array with a std::map<image_id,bilt_becht_t*> container object. To get the pointer we use the find(KEY) member. In this way we can delete and add images as we like on the heap.

As to the getter-setter discussion: Did not read much of it, but I would prefer public member variables for trivial members instead of get/set methods (just for code brevity).
Ahh, good to hear that some one shares my opinion :)
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 01, 2013, 12:15:21 AM
That would make it much much slower to look up images though!
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 12:31:35 AM
That would make it much much slower to look up images though!
I'm not 100% sure what algorithm is used, but I think it is b-tree. It might be surprisingly faster than you think. There is only one way to find out ;)

I guess we have to think about the pros and cons... Be able to use the memory more effective or a faster lookup...
Well, it was just a thought...
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 12:35:50 AM
Another thought on virtualisation.

For the theme we would need to detect mous_enter and mouse_leave to implement the hover state (also called 'hot' state in some GUI's)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 12:56:19 AM
Prissi and Ters...

I'm trying to use the scr_rect as Prissi changed it but it is really a huge pain in the xxxx to always have to use function calls for everything. The code looks more cluttered and hard to read than ever.

Can we please ( ~big round puppy eyes~ ) go back to have x,y,w,h as public members! I will agree to almost  everything else ,if we can get back to make these public...  ;)

I can add a bottom() and right() function to get my absolute positions (not used for margins).
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 01, 2013, 08:20:00 AM
Quote
I'm not 100% sure what algorithm is used, but I think it is b-tree
Whichever algorithm is used that will be signifcantly slower than simply loading a value from an array. Considering that Loading/Unloading images will be done rarely a better way would be to have a variable pointing to the next free location in the array. Pseudo-code:
Code: [Select]
images[MAX_IMAGE];
next_free_image = 0;
...
init_images()
{
  for(i=0; i<MAX_IMAGES; i++) {
    images[i]=NULL;
  }
}
...
unload_image(image_number)
{
  <image deleting code>
  ...
  images[image_number]=NULL;
  if(image_number<next_free_image) {
    next_free_image=image_number;
  }
}
...
load_image()
{
  image_number = next_free_image;
  ...
  <load image code to images[image_number]>
  ...
  for(i=image_number; i<MAX_IMAGES; i++) {
    if(images[i]==NULL) {
      next_free_image=i;
      break;
    }
  }
  ...
  return image_number;
}
Title: Re: [Project] GUI Theme
Post by: Ters on September 01, 2013, 08:24:48 AM
Yea, I figured that out. How ever, by storing the bilt_becht_t as an array makes it cumbersome to delete images and I guess this is why we keep adding them at the top.

Simutrans doesn't delete images once they are loaded. Changing this has so wide-reaching consequences that it can easily take a year. And it doesn't really keep adding images at the top, it's just too stupid to know how big to make the array before filling it.

Looking up images is likely so performance critical that it has to be O(1). There is a possible alternative solution, but it would take quite some time to implement and may ruin carefully packed data structures. At the moment, there should be focus at stabilizing the code for a new release rather than pick more things apart.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 12:57:02 PM
The theme manager will create new images and the original images will not be used after that. I thought it would same some space if we could free up the memory.

As I said, it was only a thought and I wanted to raise the subject if some one felt the urge to do something about it ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 01:02:50 PM
Whichever algorithm is used that will be signifcantly slower than simply loading a value from an array. Considering that Loading/Unloading images will be done rarely a better way would be to have a variable pointing to the next free location in the array. Pseudo-code:
Code: [Select]
images[MAX_IMAGE];
next_free_image = 0;
...
init_images()
{
  for(i=0; i<MAX_IMAGES; i++) {
    images[i]=NULL;
  }
}
...
unload_image(image_number)
{
  <image deleting code>
  ...
  images[image_number]=NULL;
  if(image_number<next_free_image) {
    next_free_image=image_number;
  }
}
...
load_image()
{
  image_number = next_free_image;
  ...
  <load image code to images[image_number]>
  ...
  for(i=image_number; i<MAX_IMAGES; i++) {
    if(images[i]==NULL) {
      next_free_image=i;
      break;
    }
  }
  ...
  return image_number;
}

This looks like an excellent idea! Since this is mainly done at startup, it really doesn't matter that much if it takes little bit of time to lookup the next free image index...
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 01, 2013, 05:00:22 PM
Theme manager patch!!!

Here is an early proof of concept path of the Theme manager.
It reads the original skin-PAK format and creates the images needed to draw an arbitrary framed rectangle with the skin.

In this patch only the round button is using the theme manager. It can be tested and used if you add this theme.tab file to the theme directory:

gui_button_width      = 100
gui_button_height     = 24


You will see that the buttons size changes and still have the same design as in the skin-PAK.

As, I said this is only a proof of concept so it is a bit hackish and the so debated scr_rect was modified a bit to work better with my needs. scr_rect still needs some redesign and is now in a hackish state.

I have attached a picture of the comic style with the above theme.tab parameters.
Well, we are getting to our target bit-by-bit... :)
Title: Re: [Project] GUI Theme
Post by: Ters on September 01, 2013, 06:29:54 PM
Whichever algorithm is used that will be signifcantly slower than simply loading a value from an array. Considering that Loading/Unloading images will be done rarely a better way would be to have a variable pointing to the next free location in the array. Pseudo-code:
Code: [Select]
images[MAX_IMAGE];
next_free_image = 0;
...
init_images()
{
  for(i=0; i<MAX_IMAGES; i++) {
    images[i]=NULL;
  }
}
...
unload_image(image_number)
{
  <image deleting code>
  ...
  images[image_number]=NULL;
  if(image_number<next_free_image) {
    next_free_image=image_number;
  }
}
...
load_image()
{
  image_number = next_free_image;
  ...
  <load image code to images[image_number]>
  ...
  for(i=image_number; i<MAX_IMAGES; i++) {
    if(images[i]==NULL) {
      next_free_image=i;
      break;
    }
  }
  ...
  return image_number;
}

My biggest worry is that all code expects image handles to be valid forever. Identical images are also merged, so one would also need reference counting to ensure that the image isn't freed until all copies have been requested deleted.

For now, it's best to just live with that images are loaded at startup, and never changed after that. Users probably change pak sets more often than gui themes, and they don't compain too much about having to restart Simutrans in order to do so.
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 01, 2013, 07:13:11 PM
Well yes - the main benefits from my point of view are greater ability to customerise look of paksets and also greater easy of use on tablets and portable devices without compromising ease of use on desktops. So not being able to switch themes while simutrans is running isn't really a huge drawback for me.
Title: Re: [Project] GUI Theme
Post by: prissi on September 01, 2013, 08:53:29 PM
It is very easy to switch themes during runtime, as those images would be added on top, or else would be reused. The overhead of adding another 50 images is neglible. Furthermore, switching themes will only mostly happen once (like language selection). So I am not worried about some extra images.

As written at east twice before: if the images are loaded from a pak, then it is trivial to have some roundbutton, colorbutton, ... skin_besch_t which always is pointing to the correct entry without using an additional layer in between. As such the thememanager seems not usesful. Rather first we have to decide which skins are needed, i.e. which images we need.

On the fly rendered images will make it impossible for an artist to design on a consistent look. Hence a theme manager should not touch the images, just load them. I do not recommend to work against artists.

And before opening the problem with the theme manager, I would be very grateful if first the full functionality of dialogues is restored. As it stands now, there are still half hidden scrollbars and similar things around.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 02, 2013, 12:31:31 AM
As written at east twice before: if the images are loaded from a pak, then it is trivial to have some roundbutton, colorbutton, ... skin_besch_t which always is pointing to the correct entry without using an additional layer in between. As such the theme manager seems not useful.
The theme manager is converting skin format into the new internal format, and later on when we have a new PAK format it will seeming less take care of it. It also has the responsible to substitute non mandatory elements. In its current prof of concept form it doesn't do much yet... The theme manager also centralise the code for basic  theme drawing and all a GUI component need to do is to supply a rect and what theme id should be drawn in, the manager takes care of the rest. I thought the prof of concept would give a hint that it isn't finished, only a prototype, hence to early to complain about its existence or functions. I did stated before that there will be a theme manager...
The theme manager will create new images... (http://forum.simutrans.com/index.php?topic=11956.msg123428;topicseen#msg123428)
I have created a theme manager that prepares all the GUI images. (http://forum.simutrans.com/index.php?topic=11956.msg123378;topicseen#msg123378)
Anyway I doing some "thinking" around the theme manager and experimenting a bit. (http://forum.simutrans.com/index.php?topic=11956.msg122532;topicseen#msg122532)
The Theme manager will chop up this image in 9 uniformed pieces. (http://forum.simutrans.com/index.php?topic=12412.msg122776#msg122776)
...and no one was arguing about the theme manager's existence. Another reason for implementing the theme manager at this stage is that we can use it in our GUI and not have to change the GUI classes when we move to a new format (it will save me a lot of work). Since the theme manager is storing the theme elements in its internal structure, just the same way it will do in the new format, I can develop the GUI controls and adjust the interface to the theme manager as I need. Then we can experiment with PAK formats without having to update every single GUI control and/or dialogues.

The theme manager will also have the Theme selector dialog and a simple editor to tweak the selected theme, such as button sizes...

Rather first we have to decide which skins are needed, i.e. which images we need.
I explained earlier that I will use the current skin-PAK to work out what we need, before we start to code a new theme-PAK format. By using the current skin and convert it to a theme format I can cut corners and show progress much faster.

On the fly rendered images will make it impossible for an artist to design on a consistent look. Hence a theme manager should not touch the images, just load them. I do not recommend to work against artists.
The theme manager is not changing the artist's images or replacing them with some random images. As long you don't override anything in the theme.tab file, it will be just the way as the artist intended it to be. I thought you understood this when we discussed how we can change button sizes and colours with the theme.tab file. The theme manager simply prepares the the images needed to draw a frame from one single picture. It is a lot easier for an artist to see the whole button as a whole and not have to chop it up in small images spread out in a grid, this is what the theme manager does for the artist. The only images that will be rendered by the theme manager are images that can't be substituted by anything else. This is no surprise for the Artist because I'm pretty sure he/she will test the design before releasing it.

And before opening the problem with the theme manager, I would be very grateful if first the full functionality of dialogues is restored. As it stands now, there are still half hidden scrollbars and similar things around.
I have not seen any half hidden scrollbars and I asked (http://forum.simutrans.com/index.php?topic=11887.msg121758#msg121758) TurfIt to show me where and maybe post some screen shots to show, but I never got any answers. If you have noticed something, please show me a screen shot and tell me where. I have gone through every dialogue I can find in the game and not seen anything...
I have intentionally left all the list dialogues untouched because Prissi explicitly told me to stay away from them:
I also explicitely reserved the list windows several time for rework. Really, no need to touch them at all, I am planning to write them more or less new from scratch (same for line management window).

I thought every one would be excited over this progress and I put a lot of hard work behind this. Although my expectation became true, not so positive response, as usual... ~sight~
Title: Re: [Project] GUI Theme
Post by: Markohs on September 02, 2013, 02:07:44 AM
I don't agree of what I've read about the theme selection will just be made once, and to change theme we might require a game restart.

It makes no sense not developing to change themes on the fly, ingame, even previewing each theme. About images not being freed, well, there are various aproaches to the issue, it needs coding ofc.

I know you guys use to like simplifity, and do do I, but in this case it's really pointing to a poor quality solution then, imho.

I agree with prissi's point that dynamic image rendering in game it's not so good idea, and should just be done if absolutely required technically.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 02, 2013, 02:19:24 AM
I don't agree of what I've read about the theme selection will just be made once, and to change theme we might require a game restart.

It makes no sense not developing to change themes on the fly, ingame, even previewing each theme. About images not being freed, well, there are various aproaches to the issue, it needs coding ofc.
Well, this was my intention, to be able to preview the theme in the theme selector, but this will have to be addressed in the end of the project I think. Mean while we can do a restart...

I know you guys use to like simplifity, and do do I, but in this case it's really pointing to a poor quality solution then, imho.
I agree with prissi's point that dynamic image rendering in game it's not so good idea, and should just be done if absolutely required technically.
I have repeatedly stated that images generated entirely by the theme manager are the fall back images. A fallback can be done in several steps before it starts to draw its own images. We can have it to use other theme components images in several fallback steps. These fallback steps aren't random, it will follow the same structure always! So, yes, generating images on its own is the very last resort...

How ever, we aren't there yet. The benefit of having these fallback steps is that we can release new enhanced versions of Simutrans without waiting for the theme/skin-PAK files to be updated, or Simutrans won't start :o
Title: Re: [Project] GUI Theme
Post by: Markohs on September 02, 2013, 03:03:14 AM
Well, this was my intention, to be able to preview the theme in the theme selector, but this will have to be addressed in the end of the project I think. Mean while we can do a restart...

 You are the programmer, I'm just stating my oppinion, ofc. ;)

 Well, it's not like we need to release now, I'd go for the complete solution and not the partial. Having a partial and a post-patch feature planned usually ends on not being even implemented ever, or having to rewrite a lot more, and refactor a lot, simply because you'll end finding a lot of information you don't have now.

I have repeatedly stated that images generated entirely by the theme manager are the fall back images. A fallback can be done in several steps before it starts to draw its own images. We can have it to use other theme components images in several fallback steps. These fallback steps aren't random, it will follow the same structure always! So, yes, generating images on its own is the very last resort...

How ever, we aren't there yet. The benefit of having these fallback steps is that we can release new enhanced versions of Simutrans without waiting for the theme/skin-PAK files to be updated, or Simutrans won't start :o

 No problem then. :)
Title: Re: [Project] GUI Theme
Post by: Ters on September 02, 2013, 04:53:56 AM
I wasn't arguing that we shouldn't be able to switch themes, but that it is postponed until a later release, or we won't be able to make a stable release for another year or so. For now, the goal should be to complete the new GUI rendering part and preferrably the associated PAK formats. Artists can then start making themes while programmers hammer out things like theme selection dialogs and ensure that the game is OK with things being swapped out underneath its feet.
Title: Re: [Project] GUI Theme
Post by: An_dz on September 02, 2013, 09:47:35 AM
If so, here are two patches making two new dialogs follow the new system.

There are some changes and additions that I think might help, will discuss later.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 02, 2013, 04:35:04 PM
Welcome back An_dz and thank you for the patches :thumbsup:

In my earlier work we fine tuned the system a bit more:
  • For all buttons (button_t) the init() and set_type() initializes the button to its default size. As long the button should have the default size, we don't need to specify the size at all. The size parameter in init() can be omitted to get the default size.
  • Now when we can override various GUI controls default size and colours through the new theme.tab file, you will find more D_XXXX_HEIGHT/WIDTH defines to refine how the GUI controls can be tweaked. I suggest you have a look in gui_frame.h for more details.
  • The divider only needs to be set by set_width() to get the default height and look. The height can be changed but there are some divider style enums that can be used instead. Have a look in gui_divider.h
  • There are now some defines for system colours; SYSCOL_XXXX. Have a look in simcolor.h to see what system colours are available.

Down the road I realised that we really need to take a deep look at the GUI structure before we do something else. I felt that there was several GUI controls missing that needs to be implemented. I tried to not do this now but ended up in some hackish GUI changes instead. This is why I stopped to convert dialogues and focused on the GUI structure instead because we will certainly redo all the dialogues once again when this is done.
Title: Re: [Project] GUI Theme
Post by: An_dz on September 02, 2013, 06:53:03 PM
  • For all buttons (button_t) the init() and set_type() initializes the button to its default size. As long the button should have the default size, we don't need to specify the size at all. The size parameter in init() can be omitted to get the default size.
Amazing, will help my work on the map window. I'm moving the map to the top and the buttons to the bottom, so the map is fixed in the window. It's working nice unless you click on scale, selections and/or factories.

  • Now when we can override various GUI controls default size and colours through the new theme.tab file, you will find more D_XXXX_HEIGHT/WIDTH defines to refine how the GUI controls can be tweaked. I suggest you have a look in gui_frame.h for more details.
I did and on my working copy I included the D_ARROW_HEIGHT and D_ARROW_WIDTH for the button_t::gui_arrow_right_size, it could be left too but it's almost obvious that they will have the same sizes.

  • The divider only needs to be set by set_width() to get the default height and look. The height can be changed but there are some divider style enums that can be used instead. Have a look in gui_divider.h
  • There are now some defines for system colours; SYSCOL_XXXX. Have a look in simcolor.h to see what system colours are available.
Ah, great. Will look into those.

Down the road I realised that we really need to take a deep look at the GUI structure before we do something else. I felt that there was several GUI controls missing that needs to be implemented. I tried to not do this now but ended up in some hackish GUI changes instead. This is why I stopped to convert dialogues and focused on the GUI structure instead because we will certainly redo all the dialogues once again when this is done.
Change or fix? If the changes will need a new rework then the new system needs work, but if only small tweaks from the converted version will be needed we can do it so once the new double height code is complete a new version can be launched.
Title: Re: [Project] GUI Theme
Post by: prissi on September 02, 2013, 09:24:48 PM
@Madmax
Well, I mentioned in all those thread that the theme loading could be easily done by me, as soon as we finally agreed what images and what paks we actually want. Getting images for those from artists is usually never a problem, fourtunately. Rather we have artists waiting to provide images. No need for fallbacks.

And images added at the end are already releaseable anyway, so reloading several themes and previewing the will be not too difficult. You can leave this to me, if you doubt it, almost everything needed is there already.

But it would be really needed, if we discuss and agree on what graphics a theme must provide, and how they are names (i.e. what skin.xxx.pak are needed). And to involve everybody, I strongly suggest doing it here, and not via external files.

Currently I think a theme needs
button skins
pos buttons
scrollbars
gadgets
window bars (those need to be in player colors if recolered)
window background

Did I miss something?
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 02, 2013, 10:44:49 PM
Well, I mentioned in all those thread that the theme loading could be easily done by me, as soon as we finally agreed what images and what paks we actually want. Getting images for those from artists is usually never a problem, fourtunately. Rather we have artists waiting to provide images. No need for fallbacks.

And images added at the end are already releaseable anyway, so reloading several themes and previewing the will be not too difficult. You can leave this to me, if you doubt it, almost everything needed is there already.

I have no doubt that you can contribute a great deal here and I have never argued that it won't be possible load/unload a theme, I just feel it is a bit to early to star that work yet. The theme manager will in the end replace the current skinverwaltung_t::window_skin so we need to add the Dialogue, loading/unloading in the theme manager.

But it would be really needed, if we discuss and agree on what graphics a theme must provide, and how they are names (i.e. what skin.xxx.pak are needed). And to involve everybody, I strongly suggest doing it here, and not via external files.

Currently I think a theme needs
button skins
pos buttons
scrollbars
gadgets
window bars (those need to be in player colors if recolered)
window background

Did I miss something?

This is very hard to discuss because I will add new GUI controls and change the GUI structure so we can benefit from class inheritance better. My aim is that each GUI class will have the possibility to have its own set of theme images.

If you star to break down what images are needed, we basically end up with a lot of frames. To demand that all these images has to be defined in a theme-PAK, other wise it won't start, can be cumbersome. Most of the GUI controls will probably use the same frame style anyway. It is here the first level of fallback comes in.

Example: if the artist wants to use the same frame for everything, he shouldn't be forced to define every GUI class to use that same frame. If the theme manager can't find any images for a specific GUI control, it will fallback and use the images of another GUI control, and if that one doesn't exist it will fallback again to the next and so on until a proper set of images is found. This fallback steps are not random and will be defined when we know what we have to work with.

Now as a last resort, the theme manager could draw a simple frame by itself. This frame doesn't need to be bigger than 9x9 pixels to cover all sizes. This is a very simple approach that will allow the game to at least start so a more appropriate theme can be selected.

The theme manager will handle all this when the theme is loaded so each GUI class doesn't need to know if something is missing or not. All GUI classes request their specific set of images and the theme manager does the rest.

Then there are other questions to solve. How to line up a component's background if it has a pattern? I do have ideas of how to solve this.
Then there might be controls where the frame is resized, but the background can't because it has a symbol. How do we handle this in the name of the artist's freedom? (well I do have a plan for how to handle this as well).

The artist must be able to define the client rectangle inside a GUI component, because it depends on his design of the frame how far in the client area starts. I do have an idea for this as well.

It would be awesome if we could do semitransparent windows, as some one suggested earlier. The artist must be able to define if a window should have this or not.


So to answer your question, I can't say what images we need and don't need because we don't know what the GUI classes will look like yet, there are still some questions that needs to be investigated and tested.

This is why I abandoned the Dialogue update because I needed the proper GUI components, and to make them I needed to create some rudimentary theme manager functions, and for this I needed the scr_rect type... everything is connected...

In the very first post of this thread I have included a link (http://mkdevelopment.se/simutrans/SimutransTheme.pdf) to the Theme document. I'm hosting the document on my own server and anyone can easily get it and read it in less time it takes to debate a geometrical definition. The document is full with pictures so there isn't really much to read, but the pictures explains quite a lot.

We can of course discuss the contents of the document here.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 02, 2013, 10:49:18 PM
@An_dz

...I included the D_ARROW_HEIGHT and D_ARROW_WIDTH for the button_t::gui_arrow_right_size, it could be left too but it's almost obvious that they will have the same sizes.
My strategy is that every single GUI image can have its own size, so in practice all the arrows can have different size. I found it very cumbersome to always keep track of each GUI component's size by manually adding the right D_XXX_HEIGHT/WIDTH.

My intention in the new design is that all functions that change a components position or size will return a bounding rectangle. This removes the need of matching constants with used GUI components, the component will instead tell its size.

To be able to do this I needed a rectangle type describing a components size. I made the scr_rect to be an easy type to work with for this purpose. How ever, there was a quite heavy debate about how this scr_rect should work and it ended up in something that doesn't make things easier for me, just more work.

The scr_rect is now in a hackish state and I'm going to adjust some parts of it back to what it was. Unfortunate the scr_rect will not be optimal for my needs any more, due to some geometrical definitions on Wikipedia that was more important to follow than its practical use :o

If the changes will need a new rework then the new system needs work, but if only small tweaks from the converted version will be needed we can do it so once the new double height code is complete a new version can be launched.

I'm trying to work on the new system right now but it seems like I spend more time debating than coding for the moment... :P
Title: Re: [Project] GUI Theme
Post by: Markohs on September 02, 2013, 11:58:29 PM
I'm trying to work on the new system right now but it seems like I spend more time debating than coding for the moment... :P

 I want you to take my comment as a constructive one, I think sometimes I sound too harsh.

 I advise you to just code, avoiding discussions as much as you can. Getting comments to your work is time-consuming, and it's better to just focus designing yourself, implementing it, one-way.

 Once you have it implemented, just post the patch, it will require minor tweaks, most of the times.

 You will never reach a agreement, allways someone will ask for features or not like some aspects of what you did. It's better to just code, all will be more agile. The only requirement to code this way is writing code that's able to be changde easly, making it modular and very decoupled.

 Just keep jitting milestones in your project, don't stop. It's easier to fix things than getting consensus over new code.

 Also, it's easy to give oppinions, and asking for different aspects of the design, but once the code it's written, then it's already working code, they allways have the option of fixing or recoding it themselves.

 On my last world limits patch, I know there were some things that were not polished, and some aspects were discutible, you'll see almost every current simutrans coder has slowly been modifying my code to make it better. This is how a open source community works, and it's great.

 Don't be afraid, just code, code an code, and once you are happy, submit the patch for the review.
 
 My oppinion, and my advise, ofc. This is just my point of view. ;)
Title: Re: [Project] GUI Theme
Post by: prissi on September 03, 2013, 08:04:27 PM
I think a theme manager is not needed at all. Theme images would load into skinverwaltung, and missing images would just take from what was there previously. Again, do not worry about missing stuff, this was and probably will never be a problem. If images are defined twice, they will be reused and do not consume additional memory. It just needs another line in a dat file. Even if somethingg is missing: as long as there is a complete theme (which will be anyway distributed by the executable). Hence, no need for an extra theme manager layer. Keep it simple!

Moreover, the theme are defined the thmes.dat; hence specifying a transparency for the background there is straight forward. And before adding more complex code by changing gui elements, I would rather finish what there is.

So based on the list I made above I will add the theme with pak loading and the currently needed skins over the weekend, following Markohs advice.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 03, 2013, 09:49:43 PM
@Prissi

Well, another point of the theme management is to encapsulate the theme as a separate system from the GUI components.
If "keep it simple" means no more classes, then why are we using C++ at all?

So please Prissi, tell me exactly what it is that isn't simple? Please point out what functions or design makes this so complicated?

...and I'm still waiting for some pictures on the half scrollbars that needs to be fixed.
I have not seen any half hidden scrollbars and I asked (http://forum.simutrans.com/index.php?topic=11887.msg121758#msg121758) TurfIt to show me where and maybe post some screen shots to show, but I never got any answers. If you have noticed something, please show me a screen shot and tell me where. I have gone through every dialogue I can find in the game and not seen anything...
I have intentionally left all the list dialogues untouched because Prissi explicitly told me to stay away from them.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 03, 2013, 09:53:14 PM
@markohs

I was told that the community was a democratic process and it should be involved (that was how interpreted it).
But it seems like you are right, maybe I should just do my thing on my own and post the milestones.

Well maybe I will do that from now on...
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 03, 2013, 10:34:00 PM
Well, the community is not a dictatorship but we don't formally vote on changes. A consensus is arrived at generally when working out what features to add or how to add them.

In this case the consensus is clearly supportive of the concept of themes - the only question is implementation. I've tended to adopt the philosophy of developing patches more or less on my own, only releasing them when there are obvious new features. As these tend to be ones often requested there are then not very many arguments against adopting the patch.

Whoever develops patches though other people will make suggestions as to tweaks that might improve readability or performance, or fit in better with other code in simutrans. These suggestions are just that, suggestions. You don't necessarily have to follow them if you have good reasons not to and you can see in your own mind where you want the code to go.
Title: Re: [Project] GUI Theme
Post by: Ters on September 04, 2013, 04:41:31 AM
I think a theme manager is not needed at all. Theme images would load into skinverwaltung[...]

Well, another point of the theme management is to encapsulate the theme as a separate system from the GUI components.

skinverwalterung more or less means theme manager, so Simutrans already has a theme manager class. It doesn't need another one, it should just evolve the one it has. But there is a question of drawing the line between skinverwalterung and the GUI components.
Title: Re: [Project] GUI Theme
Post by: Leartin on September 04, 2013, 12:40:15 PM
While I am interested in the GUI topic, this thread is way to technical for me to follow. However, as Max-Max asked for a picture of a half scrollbar:
(http://www.leartin.at/stuff/halfascrollbar.png)

this is r6658, but I guess if Max-Max hasn't seen it before, it has a low chance of being fixed by now.

I believe the mistake here is that the broadness of the scrollbar seems to be read out of the image, while our approach was to let the slider rest on a thinner rail, as seen in the skins.png. As this is a version not officially released I can't give you access to it, but using a window skin similar to this should recreate the effect.

(http://www.leartin.at/stuff/skins.png)

As for a solution... well, I guess thats more or less a problem of the intermediate state. We plan to release the next pak version around christmas, so if at that point your work at the GUI-themes is advanced enough to fix the issue with a theme.pak instead of the skin file, I (we) can bear the half scollbars (or rather extend the rail with a color similar to the background, that should work as well)


Another Mistake was found by Sybill, I'll just link to the thread instead of the image:
http://www.simutrans-forum.de/forum/index.php?page=Thread&postID=96956#post96956
( I don't know what happened there, but the button is to far on the left, not really gone, so I suppose it's a similar mistake)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 04, 2013, 04:33:17 PM
@Leartin

Thank you for the update. This is probably why I haven't seen it. I'm using the standard skin file and the 96Comic.
I think you are on to something, I will have a look at it ASAP.

Is it possible for you to send me the WindowSkin-PAK so I can test? If you don't want it to be public, just send it to me in a private message. I will keep it to myself for test purposes only...
Title: Re: [Project] GUI Theme
Post by: Leartin on September 04, 2013, 05:59:46 PM
Sent you the skin pak.
On closer inspection of sybills button, I realized it's offset fits my assumption. Probably the rightmost button hides some pixel, which make that button effectively 64px broad, centered in the middle.

If this is the same for other mistakes as well, I think it would be fair to say it is a mistake of the image, which shouldn't have any pixels beside the button graphik in the 64x64 box. Though it's different for the scrollbar - Maybe you could check the size of the slider and the arrow buttons as well, using the broadest/highest size you got. Or, if no other pak has this particular problem, leave it as it is. It's a compatibility-thingy, so if the old stuff is compatible that should fit the bill. This design is fairly new, and it can adopt for the time before it is changed into a theme pak.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 04, 2013, 08:49:07 PM
Thank you. With your skin PAK I can see the problem and I have a quit good clue to what it might be. I will get to it ASAP.
Title: Re: [Project] GUI Theme
Post by: prissi on September 05, 2013, 12:01:14 PM
As to the theme manager: Ters put it much better. We have the skinverwaltung. New object will always reside in the same structure. Hence it is a very convenient abstract, as there is alway a valid thing in the same location. The only thing left is to notify the button routine (and scrollbars) that they need to recalculate their sizes.

Since loading themes requires parsing the theme.dat as well as the loading theme paks (which load themeselves into the skinverwaltungs) very little extra code to simwin.cc would result in a dynamic loading of themes. Then the UI to it coudl derived from the savegame frame; especially if there is a preview image savegame frame requested in some other places as well. So it is only on this certain case I do not thing to replicate a something that is already there and rather use the code fully.

NB: verwaltung <-> administration/management.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 05, 2013, 05:10:25 PM
The theme manager is not only loading images, it also keeps track of how a theme element should be drawn. The Artist could for example have configured a background to be transparent, Blended, Solid Colour or Image filled. The GUI control doesn't need to know this, it only tells the manager to draw the background for theme x.

I'm separating the theme from the GUI control so the GUI doesn't need to know how to draw the theme. As it simplest form now, it might look like it doesn't do more than load images, but it will do more than that when it is implemented.

Further down the road when the structure start to settle in, it might be an idea to derive the theme manager from the skinverwaltung class. Just bear with me while the theme manager start to settle in.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 08, 2013, 02:42:19 PM
After some request I have created a GUI Theme thread (http://forum.simutrans.com/index.php?topic=12522.0) aiming artists, no code discussions  ;D

@Prissi
If you haven't started yet, I have soon a new patch ready, fixing the half scrollbars.
Title: Re: [Project] GUI Theme
Post by: prissi on September 08, 2013, 10:30:42 PM
I am only halfway through, I had a nasty bug when loading games before internal rev. 111005 failed with out of index errors. Anyway, this is fixed, so hopefully a patch tomorrow.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 08, 2013, 11:22:36 PM
Failing load games are quite an important issue ;D

Okay I will wait for you, merge and make a new patch then...
Title: Re: [Project] GUI Theme
Post by: prissi on September 09, 2013, 10:09:04 PM
Ok, I deferred so far the themeslector GUI do to lack of time, sorry. You will find here a theme. Copy standard.tab and menu.standardtheme.pak into the program theme folder (need to create it). Then rename standard.tab to theme.tab It should look like before. YOur can pak the skin.dat with "makeobj pak menu.standardtheme.pak" and create other themes in the same way. The diff is also in the zip.
Title: Re: [Project] GUI Theme
Post by: prissi on September 10, 2013, 11:29:05 PM
A version with some bugfixes and a theme selector (work in progress). You need to define a "name="", and size="") in the tab file of the theme.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 11, 2013, 04:54:07 PM
@prissi

The Simutrans installation is not longer valid because of a missing image. It complaints about the square button, but I think it does that because it is at the end of the list.

I think this happened when you added the pos button to the structure. I have always tried to be compatible with the current skin format, just to avoid the situation where Simutrans wont start without a PAK update.

I thought we would focus on what we already have and put the underlay theme structure in place before we started to add new features?

Was this you intention or an accident (not to start Simutrans without the new pos image)?

***EDIT***
I used makeobj pak menu.standardtheme.pak with the skins.dat and images from your standard.zip:

back.png
button.png
gadget.png
posbutton.png
scrollbar.png
squarebutton.png


I created the theme folder in the Simutrans root and copied menu.standardtheme.pak and your standard.tab.
I renamed standard.tab to theme.tab.

Still same error on startup...

You need to define a "name="", and size="") in the tab file of the theme.
name is the theme name, right? but what is size?

PS. how is it going with my last patch? If you haven't started yet let me know and I will send you the next instead.
Title: Re: [Project] GUI Theme
Post by: eipi on September 11, 2013, 07:14:39 PM
Try moving menu.standardtheme.pak into the pakfile directory, this has worked for me.
Title: Re: [Project] GUI Theme
Post by: prissi on September 11, 2013, 08:08:18 PM
Assuming you are using the latest patch and the previous files. You need a new directory, named "themes" in the folder where the executable is. Copy menu.standardtheme.pak and the tab file there. Simutrans will (by default) now load this theme.tab and will ignore all skins.

Not using skins is intended. When you use 9 component buttons, and titlebar images, it has to go anyway. As said before, we will get plenty of themes fast. I am not worrying about braking the compatibility. The next simutrans will have some default themes in the themes folder.

About the patch: Well I missed it somehow, so I would not mind an updated version.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 11, 2013, 09:10:58 PM
Copy standard.tab and menu.standardtheme.pak into the program theme folder (need to create it)

I just followed your instructions :)
Okay so the folder should be themes not theme

When I renamed it to themes it started, thank you.
I will merge your patch into my code before I post the patch...
Title: Re: [Project] GUI Theme
Post by: prissi on September 11, 2013, 11:13:36 PM
Use this please, it will load and apply themes, and you can call the dialogue from the display options. You can have a themes folder either in user settings or in the program folder.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 12, 2013, 02:29:24 AM
Maybe it's me, but I'm no expert on SVN.
When I try to apply your patch it complains about the path differs in the patch from what is installed on my system. Whatever solution I chose I end up with either a directory called trunk with all the files or half the patch wouldn't apply (for reasons I don't know).

Can you make a patch without the trunk path?
Title: Re: [Project] GUI Theme
Post by: prissi on September 12, 2013, 09:46:19 AM
As it contains the base.tab below trunk. To apply (I assume commandline and directory is below trunk)

patch -p0 -i thememanager.diff

If you do not care about base.tab, cd to trunk to and then

patch -p1 -i ../thememanger.diff (or where your file is)

But I happily commit it, if you are ok with it. Makes things easier.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 12, 2013, 04:09:23 PM
What is the size parameter you refer to in the theme.tab file doing?

I have not yet tried your instructions, I'm refining error handling in the theme manager first...
Title: Re: [Project] GUI Theme
Post by: prissi on September 12, 2013, 04:15:07 PM
I am not sure what error handling. My patch load new themes and instantaneously applies them by just replacing the images in skinverwaltung automagically. No need for an explicit theme manager. Although it would make sense to have the size definitions as well as the images and the loading of the theme.tabs in their own file.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 12, 2013, 04:59:47 PM
I'm improving the error handling in my theme manager, not your patch. I will fix this before I apply your patch.

But what is the size parameter in theme.tab referring too? Size of what?

As I said so many times before, some parts of these small updates doesn't make sense yet...
They are still work in progress and a part of a greater plan which may not be 100% clear at this point. I could spend a few weeks on writing a draft to explain all this, but since no one even wants to spend 5 minutes to read the current draft, I see no point in writing it further.

I explained this before, the GUI component and the actual drawing are separated. The GUI component tells the theme manager to draw a theme element within a bounding rectangle. It doesn't need to know if this is a frame, horizontal, vertical or symbol theme type.

When the theme manager initialises, it creates theme element instances of the type fitted for the available images and later on to the artists specification. In this way the GUI controls doesn't need to have multiple code for different scenarios.

Handling this through polymorphism, the calling process becomes clean because the theme manager just pick the requested theme element instance and calls the virtual function display(), regardless of the theme type. No need for endless switch case statements.

When I get your patch in place I will move some of it into the theme manager, to handle load/unload and theme browsing from there. Encapsulating all theme related functions into the same object makes it more structured and clean.

I will implement your patch as soon I have finished some error handling in my theme manager...
Title: Re: [Project] GUI Theme
Post by: prissi on September 12, 2013, 09:55:32 PM
OK, I submitted my final, cleaned up code to the svn. The gui_theme.cc may be already something, what you envision for your theme manager.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 01:41:57 AM
@Prissi

Thank you for the commit but  I can't compile due to the file gui_theme.cc and gui_theme.h are missing in the SVN trunk.
Title: Re: [Project] GUI Theme
Post by: prissi on September 13, 2013, 09:32:56 AM
I knew I missed something with such a large patch. Sorry, you have to wait another 10 hours until I am home again.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 09:38:01 AM
I knew I missed something with such a large patch. Sorry, you have to wait another 10 hours until I am home again.
:-[

Maybe I need to get out from my cave for a while :P
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 03:31:42 PM
@Prissi,

I saw that you had commited depot_frame.xx in 6703, but the Trunk can still not be compiled without the gui_theme.xx files ;)
(I guess you forgot about it)...
Title: Re: [Project] GUI Theme
Post by: prissi on September 13, 2013, 03:33:25 PM
No I fix it with r6701, updated it, commited and got back to 6701. Still at work, babysitting our growth reactor.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 03:40:59 PM
No I fix it with r6701, updated it, commited and got back to 6701. Still at work, babysitting our growth reactor.
Now you got me confused  :o
What did you fix in r6701? I'm browsing the HEAD rev. in repository and I can't find gui_theme.cc or gui_theme.h anywhere... Well I saw you had commit something in r6703 so I thought you where back home again...

Growth reactor, sounds interesting. Can we put Simutrans in it  :D
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 13, 2013, 05:03:06 PM
Prissi has said he will add gui_theme.cc and gui_theme.h when he gets back home this evening :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 05:05:40 PM
Prissi has said he will add gui_theme.cc and gui_theme.h when he gets back home this evening :)
I kind'a guessed that too. Maybe you can explain what he meant with this "No I fix it with r6701, updated it, commited and got back to 6701." That was the confusing part... :o
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 13, 2013, 05:09:34 PM
It might be easy to forget but English isn't prissi's native language - just be patient wait for later this evening and am sure everything will be sorted :)
Title: Re: [Project] GUI Theme
Post by: prissi on September 13, 2013, 07:56:58 PM
Code: [Select]
svn up -r 6701
[now fix depot, compile, test]
svn up
svn commit -m "..."

Anyway, gui_theme.* are submitted. (Actually, with my horrible spelling and sentences, it should be clear that english is far from being my strong side).
Title: Re: [Project] GUI Theme
Post by: TurfIt on September 13, 2013, 08:34:34 PM
Did you submit the wrong files? r6704 still doesn't compile.
Code: [Select]
In file included from gui/display_settings.cc:29:0:
gui/themeselector.h:27:7: error: extra qualification 'themeselector_t::' on member 'rdwr' [-fpermissive]
make: *** [build/default/gui/display_settings.o] Error 1
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 09:07:38 PM
I have never complained about any ones English, I'm not native English myself. I was just confused by the sentence which I understood probably must have been a typo, and I couldn't figure out what it was supposed to be.

I'm still confused what the fuzz about r6701 is? All I wanted was the gui_theme.cc and gui_theme.h that was just added today in r6704. Maybe I was unclear somewhere earlier in the thread...

Anyway, I have the files, thank you Prissi.

Mean while TurfIt seems to have problems compiling it, I will give it a try and see...
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 13, 2013, 09:32:00 PM
I can confirm that I got lots of compiler errors, but after I started over with a fresh checkout it compiled fine. I'm on VC++ 2012 so I have to manually update the project and solution files... But it compiled with success  :thumbsup:
Title: Re: [Project] GUI Theme
Post by: Miziiik on September 13, 2013, 10:34:15 PM
Yep, it's working for me too  ;) Good job!

But what about saving the selected theme? Now I must choose theme with every start of game  :-[
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 12:20:46 AM
@Prissi

I have managed to merge and solved most conflicts but It seems like we are developing the same code in different directions...
I know that you think my theme manager isn't needed, but it is a part of a greater plan I'm working toward.

I'm having a quite difficult time to sort this out because all theme drawing is done by the theme manager and there isn't much code left in the gui_button_t class.

But what I see as the biggest obstacles is that you have divided skinverwaltung_t::window_skin into several lists, one for each GUI control what it looks like.
Why are we doing this?
Do we need this to solve a problem?

To add more theme elements we would need a new const skin_besch_t* skinverwaltung_t::xxxxx and when analysing these images we need to know in what list an image reside in, depending on the GUI control type.

Why not keep all them images in one skinverwaltung_t::theme_images? If we need to add more themes we just add one more enum.

Since we have control of both writer and reader, we could go away from the indexed image numbers and use real words instead like:
image[button,up] =
image[button,down] =
image[button,disabled] =
image[button,focus] =
image[button,hot] =


The writer would translate this to indexes (or even better, store the name with each image).
Can we go back to use a single skinverwaltung_t::theme_images instead?

The theme selector turned out great :thumbsup: just unfortunately that the other stuff collided as it did...
Title: Re: [Project] GUI Theme
Post by: captain crunch on September 14, 2013, 02:05:17 AM
Please fix the path separator.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 02:37:19 AM
Please fix the path separator.
Consider it done... ;)

It's quite hard to merge code that has taken different development paths. I have now kept as much I can and reverted some parts back to what it was. But don't worry Prissi. I do see your intentions and I will go through your arrangements by hand and try to apply it into the theme manager. But on one point I'm afraid I have to revert back all teh way; one list for the theme images. I renamed it to skinverwaltung_t::theme although.

Further down the road when we know more of the new theme format we can discuss another solution. For me it feels natural to let the theme manager read the theme-PAK into a temporary list and then free it because it has reorganised everything internally in objects.

Well, now it compiles and run :) Next step to transfer your efforts...
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on September 14, 2013, 04:04:30 AM
I'm on VC++ 2012 so I have to manually update the project and solution files... But it compiled with success  :thumbsup:

The last time I had tries to compile simutrans with VC++ 2012, there were some mistakes ... I would greatly appreciate if I get the code ready for copirlo only with VC++ 2012

sorry for the inconvenience :thumbsup:
Title: Re: [Project] GUI Theme
Post by: prissi on September 14, 2013, 08:52:06 AM
The array in skinverwaltung is named "menu" since it comes from menu.xxx.pak. Hence the names, the symbols in skinverwaltung_t cam from "symbol.xx.pak" Hence I would suggest to keep it "menu".

Anyway, I look forward to a cleaner button_t (or rather several button classes, like pos_button_t, check_button_t, scrollbar_t, color_button_t spring to my mind). The static button images are not needed any more and do not take up much time to lookup, since the lists are much shorter. Hence they can easily replaced via direct lookup.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 11:29:22 AM
The array in skinverwaltung is named "menu" since it comes from menu.xxx.pak. Hence the names, the symbols in skinverwaltung_t cam from "symbol.xx.pak" Hence I would suggest to keep it "menu".
I'm not really sure I understand exactly what you refer too. It is still a menu "object" I only renamed skinverwaltung_t::window_skin to skinverwaltung_t::theme, it is still a menu "object", or did I misunderstand something?

Anyway, I look forward to a cleaner button_t (or rather several button classes, like pos_button_t, check_button_t, scrollbar_t, color_button_t spring to my mind).
You are absolutely right, this is the second phase, redesign of the GUI class structure.

The static button images are not needed any more and do not take up much time to lookup, since the lists are much shorter. Hence they can easily replaced via direct lookup.
Are you referring to the fallback code? Everything that has to do with theme images (or their replacement) are handled transparently through the theme manager. At this point there is no fallback at all (except a proxy rectangle for debug purpose).
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 11:35:41 AM
The last time I had tries to compile simutrans with VC++ 2012, there were some mistakes ... I would greatly appreciate if I get the code ready for copirlo only with VC++ 2012

sorry for the inconvenience :thumbsup:

I thought I was the only one on VC++ 2012 :) I can include the VC++ 2012 project file in the next patch.
Title: Re: [Project] GUI Theme
Post by: prissi on September 14, 2013, 11:57:38 AM
Getting offtopic, but does MSVC not update older project files?
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 12:39:37 PM
It is a manual process that I have to do every time I update from the trunk. The update is irreversible so I can't include the project file when I commit (or do a patch) and I have to instruct every one if I have added or remove files from the project. You can't open a 2012 project with 2010 (I was told when I made my first patch).

Besides that, isn't it time to move on? ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 03:10:17 PM
@Prissi

For the moment I need to change the theme.dat format back to what is was before as one named object. I will change the object from WindowSkin to Theme and go back to one indexed image array (in .dat file).

I can write a tokenizer and a scanner as the next step so we can classify each word and do some rudimentary syntax check. It would then be quite easy to read this kind of .dat file setup.

Code: [Select]
obj=menu
name=theme

Window[Background] => back.0.0

Gadget[Close]    => gadget.0.0
Gadget[Help]     => gadget.0.1
Gadget[Minimize] => gadget.0.2
Gadget[Previous] => gadget.0.3
Gadget[Next]     => gadget.0.4
Gadget[Unsticky] => gadget.0.5
Gadget[Sticky]   => gadget.0.6
Gadget[Resize]   => gadget.0.6
Gadget[Goto]     => gadget.0.8

Arrow[Up]
Arrow[Down]
Arrow[Left]
Arrow[Right]

Button[Up,Left]
Button[Up,Middle]
Button[Up,Right]
Button[Down,Left]
Button[Down,Middle]
Button[Down,Right]
#Button[Disabled,Left]
#Button[Disabled,Middle]
#Button[Disabled,Right]

Checkbox[Unchecked]
Checkbox[Checked]

Scrollbar[Vertical,Background]
Scrollbar[Vertical,Knobb,Top]
Scrollbar[Vertical,Knobb,Middle]
Scrollbar[Vertical,Knobb,Bottom]
Scrollbar[Vertical,Up]
Scrollbar[Vertical,Down]

Scrollbar[Horizontal,Background]
Scrollbar[Horizontal,Knobb,Top]
Scrollbar[Horizontal,Knobb,Middle]
Scrollbar[Horizontal,Knobb,Bottom]
Scrollbar[Horizontal,Up]
Scrollbar[Horizontal,Down]

With such format the Artists doesn't need keep track of index numbers and if we want to add something it is still grouped disregarding of where it actually ends up. The writer only needs to map the "words" to index enums and no changes are needed in Simutrans (other than adding new enums to the index list).
Title: Re: [Project] GUI Theme
Post by: Dwachs on September 14, 2013, 04:56:10 PM
You may want to check the besch/writer directory. There similar parsing tasks are performed, not all dats have things indexed by numbers. Vehicles use letters to indicate directions for instance.
Title: Re: [Project] GUI Theme
Post by: Leartin on September 14, 2013, 05:43:32 PM
Your dat structure gave me an idea. It might be useful to divide a theme pak into various parts, like gadget, button, scrollbar - so that you don't need to create a full theme to change parts of it. There isn't that much difference between two themes just because one has light gray buttons and the other beige buttons, or ones scrollbar is rectangular and the others rounded. Certainly, it wouldn't be worth to create 4 full themes, but if it's just spare parts as a bonus it might come in handy (if it isn't too hard to do. I guess now is a better time to mention it than when everything is in place)

Just because it strikes me, why do you only mention left, middle, right for buttons? Either those are done in nine parts and therefore nine pictures, or you set where they should be cut with another method - but in that case, why not do the same with left, middle, right? I think it's confusing to use two different methods for button-cutting and would prefer 9 seperated images, as you could understand an image just by looking at it and don't need to read the dat.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 06:35:42 PM
Your dat structure gave me an idea. It might be useful to divide a theme pak into various parts, like gadget, button, scrollbar - so that you don't need to create a full theme to change parts of it. There isn't that much difference between two themes just because one has light gray buttons and the other beige buttons, or ones scrollbar is rectangular and the others rounded. Certainly, it wouldn't be worth to create 4 full themes, but if it's just spare parts as a bonus it might come in handy (if it isn't too hard to do. I guess now is a better time to mention it than when everything is in place)
I don't know if you knew this but all image parts doesn't need to be in the same theme image. You can take the button images from one image and scrollbar images from another, everything doesn't need to be in the same image. So if I understand you right, you can achieve the same thing by using separate image files for different parts of the theme. After makeobj everything is collected in one single theme.PAK file. After som earlier discussions we came to the conclution that it was probably best to have all theme images in one single PAK file, so it can be easily distributed.

Just because it strikes me, why do you only mention left, middle, right for buttons? Either those are done in nine parts and therefore nine pictures, or you set where they should be cut with another method - but in that case, why not do the same with left, middle, right? I think it's confusing to use two different methods for button-cutting and would prefer 9 seperated images, as you could understand an image just by looking at it and don't need to read the dat.
I have kept the current format because we do this in smaller steps and not change to much at once. My goal is in the end to use the same strategy as the Torque game engine uses; a guard color. This means that you don't need to split up a button in 9 images, you just draw one button and paint in how it should be divided. Depending on how it is divided, the theme manager can apply the frame (3x3), horizontal (3x1) or vertical (1x3) rule to it.

***EDIT***
I will give you an example of the current system:

Code: [Select]
# BUTTONS #######################################
Image[12]=> button.3.0
Image[13]=> button.3.1
Image[14]=> button.3.2
Image[15]=> button.3.3
Image[16]=> button.3.4
Image[17]=> button.3.5
Image[6]=> checkbox.0.0
Image[7]=> checkbox.0.1

# HORIZONTAL SCROLLBAR ##########################
Image[24]=> horizontal.0.0
Image[25]=> horizontal.0.1
Image[26]=> horizontal.0.2
Image[27]=> horizontal.0.3
Image[28]=> horizontal.0.4
Image[29]=> horizontal.0.5

# VERTICAL SCROLLBAR ############################
Image[30]=> vertical.0.0
Image[31]=> vertical.0.1
Image[32]=> vertical.0.2
Image[33]=> vertical.0.3
Image[34]=> vertical.0.4
Image[35]=> vertical.0.5

..and this is the same with the proposed new system towards the final solution:

Code: [Select]
Button[Up,Left]     => button.3.0
Button[Up,Middle]   => button.3.1
Button[Up,Right]    => button.3.2
Button[Down,Left]   => button.3.3
Button[Down,Middle] => button.3.4
Button[Down,Right]  => button.3.5

Checkbox[Unchecked] => checkbox.0.0
Checkbox[Checked]   => checkbox.0.1

Scrollbar[Horizontal,Background]   => horizontal.0.0
Scrollbar[Horizontal,Knobb,Top]    => horizontal.0.1
Scrollbar[Horizontal,Knobb,Middle] => horizontal.0.2
Scrollbar[Horizontal,Knobb,Bottom] => horizontal.0.3
Scrollbar[Horizontal,Up]           => horizontal.0.4
Scrollbar[Horizontal,Down]         => horizontal.0.5

Scrollbar[Vertical,Background]     => Vertical.0.0
Scrollbar[Vertical,Knobb,Top]      => Vertical.0.1
Scrollbar[Vertical,Knobb,Middle]   => Vertical.0.2
Scrollbar[Vertical,Knobb,Bottom]   => Vertical.0.3
Scrollbar[Vertical,Up]             => Vertical.0.4
Scrollbar[Vertical,Down]           => Vertical.0.5

At the final solution we could expect something similar to this:

Code: [Select]
Button[Up]   => button.0.1
Button[Down]   => button.0.2
Button[Disable]   => button.0.3
Button[Focus]   => button.0.4
Button[Hot]   => button.0.5

Checkbox[Unchecked] => checkbox.0.0
Checkbox[Checked]   => checkbox.0.1
Checkbox[Disable]   => checkbox.0.2
Checkbox[Focus]   => checkbox.0.3
Checkbox[Hot]   => checkbox.0.4
Checkbox[Multi]   => checkbox.0.5

etc...

In this latter format only one image per state (down, up, disabled, hot, focus etc...) would be required, painted with guard lines.
Title: Re: [Project] GUI Theme
Post by: prissi on September 14, 2013, 08:10:17 PM
Did you had a look at my pak files: The is a pak file for checkboxes, scrollbars, posbuttons. This is way more efficient than a single list, and in the program you request from posbutton in skinverwaltung the image.

And the numbers did not stop people from contributing skins (although most several years ago and hence hidden deep in the forum). If you want to change the poak system, then please open another thread. But I would like to focus on getting a releaseable version with scaling interface across all dialogues.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 14, 2013, 10:33:17 PM
Did you had a look at my pak files: The is a pak file for checkboxes, scrollbars, posbuttons.
Yes I could notice the new arrangement because it broke everything I had done. With your solution we get one list for each GUI control. Meaning when we have more GUI controls there will be a lot of small lists, and everytime we add a new GUI control we need to create yet another list. When I require an image, I can't treat them all the same because I have to know what GUI control I'm dealing with, so I have to select the right list. You also pointed out that the theme manager was redundant because the skin list does what ever you think the theme manager is doing. I replied that the Theme manager can replace the skin list completely, it is not needed at all once the pictures are in the theme manager. So it doesn't make sense to split up the one list into several list which are only used once at theme loading.
Nothing else in Simutrans are going to access the images directly, it is only the theme manager that has the images and does theme drawing.

his is way more efficient than a single list, and in the program you request from posbutton in skinverwaltung the image.
Can you please explain to me in detail how several small lists are "way more effective than a single list"?

And the numbers did not stop people from contributing skins (although most several years ago and hence hidden deep in the forum).
Well, and two legs never stopped people from walking either. Don't you want to improve readability? Du you seriously think that magic numbers are better than an alias?

If you want to change the poak system, then please open another thread. But I would like to focus on getting a releaseable version with scaling interface across all dialogues.
You must have misunderstood me. let me quote myself:
I can write a tokenizer and a scanner as the next step so we can classify each word and do some rudimentary syntax check. It would then be quite easy to read this kind of .dat file setup...
I mean that we will leave the current system just the way it is, no changes for the artist, no changes in the writer/reader, one list, just as before. I put the manager in place and transfer all responsibilities to the manager, regarding GUI theme drawing. At this stage the GUI has been separated from the theme responsibilities.
Title: Re: [Project] GUI Theme
Post by: prissi on September 15, 2013, 02:46:21 PM
The GUI often requires image number 22 in tha image list. Hence it has to travel through the list to get image 22. It is also easier to customize the theme, when I have small paks for single function. I could even lets the user cherry pick. The monlytic lists are also not very good for extensions.

Honestly, I do not understand: There is a system for image management in Simutrans, which every other part of the program is using. There are buttons for components, where drawing a components is what I would expect from an object. I fail to see how an extra layer in between helps to keep the code easy to understand and easy to maintain. But I will wait for your theme manager.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on September 17, 2013, 12:57:54 AM
@Max-Max
Congratulations, the patch looks great :thumbsup: ..... regards!!
(https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-prn1/1234997_627863127253998_69706207_n.png)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 17, 2013, 01:12:45 AM
@Max-Max
Congratulations, the patch looks great :thumbsup: ..... regards!!
Thank you, but I don't want to steal the credit from Prissi. It is Prissi that has done the Theme loader... My patch was never added, but I'm soon ready to send a new patch.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on September 17, 2013, 01:39:53 AM
Thanks to Prissi We also, Both worked hard at this :thumbsup:
Title: Re: [Project] GUI Theme
Post by: prissi on September 17, 2013, 09:44:33 AM
As written before, the theme loading was rather a harm;less two evening patch. I would not have done it (despite on the eternal todo list) if Max-Max would not worked on theme support.
Title: Re: [Project] GUI Theme
Post by: Markohs on September 17, 2013, 11:34:04 AM
Yep, good work! :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 17, 2013, 01:52:47 PM
As written before, the theme loading was rather a harm;less two evening patch. I would not have done it (despite on the eternal todo list) if Max-Max would not worked on theme support.
It wasn't done in vain. The separated image lists gave me a hard time. I have kept the most of your code, but rearranged it a bit. You did a good work all together ;)
Title: Re: [Project] GUI Theme
Post by: kierongreen on September 17, 2013, 04:18:43 PM
The fact that there's two developers working on this and combining the best ideas from both actually shows how important a feature this is :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 19, 2013, 02:09:19 PM
@Prissi

Can you explain your intention a little bit regarding the organisation in the themes folder when we have multiple themes.

As I understand there should be one xxx.tab file for each theme xxx.pak file + one global themes.tab file.
Does the themes.tab file points out the current selected theme pak file?

Are the intention that xxx.tab file and themes.tab file are cascading? Loading xxx.tab and then themes.tab (global)?
Title: Re: [Project] GUI Theme
Post by: Miziiik on September 19, 2013, 02:52:34 PM
I have a question... Is programmed saving of chosen theme?
Title: Re: [Project] GUI Theme
Post by: prissi on September 19, 2013, 08:38:48 PM
Not yet, when finished it would be added to simuconf.tab and the default.sve file.  Reusing what is there already, i.e. for language selection.

But the theme manager is still very much a work in progress, so I did not yet add it.

Themes at the moment will come with one pak file per theme. If teh graphics in it are sizeable then more tab file may refer to the same pak obviously. Teh are either stored in themes/ in the simutrans program folder or the user folder.

On startup, the previously used theme will be loaded (so a tablet always start with its matching theme, not matter what pak was selected). This can be overridden by simuconf.tab.

Again, if you like I could add this today. Saving themes.tab in the program dir coudl fail, because on Linux (debian) as well as standard windows installs simutrans cannot write there.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 19, 2013, 10:53:59 PM
@Prissi,
I'm very soon ready to submit a patch, so It would be good if you could wait until then.

Can you please answer your thoughts around this?
@Prissi

Can you explain your intention a little bit regarding the organisation in the themes folder when we have multiple themes.

As I understand there should be one xxx.tab file for each theme xxx.pak file + one global themes.tab file.
Does the themes.tab file points out the current selected theme pak file?

Are the intention that xxx.tab file and themes.tab file are cascading? Loading xxx.tab and then themes.tab (global)?

*** EDIT ***
My intention was to include all Artist parameters in the theme-PAK file, when we have a new theme-PAK format. Then have one global theme.tab file set by the user to override the Artist's settings. This global theme.tab file is always loaded last regardless of selected theme.pak. This is because a portable device always want large buttons etc...

For example, the button size is defined in this way:

1. Read selected theme.pak.
2. Calculate the button size to the PAK image size for a button.
3. Override with the Artist's button size from the PAK file. (for now a .tab file)
4. Load the global .tab file.
5. Override again with the user's button size.

If no theme-PAK has been specified, load menu.default_theme.pak

Since we have no new theme-PAK format yet, we can use a theme.tab file for the Artist's. Later on when the Artist's params are in teh theme-PAK, this .tab file can be a user configuration for this specific theme-PAK.
Title: Re: [Project] GUI Theme
Post by: prissi on September 19, 2013, 11:04:33 PM
One pak can be used by mane theme.tab files; for instance if we use your 9 image buttons, you can either have non-scalable three button images (only top images, rest empty) or scaleable one. Then you could use a theme in standard, large and tiny (or whatever typical sizes there will be). If not scaleable (which will be probably more common, but I do not know) then you have on tab and one pak.

I think I would always load theme.tab (the global one) with a non-scaling theme and only an essential number of images and afterwards any special theme. The latter can fail, so theme.tab must be anywhere there. If this fails, well then the installation is damaged anyway.

I would not cascade themes. I do not see any advantage. But if ...
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 20, 2013, 01:22:52 AM
One pak can be used by mane theme.tab files.
Good point, sounds great :thumbsup:

...for instance if we use your 9 image buttons, you can either have non-scalable three button images (only top images, rest empty) or scaleable one.
I intend to simplify the image process for the Artist. The artist doesn't need to chop up the images in pieces. There are not 9 or 3 images for a button, only one. The artist then use a guard colour to paint in how the button will be divided, by drawing cut lines over it. I have posted a sample pictures for this many times now.

The theme manager can see, depending on how the guard lines are painted, what theme element style (theme_element_t class) to use for it. It will be chopped up in 9,3 or none pieces and stored internally. If no guard lines are painted at all, we have to decide if it means that no scaling will be done, just use it as a single picture, or if it by default means; chop in 9 pieces and allow scaling, or cop in 3 pieces along the largest side...

The guard colour scheme will be tailored for the theme type it represents. The fundamental idea here is to let the Artist draw the theme element as one single picture. Depending on what it is, we will expect different guard colour lines. For example a window frame will not only have borders and background, but also a caption (title bar).

There is no need to discuss how this is done now, because it is just ideas so far. When we get there we will see what guard colour scheme is the most practical per theme element.

In addition to this I intend to let the artist add parameters to more precisely control the behaviour of the specified theme element.
If several GUI controls are using the same image, I intend to let the Artist be able to specify a "link" to another theme image with the same set of rules or just the same image but a new set of rules to reuse the images and internally use the same theme_element_t object.

Then you could use a theme in standard, large and tiny (or whatever typical sizes there will be). If not scaleable (which will be probably more common, but I do not know) then you have on tab and one pak.
I think I need to make clear what I mean by scaling/resize. There are basically 3 types of "scaling" that I can think of;

1. Stretch
The images are streched in size.

2. Extended
The images are extended instead of stretched.

3. GUI scaling
When a window/dialogues is resized all GUI controls scale in proportions.

I have always been talking about 2 Extending. The actual size of a GUI control is set in the theme.tab and stay at that size. It will not stretch the images and the GUI will not scale when windows/dialogues are resized. Symbols will not stretch to fill the client area, it retain its original size but are centred within the client.

When we use a hires-device these symbols can be to small to see. To solve this I was thinking that the Artist could provide several images of the same theme element, but in different sizes. The theme manager will pick the image with the size best matching the client area.

This is also very useful for the collapse system to free up more space on small portable devices.

I think I would always load theme.tab (the global one) with a non-scaling theme and only an essential number of images and afterwards any special theme. The latter can fail, so theme.tab must be anywhere there. If this fails, well then the installation is damaged anyway.

I would not cascade themes. I do not see any advantage. But if ...
I didn't mean to cascade the PAK-images, only the parameters defining size and behaviour.

The theme manager can substitute missing images, or reload the default theme if there was just to few images available. For example, if there is only one frame image, it can be used for buttons, frames or anything with a rectangular shape. In worst case it can even create a 3x3 pixel frame image with the highlight, face and shadow system colours.

To illustrate the combinations I have attached 6 cases of how a the guard lines can be used in a button.

NoPadding
If no guard colour is detected, all padding are removed.

KeepPadding
The guard colour shows the bounding box and all padding are kept.

HorizontalStyle
If 3 vertical guard lines are detected, the button can be extended horizontally.

VerticalStyle
If 3 horizontal guard lines are detected, the button can be extended vertically.

FrameStyle
If a 3x3 grid is of guard lines are detected, the button can be extended both horizontally and Vertically.

NonUniform.
The 3x3 grid doesn't need to be equal in size. As long there is 9 rectangles, they can have any size so non uniform buttons can be created.
Title: Re: [Project] GUI Theme
Post by: Ters on September 20, 2013, 05:08:03 AM
The cutting lines is a good idea. I think makeobj should be the one to do the chopping, as it chops up all other images already.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 20, 2013, 11:28:05 AM
That was my first intuitive thought too. But since the theme system is still under development we do not know yet exactly what makeobj have to do. To be able to test and develop I use the old skin format and have the theme manager to do the chopping.

Since we already have the functionality in the theme manager we could try to migrate that part to makeobj or just leave it as it is. If we place the intelligence in makeobj we have to update two programs if we improve and change stuff. If the intelligence is in the manager, It might be enough to only update the manager. In that case makeobj only need to pack the full images and doesn't need to worry about guard colours, lines overlays etc...

We will see when we get there...
Title: Re: [Project] GUI Theme
Post by: prissi on September 20, 2013, 04:54:45 PM
For the moment I would suggest to have the artist chopping the images, and worry about that later.
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 21, 2013, 12:44:11 PM
For this precise moment I will leave it exactly as it is...
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 26, 2013, 02:17:01 PM
Okay, we are getting closer to the next patch and while I was testing it struck me...

Now when the theme is loaded, how can we select the skin from the pak-set? Maybe the easiest way would be for the artist to include a menu.xxx.pak + theme.tab file. The pack selector can then scan the pack directories for pak related themes.
A new setting "Autoload pak theme" could have a pak-theme to load automatically when the pak-set is loaded or not.

Thoughts?
Title: Re: [Project] GUI Theme
Post by: prissi on September 26, 2013, 07:58:11 PM
I do not think a pak should enforce its theme, as it may not be suitable for tablets or phone or whatever device the user has its hand on. Hence, it can be paked that additionally to its simutrans/pak.../ fodler it contains a simutrans/themes/pakxyz.tab/pak files, so its theme would be available via the selector. If no theme (or the default thems) has been selected, then an entry in the pak set simuconf.tab for a preferred theme is used, otherwise ignored.
Title: Re: [Project] GUI Theme
Post by: Markohs on September 26, 2013, 09:03:37 PM
It's hard to say, I think I'd keep themes and paksets separated. So no, I think paksets should not specify anything about the theme, and if they do, the less relation possible. :)
Title: Re: [Project] GUI Theme
Post by: prissi on September 26, 2013, 09:06:56 PM
If my post above failed to transmit this: I completely agree with you. I just outlined a way a pak could suggest a thme, and even isntall one optinal choice.
Title: Re: [Project] GUI Theme
Post by: An_dz on September 27, 2013, 04:25:15 PM
It's hard to say, I think I'd keep themes and paksets separated. So no, I think paksets should not specify anything about the theme, and if they do, the less relation possible. :)
But don't we need to specify the pak file in the theme file? Does it ties a theme with only one image set?
Title: Re: [Project] GUI Theme
Post by: Max-Max on September 28, 2013, 04:33:20 AM
We are still in an early stage here, it is hard to tell what is included in a theme and what is a part of the pak-set.
In my opinion, the skin-pak used in the pak-set today should be in the new theme "format" ( a separate pak-file ) but still be loaded with the pak-set if the user wants it. I think the themes that comes with a pak-set is a very important to give the right feel and look.

The user can always override this and use whatever theme he likes...
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 03, 2013, 03:57:16 AM
Okay so I think I finally have something that will enrich the user experience...
The patch gets quite big (I'm truly sorry Prissi), but adds more GUI elements to customize. We are back on the old skin format for the themes, but it can still do some neat new tricks without changing the format. It is even easier to make themes now.

It's quite late now and I will prepare and post the patch tomorrow. Meanwhile here are some eye candy from the comming patch.
There are still some dialogues that needs to be adjusted for buttons larger thean the old standard, and the theme manager have some minor clipping issues. But I will adress this as soon the patch has been implemented.

This is the default theme with the new skin elements. All buttons have an up, down and disabled image. Color buttons can also be themed now.
(http://simutrans-germany.com/files/upload/DefaultTheme.png)

And this is an upgraded Aero theme
(http://simutrans-germany.com/files/upload/AirTheme.png)

Theme images doesn't need to be chopped up anymore, it is enough that they span over the cell borders. Scrollbars and buttons doesn't need to be separated in left,middle and right. Just draw the full button in one cell and the Theme manager will chop it up for you.

Here are some default and Aero theme images...
I will post the source and photoshop files tomorrow as well...

Good night...
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on October 03, 2013, 10:15:15 AM
I like it, Nice work! :thumbsup:
Title: Re: [Project] GUI Theme
Post by: IgorEliezer on October 03, 2013, 09:30:31 PM
DON'T MOVE! I dropped my jaw! O.O
Title: Re: [Project] GUI Theme
Post by: Sarlock on October 03, 2013, 10:37:37 PM
Very nice!  It gives it a very fresh appearance.

Might I suggest symbols in the menu control buttons at the top right to indicate what each colour does?  ie: an "X" in the red circle, etc.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 04, 2013, 12:16:30 AM
Good work! I must say I hate that aero theme, however. It's just personal taste. :)

Congratulations, Max-Max and prissi, for your hard work in the project so far.

I hope our artists get inspired and do a nice theme, I'm pretty tired of seeing the default one, it reminds me of very old UNIX desktops, like CDE, but worse. ;)
Title: Re: [Project] GUI Theme
Post by: An_dz on October 04, 2013, 01:26:32 AM
I hope our artists get inspired and do a nice theme, I'm pretty tired of seeing the default one, it reminds me of very old UNIX desktops, like CDE, but worse. ;)
I always liked the 96comic theme, so bad it doesn't fit the other paksets style.

Good work! I must say I hate that aero theme, however. It's just personal taste. :)
Me too, now imagine a whole OS like it.

Might I suggest symbols in the menu control buttons at the top right to indicate what each colour does?  ie: an "X" in the red circle, etc.
From what I know this theme tries to follow the Mac look and there are no symbols on Mac. This theme should be updated to match the new MacOSX Lion theme.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 01:33:09 AM
Very nice!  It gives it a very fresh appearance.

Might I suggest symbols in the menu control buttons at the top right to indicate what each colour does?  ie: an "X" in the red circle, etc.
It is the Aero skin, modified to a theme pak. I have redrawn the old aero and hasn't really changed so much except it original original size (based on Aqua). The colour dots are a Mac thing and since aero came from the Mac...  ;)

DON'T MOVE! I dropped my jaw! O.O
Thank you, this is only the beginning of the work ahead, but I think we are in a stage where we can see some of effect of my work. Meanwhile Prissi merges this patch into the trunk I will write an "Artist's theme guide" and continue on my mock-up design I showed earlier...


@Prissi (and every one else) ;)
Here is the little too large patch file, but it isn't that bad. Half of it are brand new source files added.
Them manager patch (http://simutrans-germany.com/files/upload/ThemeManager.zip)

Here are the new Simutrans icons and the resource script that selects the right one depending on build version.
Resource script + icons (http://simutrans-germany.com/files/upload/ResourceIcons.zip)

The theme pak format is back to the old format, you will need these new ones. I have built both default and aero in this archive ready to drop in and use.
Ready to use theme paks (http://simutrans-germany.com/files/upload/ThemPaks.zip)

Here are the photoshop source to the themes
New aero theme source (http://simutrans-germany.com/files/upload/aero_theme_source.zip)
New default theme source (http://simutrans-germany.com/files/upload/default_theme_source.zip)

I have not done anything on the original work with dialogues and resize. But as soon this is in the trunk and I'm up in synch this will be my next task on the list. Meanwhile I will write an "Artist's theme guide", explaining what can be themed and not (at this point).

Cheers...

*** EDIT
Some of you had posted before I finished this one... So thank you for the great feedback so far, we will see how the code merge goes  ???
As you will find out there is a new skin for a filter button (the old colour button that couldn't be skinned). Any transparent area will be filled with the button colour.
You will also notice that almost all controls now have a down, up and disable image.
Most of the text, background, highlight and background colours can be set in the theme.tab file. It is a bit chaotic there, but I will clean up and try to find a structure in it...
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 01:46:45 AM
I always liked the 96comic theme, so bad it doesn't fit the other paksets style.
Me too, now imagine a whole OS like it.
From what I know this theme tries to follow the Mac look and there are no symbols on Mac.
Now you can make a Comic theme to be used with any pak-set ;)
Title: Re: [Project] GUI Theme
Post by: Sarlock on October 04, 2013, 02:18:55 AM
Quote
From what I know this theme tries to follow the Mac look and there are no symbols on Mac. This theme should be updated to match the new MacOSX Lion theme.

It is the Aero skin, modified to a theme pak. I have redrawn the old aero and hasn't really changed so much except it original original size (based on Aqua). The colour dots are a Mac thing and since aero came from the Mac...  ;)

Understood.  I never did like those buttons on MacOS... the Windows user in me was so confused that I went crying back to Windows again!   ;D

Wonderful work so far!
Title: Re: [Project] GUI Theme
Post by: Markohs on October 04, 2013, 08:01:51 AM
Me too, now imagine a whole OS like it.
From what I know this theme tries to follow the Mac look and there are no symbols on Mac. This theme should be updated to match the new MacOSX Lion theme.

 I'm allergic to all Apple products and software, I think all they do it's overrated ****. The only good thing they did is iPods, rest is ****. ;)
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 04, 2013, 11:36:32 AM
nice work! impressive patch file. Looks like a lot of clean and nicely documented code :)
Title: Re: [Project] GUI Theme
Post by: Markohs on October 04, 2013, 12:13:06 PM
Just had it a brief look so far, but two comments:
 * .cpp files should be renamed to .cc.
 *  theme_element_t::encode and get_RLE_size can be useful in other parts of code(to build the world slopes for example, but not only there), I'd not associate them just with themes, I'd prefer them under a "imageutils::" or "imagetools::" namespace (this option will be rejected by some developers, I think), so move it to global C functions. They are not functions only related to theme management, so they should be moved.
Title: Re: [Project] GUI Theme
Post by: prissi on October 04, 2013, 12:48:36 PM
It is a very large patch, and some is very nice and on some I think a little polishing is needed. For sure everything in one list will not do, this was a bad design decision by Hajo and I will not repeat it. But I will have to digest this longer.

A few initial comments in the order I found them in the patch:
- While it does not seems so, calling display_fit_proportional and then display_calc_proportional_string_len_width internall, does just replicate what the previous function did. Why doing this twice?
- The debug string will not be shown to the user. It will only yield stupid questions. If you want you can find out about a debug built anyway in the status line if you know where to look.
- I though you would put checkboxes into checkbox_t type and so on. They could still inherit from button. But ok, that is probably next. Similarely, if touching background as button public, then one should do set_background_color() to be consequent.
- you introduce a new element "component" while the GUI already has gui_komponente_t Why???
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 01:29:32 PM
Just had it a brief look so far, but two comments:
 * .cpp files should be renamed to .cc.
The .cpp files are an honest mistake. MSVC automatically add .cpp on new files, I was not paying enough attention, my bad.
*  theme_element_t::encode and get_RLE_size can be useful in other parts of code(to build the world slopes for example, but not only there), I'd not associate them just with themes, I'd prefer them under a "imageutils::" or "imagetools::" namespace (this option will be rejected by some developers, I think), so move it to global C functions. They are not functions only related to theme management, so they should be moved.
In the comments I wrote a note about making raw_bitmap_t to a class, working more or less as a canvas. There are several functions in this category. create_bitmap(), blit(), get_RLE_size(), decode(), encode(), make_horizontal() and make_vertical().

There are also a number of std::string functions that I wasn't sure where to place them; get_path() and get_name(). But I placed the std::string version of trim() in simstring.cc but I'm not sure that would be a good place for it.

This is still in development and more functions will be added, modified or removed... There will for sure be more theme_element_t derivatives as we go along...

It is a very large patch, and some is very nice and on some I think a little polishing is needed.
Keep in mind that this isn't the final, it is a ruff draft and there are a few clipping issues in the manager and no optimization done at all. But what is more important, it is good enough to be used and it will give a quite good user experience. I could go on and do more, but I felt that the patch was big enough.

For sure everything in one list will not do, this was a bad design decision by Hajo and I will not repeat it. But I will have to digest this longer.
What list are you referring to, the skin theme or images[]?

The use of the theme list is really more out of convenience, it is really an unnecessarily step in theme loading. But to get rid of it we need to write a new reader and I would prefer to have the theme manager to do it directly. The use of images[] is because all the display_xxx routines are using it. In my first early test version, the manager was doing this on its own, but I figured it would be better to use the display_xxx functions so I don't need to worry about any format changes in the future.

How ever, thanks to the theme manager it is a lot easier to prepare the theme images than before, but still using the old PAK format so we don't have to touch any reader or writers yet. I think all those magic index in the .dat file can be made simpler. I would like to write a scanner, tokenizer and a parser for the .dat/.tab files. This would allow us to create a more flexible system. By adding the parameter name together withthe value in the PAK file, we are not relying on indexed positions anymore and can actually use names instead. However, loading a PAK file isn't time critical, so we can afford the extra time to search for each parameter and put it where ever it belongs. because the gui elements are easy to visualize as objects, it would only be logical to also have a more object oriented format in the .dat file (...and I'm not thinking of the obj sections in the current format).

A few initial comments in the order I found them in the patch:
- While it does not seems so, calling display_fit_proportional and then display_calc_proportional_string_len_width internall, does just replicate what the previous function did. Why doing this twice?
As I said I have not optimized anything yet. However this isn't anything I have reflected over. Can you point out any place where you see this so I can have a look? When it comes to the drawing of truncated text with an eclipse, it should definitely go into its own function, or be a part of the text drawing routine.

- The debug string will not be shown to the user. It will only yield stupid questions. If you want you can find out about a debug built anyway in the status line if you know where to look.
What debug string are you referring to? There are a couple of them...
I forgot to mention that I have added a DEBUG switch to the makeobj.exe that will dump the progress of PAK creation. It is very useful to find out why a theme isn't working as it should. It dumps the makeobj's intepretation of the .dat file and all image positions, and size.

- I though you would put checkboxes into checkbox_t type and so on. They could still inherit from button. But ok, that is probably next. Similarely, if touching background as button public, then one should do set_background_color() to be consequent.
Yes that will be done in the new gui structure later down the road... For now I have been focusing on theming, next step to fix the remaining dialogues and after that I thinnk it is time for the new gui structure, or the parser...

- you introduce a new element "component" while the GUI already has gui_komponente_t Why???
Oups, my mistake. It is a draft on the new gui structure and it isn't used anywhere. It wasn't supposed to be in the patch at all, please delete it.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 04, 2013, 02:46:06 PM
In the comments I wrote a note about making raw_bitmap_t to a class, working more or less as a canvas. There are several functions in this category. create_bitmap(), blit(), get_RLE_size(), decode(), encode(), make_horizontal() and make_vertical().

 Good.
There are also a number of std::string functions that I wasn't sure where to place them; get_path() and get_name(). But I placed the std::string version of trim() in simstring.cc but I'm not sure that would be a good place for it.

 You also have savegame_frame_t::get_filename and get_basename() . Whatever you decide, both parts of the code should end calling the same function, no core duplicity is desired.

 Cool, let's see what we get when this patch is finished. :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 02:53:07 PM
You also have savegame_frame_t::get_filename and get_basename() . Whatever you decide, both parts of the code should end calling the same function
That is a very good point, but I didn't want to change the current string system. I think maybe we should make use of the std::string class instead of the pre STL string functions. If I'm right, std:string also handles unicode?

The VCL framework have a String type that is redirected to the ANSI or Unicode version depending on compiler target. Maybe we should have something similar, or just always use unicode?
Title: Re: [Project] GUI Theme
Post by: prissi on October 04, 2013, 03:12:51 PM
One question about programming styles. Why do you not make you structures a class when you are using a constructor (or any other function). The ..._tag style is used nowhere in simutrans, and you are more likely to produce clashes by this. If you want to do any function (or whatever I would call a side effect possibility) by something like "bla_t a;" then you should put it into a class.

Or is there a hidden reason for this?
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 03:31:42 PM
One question about programming styles. Why do you not make you structures a class when you are using a constructor (or any other function). The ..._tag style is used nowhere in simutrans, and you are more likely to produce clashes by this. If you want to do any function (or whatever I would call a side effect possibility) by something like "bla_t a;" then you should put it into a class.

Or is there a hidden reason for this?
I assume you are referring to the new scr_size. A struct is the simplest form of a class where all members are public. the _tag is there to be able to define a constructor to initialise the type when it is created. When I created it it just had one constructor and two member variables, then I needed to add some operators and it got bigger...

Structs are by tradition used by POD classes (Plain Old Data), meaning it is a type just like int, double etc... All other classes are defined as class. I'm sidestepping here from a "true" POD definition, by having constructors and operators, but the struct definition indicates that this is a type class that only store information, not a class like a karte_t or frame_t that manage a number of functions.

If you still want everything to be classes, even if they are types with some helper functions, you can turn it into a class and make ALL members public.

*** EDIT
Clarifying:
The use of tag_ is the only way to define members using the type they belong to, since scr_size hasn't been defined yet. This is a common solution to this problem.

A struct is a class with the only difference that all members are default public instead of private (well and the use of a struct vs class may differ in unions and templates).
Title: Re: [Project] GUI Theme
Post by: Ters on October 04, 2013, 04:48:22 PM
If I'm right, std:string also handles unicode?

Yes and no. It handles Unicode like Linux handles Unicode: If it's UTF-8, it's also valid ASCII as far as the computer cares. Everything above codepoint 127 will appear as junk to a human of course, and a char won't necessarily be a complete character, so code wanting to operate on single characters and not just bulk text must do extra processing.

std::wstring, made up of wchar_t, is supposed to be Unicode, but on Windows, it's "just" UTF-16. UTF-16 should be enough, except for certain CJK characters. I'm not sure how common those CJK characters are though. On Linux, wchar_t, and hence std::wstring, is UTF-32 and encode the entire Unicode character set. So in this case, a wchar_t is a always a complete character. It wastes a lot of memory, though.

In my experience, it is difficult to use std::wstring, as lots of legacy APIs only accept char arrays. So in pratice, C/C++ doesn't handle Unicode. Windows has dedicated Unicode APIs (although only UTF-16), so you can almost get it right there if you stick to the Windows APIs. The rest just "fakes it" with UTF-8, which I've learned causes compatibility problems for both Git and Mercurial.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 04, 2013, 10:21:53 PM
The question is really, where do we want to go? If we say that we will support languages such as Chinese, Japanese, Hebrew etc we must support full unicode.

I found recommendations to use the ICU string library (http://site.icu-project.org/) for C/C++ that has full unicode support.
Maybe some one is interested to have a look?
Title: Re: [Project] GUI Theme
Post by: Tazze on October 05, 2013, 12:39:05 AM
The question is really, where do we want to go? If we say that we will support languages such as Chinese, Japanese, Hebrew etc we must support full unicode.
My recommendation is Unicode, UCS-2.
It can apply various language in the world ,of course included in kanji ,in order to wards represented by 2 byte .
This contents is as same as IOS/IEC 10646 (http://en.m.wikipedia.org/wiki/Universal_Character_Set)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 05, 2013, 01:22:31 AM
I have discovered something strange... If I start Simutrans without the -workpath switch AND have configured it to use the default_theme it crash. If I do the same procedure but instead select aero_theme it works well.

Now the strange thing, if I add the -workdir switch, the default_theme works!?!
Same installation and exe in both cases...

So there is something fishy in my patch. I will investigate ASAP...
Title: Re: [Project] GUI Theme
Post by: Ters on October 05, 2013, 07:21:33 AM
My recommendation is Unicode, UCS-2.

UCS-2 has been superseeded by UTF-16 since 2 bytes can't encode all of Unicode. There is still the problem that virtually no API (except Windows') use UCS-2 or UTF-16 (or UTF-32), so you have to convert between them and UTF-8, or perhaps even ASCII.

Simutrans seems to be using UTF-8 when needed and ISO-8859-1 (or rather windows-1251 on Windows) otherwise.
Title: Re: [Project] GUI Theme
Post by: prissi on October 10, 2013, 11:21:59 PM
Ok, I submitted scr_coord.h as suggested. I did not find some of the names very informative, so I changed them. I am open for discussion.

I still like to have a getter and setter instead accessing the elements directly. If everything is public, then we could have stayed with C ...
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 11, 2013, 01:41:48 PM
Ok, I submitted scr_coord.h as suggested. I did not find some of the names very informative, so I changed them. I am open for discussion.
I had commented out not yet used member functions, to be brought in when needed. You added them all back in again, I guess that's okay. I just commented them out to see what members was used and what wasn't...

A better name for the member reduce_to_overlap() (original clip()) imho is intersect() and have another member get_intersect() returning a new scr_rect as suggested.
The term intersect is a common term when performing bool operations on geometry/polygons (http://en.wikipedia.org/wiki/Boolean_operations_on_polygons).

I still like to have a getter and setter instead accessing the elements directly. If everything is public, then we could have stayed with C ...
I have mentioned this before, just because we use a C++ compiler doesn't mean that we have to put everything in classes. By tradition, simple types (POD) are put in structs because they don't need anything more advance that that.

C++ programming and Object oriented design isn't the same thing as putting everything in classes and hide all data... Getter and setters are used when you need to protect the data or perform some automatic operation when the data is accessed. In this case there is no need to do that. I tried the getter/setter version and it was a true pain to use it. These members are accessed so often that the code became really cluttered and hard to follow...
Title: Re: [Project] GUI Theme
Post by: prissi on October 11, 2013, 02:10:43 PM
I left them public for this reason.

About the clip function. Maybe call it clip_to and then the parameter clip?rect instead rect. That may make the function more clear.

Anyway I am working on the rest now.
Title: Re: [Project] GUI Theme
Post by: Ters on October 11, 2013, 02:33:02 PM
I get lots of warnings from scr_coord.h line 192. That function should perhaps return void. Alternatively, if someone is trying out chaining, it should return some form of reference to this, not an instance.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 11, 2013, 04:46:01 PM
I get lots of warnings from scr_coord.h line 192. That function should perhaps return void. Alternatively, if someone is trying out chaining, it should return some form of reference to this, not an instance.
I changed the return type to void already.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 11, 2013, 10:05:38 PM
I get lots of warnings from scr_coord.h line 192. That function should perhaps return void.
I'm complete innocent here, it is a void in my original code.

About the clip function. Maybe call it clip_to and then the parameter clip?rect instead rect. That may make the function more clear.

void clip_to( scr_rect clip_rect ) or void intersect( scr_rect rect ) will do fine.
Intercept is the standard term for this operation and will fit in well if we add the other operations as well.
However if this object would support such operations it is most likely something else than a rectangle and should maybe be another class instead.

So, I guess clip_to() will do.

Anyway I am working on the rest now.
I fell both happiness and anxiety at the same time... I do hope you don't change anything, the system isn't complete yet and it is to early to remove the single Theme list yet.
Title: Re: [Project] GUI Theme
Post by: prissi on October 12, 2013, 07:53:28 PM
Sorry since Friday evening my MSVC was broken. (About some Unicode cahrachter (\uDB4B) in the project file while there was absolutely nothing. After reinstalling and checkout from empty it work again. So no progress since Friday. I will change scr_coord.h immediately.

EDIT: Microsoft really does not won't me working this weekend. While editing file Windows7 did a restart to install patches. Without a warning, not asking for saving, just restart while I was typing. (XP did this about once a year, but I never expected it from Win7). I lost the last two hours. Sorry, will not finish today then.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 12, 2013, 09:54:00 PM
Microsoft really does not won't me working this weekend. While editing file Windows7 did a restart to install patches. Without a warning, not asking for saving, just restart while I was typing. (XP did this about once a year, but I never expected it from Win7). I lost the last two hours. Sorry, will not finish today then.
Really? That never happened to me, are you sure you have turned off automatic updates?
Title: Re: [Project] GUI Theme
Post by: Markohs on October 12, 2013, 11:00:54 PM
You really need to save files more often.  :-)
Title: Re: [Project] GUI Theme
Post by: Markohs on October 12, 2013, 11:01:14 PM
You really need to save files more often.  :-)
Title: Re: [Project] GUI Theme
Post by: IgorEliezer on October 13, 2013, 02:04:25 AM
You really need to save files more often.  :-)
You really need to post the same thing so often? ;)
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on October 13, 2013, 02:32:49 AM
You really need to post the same thing so often? ;)
Jejeje
Title: Re: [Project] GUI Theme
Post by: Markohs on October 13, 2013, 10:13:03 AM
My phone lost wi-fi and accidentally double posted, and I don't know how to delete posts. ;-)
Title: Re: [Project] GUI Theme
Post by: isidoro on October 13, 2013, 09:59:43 PM
You really need to save files more often.  :-)

I'd rather say: "You really need to change your Operating System."   ;)
Title: Re: [Project] GUI Theme
Post by: Markohs on October 13, 2013, 10:33:03 PM
Well, linux doesn't force auto-save of edited files neither, lots of things can happen to a computer, not saving open files for one hour you are calling this happening to you. :)

Anyhow I know Windows 7 does that, you just need to change system updates to require conformation. I agree it should never reboot without asking for conformation.  Linux will do that the sooner or the later, seeing they are just going that direction lately, specially Ubuntu. :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 13, 2013, 10:52:05 PM
Hmmm, maybe we should try to stick to the topic here, no need to rub it... I guess we all have been there...  :police:
Title: Re: [Project] GUI Theme
Post by: prissi on October 13, 2013, 10:56:30 PM
Indeed, let's not get offtopic. I worked through the patch, and I am closer to submit it. Still not finished though.

First some observations
- Convoi dialoges do not display nicely with large buttons
- Factory dialogues do not open with standard size any more (but that may be even better)
- First start will give no visible buttons at all, just plain text. I think a theme shoudl be enforced and missing images not tolerated.
- You assumed a system with lowercase==uppercase. (Incidentally your directory is "Themes".) That will not work anywhere but on windows. But removing to_lower is trivial though.

Some things that probably need more though:
- I am not sure about location and function of "global.tab". If such a thing is required, it should go into the user dir. And then one might think of using simuconf.tab for this. However, I fail to see the advantage of global theme settings, resp. many setting will not work with certain themes (like certain colors).
- The themeselector does apply themes without closing itself. That is not how the other selector work (although I introduced it this way).
- The drawing of color buttons should rather use a mask image which is then blended before the final button is drawn. The rectangle will not work on certain buttons designs (like asymmetric with a colored tab on the left.) So it would need up to 10 images for a fully scaleable button.
- button_t should be a pure virtual function and all buttons should be derived from it. This will automatically force the correct init functions (liek with string or without, with sizes or without, with a position or without). The impact on the construction of dialogues will be rather small; instead definition of one array of buttons more than one with different elements are needed. At that time some of the long action callback functions could be split into more, depending on how much actions they join.
- All theme image under skinverwaltung_t::theme is not needed and does not simplify anything.
- Finally the chopping of images by the Simutrans exe. As stated times before, it always turned out better to give the artist more freedom. Sorry, since you put much effort in decoding and cutting. But I am very deeply convinced that this must belong to the artist, not the program. Also certain asymmetric button designs (or the masked ones) seem difficult to be cut up like this but I have to think on that more. The patch I submit will most likely miss that part (for now). I really want to hear more artist input on that.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 14, 2013, 12:35:06 AM
First some observations
- Convoi dialoges do not display nicely with large buttons
- Factory dialogues do not open with standard size any more (but that may be even better)
Well observed. I wrote that I haven't done anything about the dialogues. This will be the next step...

- First start will give no visible buttons at all, just plain text. I think a theme shoudl be enforced and missing images not tolerated.
I have not yet implemented any fallback at this point. There is an empty validation routine that will take care of this.
For some one who are developing Simutrans, fall backs might seem unnecessarily. If Simutrans won't start we usually know why.
A first time user starting Simutrans, only to find it close immediate, or leave a cryptic error message might think "what a crap program" and never try it again...

- You assumed a system with lowercase==uppercase. (Incidentally your directory is "Themes".) That will not work anywhere but on windows. But removing to_lower is trivial though.
I'm fine with all lower case, I'm only on Window based systems so I'm not used to think about these file name constraints...

Some things that probably need more though:
- I am not sure about location and function of "global.tab". If such a thing is required, it should go into the user dir. And then one might think of using simuconf.tab for this. However, I fail to see the advantage of global theme settings, resp. many setting will not work with certain themes (like certain colors).
The global theme setting is to ensure that you get a certain size of your GUI no matter what. This is important on mobile devices where the GUI needs to be big enough to use. Sure not all themes would look "nice" but at least be operational. I'm sure the user will select a theme he likes and fits his purposes.
It is not that the global.tab by default makes all GUI elements huge in size. It is something intended for users who need it on mobile devices without having to modify every theme before he can select one.

- The themeselector does apply themes without closing itself. That is not how the other selector work (although I introduced it this way).
It should absolutely not close itself for three main reasons.
  1) To easily be able to browse and preview the themes, the dialogue can't be closed in between, it would make it very un-user friendly to select a theme.
  2) If the selected theme for some reason screw things up, you must be able to select another one.
  3) As a Theme designer you can do a change and then easily test it by just press the same theme again in the theme selector to reload it. Other wise he has to go through a series of dialouges before he can reload his modified theme.
You might also have seen that there is a Cancel button if you aren't happy with your choice, it reloads whatever you had before you opened the theme selector.

- The drawing of color buttons should rather use a mask image which is then blended before the final button is drawn. The rectangle will not work on certain buttons designs (like asymmetric with a colored tab on the left.) So it would need up to 10 images for a fully scaleable button.
I know all about it. But it is better than nothing right?
I do have an idea of how to automatically create a mask, use a special colour or simply provide a mask... it is in the pipe...

- button_t should be a pure virtual function and all buttons should be derived from it. This will automatically force the correct init functions (liek with string or without, with sizes or without, with a position or without). The impact on the construction of dialogues will be rather small; instead definition of one array of buttons more than one with different elements are needed. At that time some of the long action callback functions could be split into more, depending on how much actions they join.
- All theme image under skinverwaltung_t::theme is not needed and does not simplify anything.
- Finally the chopping of images by the Simutrans exe. As stated times before, it always turned out better to give the artist more freedom. Sorry, since you put much effort in decoding and cutting. But I am very deeply convinced that this must belong to the artist, not the program. Also certain asymmetric button designs (or the masked ones) seem difficult to be cut up like this but I have to think on that more. The patch I submit will most likely miss that part (for now). I really want to hear more artist input on that.
Prissi, have you read any of my posts at all? Have you read my document? Have you even read the first post in this tread?
I have a vision, a plan and a goal. But I can't implement everything at once because you don't want to big patches. This means you will find things not being fully developed or implemented. I can't just remove stuff without having something replacing it. I also try to submit patches that make as little impact as possible on current system. As long we use the "old" skin format there are some limitations, but it's still an improvement compared to the old skin files.

I will say this again, and hopefully for the last time:

- skinverwaltung_t::theme will be removed, it is not needed as soon the theme manager can load the theme images by itself. It is still used for the convenience of using an already working system instead of a new untested one.

- The gui classes will be redesigned in a more strict hierarchy to reuse code and behaviours. I have not done this yet because at first it will not contribute anything to the end user and meanwhile this reconstructing is done, the code will be quite useless (unless we run parallel systems meanwhile). I thought it was better to first give the end user some more candy before I star to work on this.

- The artist will be able to shop up the images, set text offset, colours, masks etc... but we need a new pak format for this. Meaning new readers and writers, a scanner, tokenizer and a parser.

Do not remove any code, you will take away a lot of the infrastructure I have built to use as a base for coming features. I can't in my wildest imagination think that an artist would oppose the possibility to draw a button in one or two or three cells depending on how he wants it to be cut. If you think that all GUI elements are cut in equal pieces, then you have not understood the code.


All this will be done in the end, but it goes really slow because I can't check in stuff myself. I'm depending on those who can and when they have time for it. If we on top of this also debates about small details, imaginary problems or remove code we "don't like", I also get lesser time to do coding and move the project forward.

I think what I have submitted now, even with a few limitations, are far better than the skin system we had before. The end user only sees what's on screen, not how it is implemented (and probably doesn't care either). The work will continue and next up is to fix the remaining dialogues if there aren't any more urgent things to fix before that. But if you are to remove code because you don't "like it", this project is doomed and I see no point in continuing...

If some one disagree or agree with me please step forward...
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 14, 2013, 12:50:35 PM
Quote
If some one disagree or agree with me please step forward...
Just so you know people are reading what you say - I can't agree or disagree on this. From my own experience I know that developers are reluctant to include code in trunk until there is an actual need for it. Until then it may just seem an unnecessary complication.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 14, 2013, 01:01:42 PM
I prefer allways to go with the simplest design that works, I don't like seeing code that's not used, just because it was pre-designed that way in the hopes of using it later.

 I'd say patches should *never* include code that's not being used, because if you are not using it, you will probably not use it in the future, and when you are going to use it, you prolly designed it in the wrong way.

 The best way of designing is just implement in the go, just implementing what you are going to use, *now*.

 http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it (http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it)
 http://en.wikipedia.org/wiki/KISS_principle (http://en.wikipedia.org/wiki/KISS_principle)

 Including provisioned code just for the future will take to the place you are right now, because now developers are arguing about a design that's not even used. You are on a weak position , trying to defend something without many arguments, just defending "air". And that's not a good position to be. ;)

 My advise is the same I gave you before, program more, implement more, when results are evident, you'll be able to defend your design way better. Even I understand you, Max, and my wild guess is your design makes sense. But you can't prove it. ;)

 Hope to see more of this new code soon! :)
Title: Re: [Project] GUI Theme
Post by: prissi on October 14, 2013, 08:56:14 PM
I put a lot of effort in the GUI system. Even though, I certainly see that there is lot of room for improvement.

Let us go back to your first post:
Quote
Road map

Convert all GUI elements to use the elements defined in frame_t.h instead of all the magic numbers. This may result in additional element definitions.
 1) Set each element size to the size of its skin image.
 2) Create a true window class, gadget bar class and a gadget class
 3) Introduce a true client relation and update all dialogs
 4) Modify/add controls if needed to work better with the concept of resizing
 5) Create a dialog to select and apply a skin (theme).
 6) Add detection and special handling for a small screen area (example portable devices).

1) and 5) is done, 4) is somewhat tackled by this theme manger, which I do not like. But on the basis of this list, the thememanager is not even menitioned.

I think we can agree on many things concerning the GUI: That the current state of buttons is not good, many switch statements were not very OOP. That the dialogues were hardcoded and that elements need to align much more relative to each other. That there are configurable themes and more flexible designs. Even that the window should be maintained by a class and not from the code of a C-file (like simwin.c was) And the artist may not care about how the button is draw, he cares about how much control he would get over appearance. Hew would certainly not mind the freedom of having scalability or not, you are right.

But as long as the dat format is documented, an artist does not call whether he has to write "Image[1]" or "Image[button-pressed]" or whatever, which we probably disagree. But unfourtunately we disagree on a fundamental level. The core of disagreement is here:
Quote
but we need a new pak format for this. Meaning new readers and writers, a scanner, tokenizer and a parser.
It is nice to change everything for the sake of change and challenge. But *why*? Simutrans has a working pak system, everything in the Simutrans universe in the last 10 years or so is built around it. There is *absolutely no need* to break this. It can be achieved quite easily in current format, or you can extend it (like button definitions in 2D image list, with "phase 0" normal, "phase 1" pressed and "phase 2" disabled.

On there very core of this topic: The themeability of Simutrans has made no progress by this patch (dialogues are still visually not compatible with the new sizes). It may be an unfair statement, I agree.

So this is how is stands: I do not like another Hajo sized flamewar on Simutrans. Please accept to reuse the existing infrastructure for what it is worth (you will see this when the patch is submitted). Or we have to agree that I cannot make my ideas compatible with yours on a fundamental level and we have to depart (which I would regret).
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 14, 2013, 11:04:47 PM
But as long as the dat format is documented, an artist does not call whether he has to write "Image[1]" or "Image[button-pressed]" or whatever, which we probably disagree. But unfourtunately we disagree on a fundamental level. The core of disagreement is here:It is nice to change everything for the sake of change and challenge. But *why*? Simutrans has a working pak system, everything in the Simutrans universe in the last 10 years or so is built around it. There is *absolutely no need* to break this. It can be achieved quite easily in current format, or you can extend it (like button definitions in 2D image list, with "phase 0" normal, "phase 1" pressed and "phase 2" disabled.
Well, I have not explained exactly how it would work so you are only speculating and assuming that I will "invent" a complete new pak file format. I'm no expert on writers/readers but what I have seen so far, It looks like each writer class is doing its own scanning and parsing, even its on white space filtering. In the end, this design allows each individual line in a .dat file to have a complete different syntax from another.

If we used a scanner and a tokenizer ALL .dat and .tab files would have the same syntax, you would get something that people recognize and can use in all .dat and .tab file creations. The parser might be specialised for different purposes, but could be shared among the most writers. This would not only give us a homogeneous configuration language, but also syntax checking already at "compilation", not a crash when testing.
The .dat variables that now are hard coded to a child node's index, makes it inflexible. By adding a text node with all variables coded with name and its binary value would make it easy to search for a specific variable, not worry about what index it is located at. This would move the reading up to a more high level so a standard reader could be used and simply just pick the information that is known.

The only new in the PAK file would be the new text node with all named variables. Backward compatibility. The reader can look for the current index based variables and then in the new text node.
To include all the things I want in the theme PAK file, such as element size, behaviours, colours, text offsets etc... The use of a text node is the most flexible because we can then add or remove variables without changing the low level writer or reader.

Further more I have talked about a guard colour (http://forum.simutrans.com/index.php?topic=11956.msg124700#msg124700) that the artist will use to show how the GUI control images should be cut. By using this and have the theme manager to detect these lines we are not only backward compatible with existing skin format but also making use of the current .pak format. See the current images as a transport layer for an extended format, detected and used by the theme manager. What is it that is so bad about this design? The artist get a lot more flexibility and we still use the same old pak format and as a bonus we get a homogeneous syntax for .dat and .tab files. What is it in this you don't like?

If you look closely at how I use the current skin-pak format you will see that it works just as before with even more flexibility.

So this is how is stands: I do not like another Hajo sized flamewar on Simutrans. Please accept to reuse the existing infrastructure for what it is worth (you will see this when the patch is submitted). Or we have to agree that I cannot make my ideas compatible with yours on a fundamental level and we have to depart (which I would regret).
Maybe this is one of the problems, that parts who really needs some design changes isn't "allowed" to change... ???
I have no idea of who Hajo was or is, what kind of quarrels you two had, but maybe he had a great vision and got frustrated because some one kept deleting his code with the argument "this isn't needed" ???

On there very core of this topic: The themeability of Simutrans has made no progress by this patch (dialogues are still visually not compatible with the new sizes). It may be an unfair statement, I agree.
Really... So we have no filter button?, we have no sizeable buttons? we have no disable states? No auto hidden scrollbars? No configurable colours? I have just wasted 400 hours on nothing? Is this what you think of my work?
I was really excited about this patch because I thought I was introducing more eye candy for the user and more flexibility to the artists. The screen shots I posted got really good comments from artists, but I guess we all where wrong... I'm sorry I put so much work into something so "useless".

I'd say patches should *never* include code that's not being used, because if you are not using it, you will probably not use it in the future, and when you are going to use it, you prolly designed it in the wrong way.

Including provisioned code just for the future will take to the place you are right now, because now developers are arguing about a design that's not even used. You are on a weak position , trying to defend something without many arguments, just defending "air". And that's not a good position to be. ;)
The code in question is in use... Code I had commented out in scr_coord.h because it was not used has been enable again, so I really don't get the logic here; enable code not in use and remove code in use...  :o

My advise is the same I gave you before, program more, implement more, when results are evident, you'll be able to defend your design way better. Even I understand you, Max, and my wild guess is your design makes sense. But you can't prove it. ;)
Sure I can do my "thing" and then upload a huuuge patch and you guys will have quite some job to implement it, that isn't really my problem. But I agree that it is best to update small sections at the time. It will make it easier for you and me, but all updates will not necessarily contribute with something magnificent. It just makes it easier for us to keep in synch.

Hope to see more of this new code soon! :)
You would if someone didn't changed my code all the time. I'm not sure I want to do this any more...

If you try to build a house, you have to start with the ground, then the first floor and so on. How can you at the end put up the roof if someone decides that no walls are needed and removes them, because he can't see any roof yet  ???
If the stairway to the second floor isn't finished yet, but there is a temporary ladder in place. Is this an argument to remove the whole second floor?
Title: Re: [Project] GUI Theme
Post by: Ters on October 15, 2013, 05:42:07 AM
If we used a scanner and a tokenizer ALL .dat and .tab files would have the same syntax, you would get something that people recognize and can use in all .dat and .tab file creations. The parser might be specialised for different purposes, but could be shared among the most writers. This would not only give us a homogeneous configuration language, but also syntax checking already at "compilation", not a crash when testing.

dat and tab files already share their syntax.

The .dat variables that now are hard coded to a child node's index, makes it inflexible. By adding a text node with all variables coded with name and its binary value would make it easy to search for a specific variable, not worry about what index it is located at. This would move the reading up to a more high level so a standard reader could be used and simply just pick the information that is known.

I just looked through the dat-files for pak64 and couldn't find many places where indicies are used without it being natural. As far as I can see, the only places with cryptic indicies are building rotations, signals and whatever one should call the indicies for grounds. To a lesser extent also seasons. For grounds, I seem to remember that the indicies for grounds makes perfect sense inside the code. Coming up with meaningful names might be impossible, or the names might be so long that nobody wants to have to write them. Buildings are cryptic to me either way. Seasons work fine as indicies in the pak, but could use symbolic names like normal rotations have.

Signals are the only type I could find where indicies map directly to unstructured pak file indicies. These really should be written with separate direction and state in the dat file. (There is also the electrification issue, but that is a different issue completely.)

Where the indexed nature of pak files really is a bad thing is not when writing dat files, but when the game reads a pak node where a variable number of child nodes have been flattened out into single list. Looking up a particular node then involves a rather complicated index calculation that has to take into account how many preceeding child nodes are present.

If the stairway to the second floor isn't finished yet, but there is a temporary ladder in place. Is this an argument to remove the whole second floor?

I think the argument here is that there isn't even a temporary ladder. There is no way to get to the second floor at all, not even a hole between the floors yet. (Although I haven't myself checked if that's the case.)
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 15, 2013, 06:37:16 AM
I think we are turning cycles in this discussion.

Max-Max, it would be really good if you could split your large patch into smaller pieces. Explain how these pieces fit together and depend on each other. You have put a lot of effort into this patch, which should not be wasted.

Prissi, I hate to say this, please post your modifications before committing modified parts of the patch. If you do not like to work on this patch, then please say so. I can do this as well.

About the pak/dat-stuff: There is already a parser at hand: tabfile_t does the low-level parsing. It creates an array/table with string keys and values. There is room to remove code duplication, I agree, as each writer-class puts generates the keys using string buffers. Changing the skin-writer class to use string keys instead of integers is favorable ofc, but the necessary change can be done on high-level (the writer) without changing low-level stuff (parser / tabfile).
Title: Re: [Project] GUI Theme
Post by: Markohs on October 15, 2013, 07:55:44 AM
The code in question is in use... Code I had commented out in scr_coord.h because it was not used has been enable again, so I really don't get the logic here; enable code not in use and remove code in use...  :o

 My excuses then, I was just commenting based on previous comments in this posts, I didn't actually look into the code.

Sure I can do my "thing" and then upload a huuuge patch and you guys will have quite some job to implement it, that isn't really my problem. But I agree that it is best to update small sections at the time. It will make it easier for you and me, but all updates will not necessarily contribute with something magnificent. It just makes it easier for us to keep in synch.
You would if someone didn't changed my code all the time. I'm not sure I want to do this any more...

If you try to build a house, you have to start with the ground, then the first floor and so on. How can you at the end put up the roof if someone decides that no walls are needed and removes them, because he can't see any roof yet  ???
If the stairway to the second floor isn't finished yet, but there is a temporary ladder in place. Is this an argument to remove the whole second floor?

 I was just speaking in general, and not of any of the details of your implementation, that I don't know enough. If it was for me, I'd just give you green light to incorporate all your code. After all this is a open sourced project, and we use a versioning system so we can allways rollback any changes if they come undesired with time. And we have to accept everyone has different programming styles. If your approach to the isue is proved to be wrong, or partially wrong, we can allways refactor it, or throw it to the trash 100% and start again from scratch.

 What I was trying to point you is my vision of how design should be in my oppinion. And I strongly believe you should not even think about the roof, before you finished the first floor at 100%, experience taught me so. Once you start second floor, you'll prolly need to modify first floor, but just sightly, and if it's a heavy modification, you'll know exactly how you need to modify it, because you have extra information. But of course it's just my personal opinion. :)

 About pak file format, I hate it too, but it's what we have, and it has proven to work quite good. I'd just suggest you to use it, resign to it, and once you are to the point you can't step forward because of the limitations of that format, you'll have a strong point to suggest a change. If you are positive about pak, and start using it, you'll find many good parts of the old system, and maybe you change your oppinion. It's better to know your enemy well. ;)

 When I read about cut colors on the gui element it sounded like a good idea to me, I don't know how did that end.

 I won't comment more on this issue, to not grow the issue more and speak more about this in circles.
Title: Re: [Project] GUI Theme
Post by: prissi on October 15, 2013, 10:18:46 PM
I am nearly done, but have to fix some small errors first. I will publish the patch (based on Max-Max one) hopefully tomorrow evening (currently all children are with fever, so short nights for me). Sorry for the delay.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 15, 2013, 11:10:45 PM
I hope your children get better soon prissi!
Title: Re: [Project] GUI Theme
Post by: prissi on October 16, 2013, 10:49:07 PM
They did not, rather now my throat is sore ...

I did not finish the designs yet, so also I would consider this as a work in progress. I did not finish the standard theme yet, and also not the Windows7 button discussed earlier (even though the infrastructure is mostly in place).

ThemeWorked9.zip contains the patch, themes.zip the new theme paks for the simutrans folder, and aero-src.zip the sources of the theme pak.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 16, 2013, 11:41:34 PM
As you say, it's work in progress so I will not judge you to hard... yet.
By looking at the theme source I noticed you have reinstated "your" version of the theme .dat file and graphic format, I assume you must have thrown out quite a lot of my code and constrained the artist to the old one-and-only way to draw graphics, not my simpler addition to the current format.

I just don't understand why you can't just apply my full patch and have the community to have a look and say what they think before you start to throw away my work. Are you always censoring everyone's code or is it only mine :o (feels like that), I thought this was open source and any one could contribute.

I will stop to write now because I'm quite pissed and will probably say something I will regret later (http://mkdevelopment.se/simutrans/angry.gif)
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 17, 2013, 06:55:29 AM
I feel we are heading full speed into a wall here.

Max-Max, it would REALLY help your case, if you could split your gigantic patch into smaller, easier to review parts. From looking at the patch, you have several different lines of development there: debug output for makeobj, named constants in simskin, alot of theme-stuff-* etc. The patch says nothing about the purpose of these theme-vertical classes.

It is impossible to judge whether some part is not needed, another part reduces code duplication etc. Controversial changes are mixed with helpful ones etc.

Edit: I would like to help, but it is really a lot of work to go through the patch, look for easy-to-include stuff and commit it. You cannot expect that somebody blindly commits large patches in one go. I like these new filter buttons, the introduction of named constants, debug output for makeobj.

Edit2: Your patch is also not that much consistent: It looks like the theme-manager could make use of scr_coord, scr_rect instead of koord and KOORD_VAL?

This evening I will have some free time. If you could split your patch then I could commit the not-so-controversial parts.
Title: Re: [Project] GUI Theme
Post by: prissi on October 17, 2013, 08:50:56 AM
Maybe some more word, since it was quite late yesterday.

The main concerns about your patch was that it did not fit the exiting code.
The changed version above is with a gui_theme_t like env_t. The drawing is all in simgraph, where all the drawing using image interna imho belongs.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 17, 2013, 10:31:49 AM
Quote
I just don't understand why you can't just apply my full patch and have the community to have a look and say what they think before you start to throw away my work.
Because generally code should only go into trunk that will stay in trunk. In this case we are all agreed that themes are a good idea - it's the implementation details that are being disputed.

Quote
Are you always censoring everyone's code or is it only mine
Censor is a strong word - everyone's patches have been reviewed with some parts accepted other parts rejected. I've had patches outright rejected (slope images for vehicles), others that have been heavily modified (initial underground view), and some that have just been incorporated as I wrote them (powerline bridges).
Title: Re: [Project] GUI Theme
Post by: Ters on October 17, 2013, 03:08:04 PM
I have to agree that patches should not be applied to trunk before it has been reviewed. This is especially important for Simutrans, where there is no stable branch, only trunk.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 17, 2013, 03:20:47 PM
Or at least non-trivial patches. Patches which fix a reported bug and only affect a small area of code can be applied straight away I would say.
Title: Re: [Project] GUI Theme
Post by: Ters on October 17, 2013, 03:57:26 PM
Or at least non-trivial patches. Patches which fix a reported bug and only affect a small area of code can be applied straight away I would say.

I agree, I was just in a bit of a hurry at the time and failed to make that distinction.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 17, 2013, 05:13:57 PM
Max-Max, it would REALLY help your case, if you could split your gigantic patch into smaller, easier to review parts.
I did Submitting smaller patches (http://forum.simutrans.com/index.php?topic=11956.msg123455#msg123455) before but somehow no one saw it and it was never reviewed.

To submit small patches might work well if they are just small patches, not complete new development. If I submit new code in small patches, they will be out of context and refused because Prissi don't see any use of them, even if I explain the intention of it.
If I get the opinion "The themeability of Simutrans has made no progress by this patch." (http://"The themeability of Simutrans has made no progress by this patch.") on a patch that added quite a lot of features, then how can I submit small patches?

From looking at the patch, you have several different lines of development there: debug output for makeobj, named constants in simskin, alot of theme-stuff-* etc. The patch says nothing about the purpose of these theme-vertical classes.
I have touched the purpose of these classes in this thread (http://forum.simutrans.com/index.php?topic=11956.msg124700#msg124700). The class is used in the theme manager and if you have understood what the frame, symbol and horizontal class are doing, it can't be to hard to figure out what a vertical class is doing, or?

The vertical class is used when you want to constrain a theme element to only adjust size vertically, like a vertical scrollbar. The theme images are horizontal centred in the client area, but extended vertically from left to right.

It is impossible to judge whether some part is not needed, another part reduces code duplication etc. Controversial changes are mixed with helpful ones etc.
This is exactly my point with submitting work in progress as small patches. I do try to explain what it does in this thread, but because people point out things I have already explained, I can't come to any other conclusion that my post isn't being read or understood.

Edit: I would like to help, but it is really a lot of work to go through the patch, look for easy-to-include stuff and commit it. You cannot expect that somebody blindly commits large patches in one go. I like these new filter buttons, the introduction of named constants, debug output for makeobj.
I would really welcome that more than just one person are reviewing the code. We all have different background and experience. If one person think a solution is bad, doesn't mean it is. There might be 10 others thinking it is a good solution.

Edit2: Your patch is also not that much consistent: It looks like the theme-manager could make use of scr_coord, scr_rect instead of koord and KOORD_VAL?
I do use the new scr_coord.h functions if I know I can do it without complications. The code you refer to has been moved and collected in one place. I didn't change the KOORD_VAL and koord yet because it might have introduced complications and even a larger patch.

This evening I will have some free time. If you could split your patch then I could commit the not-so-controversial parts.
I would love too, but my local trunk is quite out of synch from the HEAD version. Maybe I can break out the makeobj DEBUG update.



Maybe some more word, since it was quite late yesterday.

The main concerns about your patch was that it did not fit the exiting code.
In what way? You are very often vague in your critique. When I comment on it and ask questions I usually don't get an answer. I usually have to guess what you mean and so far I have been not so successful. But I try my best to read your mind, so here I will try again.

Before creating each patch I apply my changes to the server's HEAD revision, compile and test. Then I create the patch from there. The patch should be able to be applied to the HEAD revision without any conflicts at all.

...and here are some more cryptic comments.
The changed version above is with a gui_theme_t like env_t.
What do you mean by this? I have not moved anything from env_t into gui_theme_t...

The drawing is all in simgraph, where all the drawing using image interna imho belongs.
This is again an example of a comment that makes me believe that you don't understand how the code works. The theme manager isn't doing any drawing, it is calling the low level functions in simgraph for drawing.

Simgraph, as I understand it, is where we keep the drawing interface, the low level pixel routines that will be implemented differently depending on the target system. To put everything that has even a remotely connection to drawing means that even if it is a high level drawing function, it needs to be maintained for each target implementation.

some of us, in the community, has expressed the need for a canvas. This would also make better use of the drawing routines. I expressed in one of my posts (http://forum.simutrans.com/index.php?topic=11956.msg125568#msg125568) that the theme manager has a good candidate for this in it's raw_bitmap_t. I also put in a comment in the code that this might be better of as a separate class.

Regarding to your own logic, it doesn't make sense to break out code, used privately by one class, into an already very large C structural module. I thought we where going to more OOP, not more structural C.

Now, the theme elements are using the display_image routines it is only the preparation of the theme images that is done internally because there is no way to use the display_image routines on something else than the screen. This is why I brought up the canvas concept earlier...



Because generally code should only go into trunk that will stay in trunk. In this case we are all agreed that themes are a good idea - it's the implementation details that are being disputed.
I find this strange because you guys can submit code that breaks functionality, unreviewed and uncriticized. While my code can be refused for the wrong formatting of spaces and tabs. It seems like there is one set of rules for you guys and a much stricter, non forgiving set of rules for every one else.

Censor is a strong word - everyone's patches have been reviewed with some parts accepted other parts rejected. I've had patches outright rejected (slope images for vehicles), others that have been heavily modified (initial underground view), and some that have just been incorporated as I wrote them (powerline bridges).
But it is what it is. Ideas and solution that isn't in line with what one single person agree on, is just taken out or rewritten, without first consulting the author or discuss it. How can this not be censorship?
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 17, 2013, 06:12:26 PM
Here is a quick review of your patch. As you see you cannot expect anybody to just take it and commit.
-- macros.h: these changes should go into related gui and simstring headers
-- simhalt.cc, koord.h: non-sensical changes
-- simsys.h, translator.h: we are using chdir not _chdir
-- simwerkz-dialogs.h: one line commented out - the dialog is broken ?
-- bild_besch.h why add all the (void) parameter lists
-- skin_writer.cc: I doubt that it would work correct if some images are not defined in the dat
-- scr_coord.h: what is purpose of the typedef tag_size {} size; construct ?
-- new files are doubled in the patch

This patch contains the following subpatches (beside the gui and theme stuff)
-- new resource and icon file
-- different debug output for makeobj
-- use ltrim for image keys
-- comments in bild_besch.h

It does not apply on trunk anymore.

Edit: It does not even compile with r6781, which is the revision the patch seems to be taken against.
Code: [Select]
In file included from gui/loadsave_frame.h:12:0,
                 from gui/banner.cc:22:
gui/savegame_frame.h:41:19: error: '_MAX_PATH' was not declared in this scope
gui/savegame_frame.h:42:25: error: '_MAX_PATH' was not declared in this scope
gui/savegame_frame.h: In constructor 'savegame_frame_t::dir_entry_t::dir_entry_t(button_t*, button_t*, gui_label_t*, savegame_frame_t::dirlist_item_t, const char*)':
gui/savegame_frame.h:78:19: warning: 'savegame_frame_t::dir_entry_t::button' will be initialized after [-Wreorder]
gui/savegame_frame.h:77:19: warning:   'button_t* savegame_frame_t::dir_entry_t::del' [-Wreorder]
gui/savegame_frame.h:69:3: warning:   when initialized here [-Wreorder]
gui/savegame_frame.h: At global scope:
gui/savegame_frame.h:109:15: warning: unused parameter 'fullpath' [-Wunused-parameter]
gui/savegame_frame.h:111:15: warning: unused parameter 'fullpath' [-Wunused-parameter]
Now guess who is pissed as well :(
Title: Re: [Project] GUI Theme
Post by: Markohs on October 17, 2013, 07:07:41 PM
I'm having it a look too, to the ThemeWorked.zip

I don't know who typed this, if Max-Max of prissi, but I see no point in:

* why adding (void) to functions without parameters? I don't see the point.
* macros.h adds a lot of empty lines for no reason too.

 Well, appart from that, that's minor things that well, should just be fixed, I don't see much problems, but I wonder why there are so many uppercase macros in new code:

Code: [Select]
            image_id const img = sel-- != 0 ? button_t::pos_button_normal : button_t::pos_button_pushed;
            display_color_img(img, offset.x + 2, offset.y, 0, false, true);

To:


Code: [Select]
            display_img_aligned( skinverwaltung_t::posbutton->get_bild_nr(SKIN_BUTTON_POS + (sel == 0) ), scr_rect( offset.x, offset.y, 14, LINESPACE ), ALIGN_CENTER_V | ALIGN_CENTER_H, true );

 New code should be easier to read, and it's not.

 But well, the patch is too big for me to figure if there is something wrong.
Title: Re: [Project] GUI Theme
Post by: prissi on October 17, 2013, 07:46:32 PM
The uppercase marcros are for once toget rid of #if MULTI_THREAD #else. The functions coudl be shorter if gui_theme_t remberes all the images. I can easily add this.

I think there is some time needed to cool this off. I will take a short time out (especially since my cold got worse).  I have also still to go over the final patch, as it was rather a quick work in progress. I would like to implement also the 3x3 image buttons (which I think is a very good idea of Max-Max) and woudl certainly answer to your comments.

But how to proceed now:

- If there are no objections, I would like to submit the cleaned up scrollbar.cc since the one in trunk is really confusing and lots of compatibility code from the time it was even a C-file. I think this is rather independent of any patch.

- During the work I saw that some dialogue use roundbuttons, but declared them as buttons. That was not so obvious until the themes (and especially since now both buttons are skinable), but needs to be fixed. I will do this on trunk, it need to be fixed regardless of how the theme manager is implemented.

- Furthermore, apart for the implementation of the theme manager, most changes from Max-Max are in both patches and, when concerning dialogues, are not really very controversial. If ok, I can commit them, so the decision is left between the way the images for the theme manager are loaded (and also much smaller patches to look at).
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 17, 2013, 07:52:26 PM
Quote
If I get the opinion "The themeability of Simutrans has made no progress by this patch." on a patch that added quite a lot of features, then how can I submit small patches?
I actually understand where you are coming from with regards to this. With the updated landscapes I ended up having to submit a huge patch in the end for this reason. Small patches are more likely to work there way into trunk (because they are quicker to check) but as you say - not much point doing this if you need a large patch to introduce something useful.

Quote
I would love too, but my local trunk is quite out of synch from the HEAD version. Maybe I can break out the makeobj DEBUG update.
If you are submitting patches you need to ensure your local trunk is kept up to date. Yes this is a pain, however it is necessary - otherwise people reviewing the patch will have great difficulty doing so.

Quote
I find this strange because you guys can submit code that breaks functionality, unreviewed and uncriticized. While my code can be refused for the wrong formatting of spaces and tabs. It seems like there is one set of rules for you guys and a much stricter, non forgiving set of rules for every one else.
Firstly we are all human - we make mistakes from time to time. Sometimes someone will have tested a patch extensively on Linux only for it to break on Windows (or vice versa). Sometimes we submit patches quickly - if there's a known bug and there is a simple fix it would be silly to have to wait for code to be reviewed. However when we are adding a major feature then it is discussed first and reviewed by other people. Themes are clearly a major feature - one that I support being introduced and it's good that through discussion here the best overall solution will be incorporated into trunk. What I'm not going to do is take sides on your preferred implementation vs prissi's.



Overall I'll repeat comments I made earlier - if you've got an idea then write the code. By all means share code along the way but make sure it does something that adds real functionality to simutrans before requesting it get added to trunk. That way if you decide to make huge disruptive changes at least people will understand there is a need for these.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 18, 2013, 02:49:15 AM
Here is a quick review of your patch. As you see you cannot expect anybody to just take it and commit.

-- macros.h: these changes should go into related gui and simstring headers
I guess you are refering to to D_GET_CENTER_ALIGN_OFFSET(), D_GETFAR_ALIGN_OFFSET and GET_THEME_PICTURE.
Well they are all macros and the file is called macro.h no comments of what to expect in it. If you don't want people to put macros in a file called macro.h you have to put in some information about it. I can agree that GET_THEME_PICTURE shouldn't be there and I did move it after the patch was submitted.

I really had no clue of where to put these std::string functions, because it isn't a part of the simstring functions only dealing with char*. In this post (http://forum.simutrans.com/index.php?topic=11956.msg125568#msg125568) I was raising the question of where to place them.

But at this point it seems a bit odd to put them in macro.h, I'm more than willing to admit this. But where would I but std::string related functions?

-- simhalt.cc, koord.h: non-sensical changes
What specific are you referring too?

-- simsys.h, translator.h: we are using chdir not _chdir
Check this information (http://msdn.microsoft.com/en-us/library/ms235420(v=vs.90).aspx).
First I used _chdir() and then changed it back to chdir() because I was convinced that it would only give more fire to the refusal discussions and I was right. I must honestly have missed a place...

-- simwerkz-dialogs.h: one line commented out - the dialog is broken ?
No the dialogue works fine, but at the time I was debugging and suspected I had two instances of the same dialogue.
When I look back at it now I realize this is to fire the dialogue from the toolbar. A simple comments in the beginning of the file would have made things easier to understand for someone new to the code.
This is what code review is all about :thumbsup:

-- bild_besch.h why add all the (void) parameter lists
A common misconception for C programmers, is to assume that a function prototyped as follows takes no arguments:
int foo();
In fact, this function is deemed to take an unknown number of arguments. Using the keyword void within the brackets is the correct way to tell the compiler that the function takes NO arguments.

Google it or check a few links.
Is there a difference between foo(void) and foo() in C++ or C (http://stackoverflow.com/questions/51032/is-there-a-difference-between-foovoid-and-foo-in-c-or-c/51044#51044)
int foo (int argc, …) vs int foo() vs int foo(void) in C (http://stackoverflow.com/questions/9784467/int-foo-int-argc-vs-int-foo-vs-int-foovoid-in-c)

I learned to always use foo(void) over foo(), unless you really need to have different implementations of foo with different arguments. foo(void) makes it absolutely clear, 100% that there will not be any parameters what so ever. So I have the habit of filling in the void when I see an foo(). I didn't know this would be a problem worth mentioning to refuse a patch...

-- skin_writer.cc: I doubt that it would work correct if some images are not defined in the dat
Ahh, you are right. My intention was to have makeobj to automatically fill in empty nodes for the first 100 indexes. But then I made the DEBUG switch so we can see what goes wrong instead of guessing if we miss to define empty image indexes. I forgot to restore it.
Again, this is what code review is about :thumbsup:

-- scr_coord.h: what is purpose of the typedef tag_size {} size; construct ?
Have you tried to declare a struct referencing itself? The use of tag_ concept is a well known solution to this very problem.
A struct is exactly same thing as a class with all members public but by tradition structs are used for type-like "classes".
The use of typedef struct tag_size allows us to define a constructor to the yet not defined type. The main advantage of a constructor in a struct is to initialize it. For some reason Prissi don't like that a struct or class initialises itself at creation, hence his concept of invalidate the type, which introduces more problems than it solves. It indicates that the type in deed can be invalid and ther fore should be checked every time before use.

I have no problem with making this to a class as long all members are public, as I mentioned in an earlier post (http://forum.simutrans.com/index.php?topic=11956.msg125575#msg125575).

-- new files are doubled in the patch
I only used TortoiseSVN menu option "Create patch...". If code has been duplicated I have no idea why...

Quote
This patch contains the following subpatches (beside the gui and theme stuff)
-- new resource and icon file
-- different debug output for makeobj
-- use ltrim for image keys
-- comments in bild_besch.h
I submitted the icon patch (http://forum.simutrans.com/index.php?topic=12557.msg125549#msg125549) earlier and then again (http://forum.simutrans.com/index.php?topic=11956.msg125551#msg125551) together with the original patch[/url].
Well, maybe but when developing, things goes in parallel. It's not like I pick to do one of those thing one after another. I probably could have created some of it in individual patches, but I'm not sure how isolated these things can be done as patches when it is already implemented. If I had tried to break it up and something goes wrong, we would have all this discussion again that it's **** and shouldn't have been submitted at all.

Quote
It does not apply on trunk anymore.
This is probably because it has gone quite some time now since I posted the patch. I have no control over how fast it is implemented into the trunk, so you can't really blame me for it.

Quote
Edit: It does not even compile with r6781, which is the revision the patch seems to be taken against.
Code: [Select]
In file included from gui/loadsave_frame.h:12:0,
                 from gui/banner.cc:22:
gui/savegame_frame.h:41:19: error: '_MAX_PATH' was not declared in this scope
gui/savegame_frame.h:42:25: error: '_MAX_PATH' was not declared in this scope
gui/savegame_frame.h: In constructor 'savegame_frame_t::dir_entry_t::dir_entry_t(button_t*, button_t*, gui_label_t*, savegame_frame_t::dirlist_item_t, const char*)':
gui/savegame_frame.h:78:19: warning: 'savegame_frame_t::dir_entry_t::button' will be initialized after [-Wreorder]
gui/savegame_frame.h:77:19: warning:   'button_t* savegame_frame_t::dir_entry_t::del' [-Wreorder]
gui/savegame_frame.h:69:3: warning:   when initialized here [-Wreorder]
gui/savegame_frame.h: At global scope:
gui/savegame_frame.h:109:15: warning: unused parameter 'fullpath' [-Wunused-parameter]
gui/savegame_frame.h:111:15: warning: unused parameter 'fullpath' [-Wunused-parameter]
I reverted to rev 6781, downloaded and dropped in the patch I posted. No problems at all applying the patch. Compiled, no errors...
I seriously hope you don't think I submit code that doesn't compile in my end?

On MSDN we can read (http://msdn.microsoft.com/en-us/library/vstudio/930f87yf(v=vs.120).aspx).
"The C Runtime supports path lengths up to 32768 characters in length, but it is up to the operating system, specifically the file system, to support these longer paths. The sum of the fields should not exceed _MAX_PATH for full backwards compatibility with FAT32 file systems. Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003, Windows Server 2003, and Windows Vista NTFS file system supports paths up to 32768 characters in length, but only when using the Unicode APIs. When using long path names, prefix the path with the characters \\?\ and use the Unicode versions of the C Runtime functions."

Maybe this is a Microsoft thing? If this doesn't work on Linux, we need a way of defining the MAX_PATH and MAX_FILENAME that works for both windows, mac, linux and unicode.

Quote
Now guess who is pissed as well :(
For what?
It is my work that has been dissected, rewritten, called ugly, useless, pointless, unnecessary, confusing. It is I who has repeated the same information over and over again and still it doesn't seems like no one is reading it. Unless you are upset about this too, but I doubt you are ;)

-------------------------

I'm having it a look too, to the ThemeWorked.zip
This is Prissi's rewrite of my original code. My original patch can be found here (http://forum.simutrans.com/index.php?topic=11956.msg125551#msg125551).

I don't know who typed this, if Max-Max of prissi, but I see no point in:

* why adding (void) to functions without parameters? I don't see the point.
* macros.h adds a lot of empty lines for no reason too.
See my answer above about the foo(void) vs foo().
The extra empty lines are present in Prissi's patch, not mine.

Well, appart from that, that's minor things that well, should just be fixed, I don't see much problems, but I wonder why there are so many uppercase macros in new code:

Code: [Select]
            image_id const img = sel-- != 0 ? button_t::pos_button_normal : button_t::pos_button_pushed;
            display_color_img(img, offset.x + 2, offset.y, 0, false, true);

To:


Code: [Select]
            display_img_aligned( skinverwaltung_t::posbutton->get_bild_nr(SKIN_BUTTON_POS + (sel == 0) ), scr_rect( offset.x, offset.y, 14, LINESPACE ), ALIGN_CENTER_V | ALIGN_CENTER_H, true );
This is again Prissi's rewritten version of my code. display_img_aligned() isn't coming from my patch at all.
When it comes to capital names, I was again told  (http://forum.simutrans.com/index.php?topic=11956.msg118390#msg118390)my code was "dead ugly" when enums wasn't all in capitals.

New code should be easier to read, and it's not.
But well, the patch is too big for me to figure if there is something wrong.
I agree and this is a very subjective definition of what is readable code? But from the patch name you stated, I can only assume you have been looking into Prissi's version of my original code.

-------------------------

The uppercase marcros are for once toget rid of #if MULTI_THREAD #else. The functions coudl be shorter if gui_theme_t remberes all the images. I can easily add this.
Prissi, if you want to be an active part in developing this, we have to work together. We can't start to implement things in different directions just because you don't like my Object Oriented approach. I'm working towards a goal and if you keep changing my structure all the time and add stuff that interfere with what I'm developing it will be nothing of this.

The reason why the theme manager is adding all the images to the global image list is because the display_xxx routines can't work with anything else. I first had this code in the theme_element_t to directly draw the images to the screen, but I was told to use the structure we already have. My goal is to remove this dependency, but it is to early to start messing around with it.

I think there is some time needed to cool this off. I will take a short time out (especially since my cold got worse).  I have also still to go over the final patch, as it was rather a quick work in progress. I would like to implement also the 3x3 image buttons (which I think is a very good idea of Max-Max) and woudl certainly answer to your comments.
...and why can't you just implement the theme manager, theme_elements as they are? Why do you have to rewrite this code from an object oriented design to more or less structural C design? Why is it so hard for you to accept an object oriented design?

But how to proceed now:

- If there are no objections, I would like to submit the cleaned up scrollbar.cc since the one in trunk is really confusing and lots of compatibility code from the time it was even a C-file. I think this is rather independent of any patch.

- During the work I saw that some dialogue use roundbuttons, but declared them as buttons. That was not so obvious until the themes (and especially since now both buttons are skinable), but needs to be fixed. I will do this on trunk, it need to be fixed regardless of how the theme manager is implemented.

- Furthermore, apart for the implementation of the theme manager, most changes from Max-Max are in both patches and, when concerning dialogues, are not really very controversial. If ok, I can commit them, so the decision is left between the way the images for the theme manager are loaded (and also much smaller patches to look at).
I have repeatedly times explained both that this is work in progress, it is to early to change the way images are loaded. I also have the feeling that you will do this your way without discussing it, and if we where, my planned implementation will not be respected anyway.

If you want to help me it is fine, but please ask me first what you can do. Please respect that I'm using a more object oriented approach to this, that I have a vision and a goal I'm working towards.

It is like building a house and when the basement is done, some one comes and builds a parking lot over it so then I have to redesign the whole house again, and again, and again...

-------------------------

I actually understand where you are coming from with regards to this. With the updated landscapes I ended up having to submit a huge patch in the end for this reason. Small patches are more likely to work there way into trunk (because they are quicker to check) but as you say - not much point doing this if you need a large patch to introduce something useful.
Exactly my point. I have been trying to tell every one this from the very beginning.

If you are submitting patches you need to ensure your local trunk is kept up to date. Yes this is a pain, however it is necessary - otherwise people reviewing the patch will have great difficulty doing so.
My patches are in synch, compiled and tested with the HEAD revision when I submit them. Then depending on how much Prissi rewrites it, I get a true hell when it is in the trunk because TortoiseSVN get confused when code marked as new already exists in a different form.

Firstly we are all human - we make mistakes from time to time. Sometimes someone will have tested a patch extensively on Linux only for it to break on Windows (or vice versa). Sometimes we submit patches quickly - if there's a known bug and there is a simple fix it would be silly to have to wait for code to be reviewed. However when we are adding a major feature then it is discussed first and reviewed by other people. Themes are clearly a major feature - one that I support being introduced and it's good that through discussion here the best overall solution will be incorporated into trunk.
I have no problem with this procedure, but as it is now, Prissi rewrites my code without so much as asking what it does and what the intention is.

What I'm not going to do is take sides on your preferred implementation vs prissi's.
You don't need to take a "side", you can have your own opinion on what approach you think is a good one. You can comment on pros and cons, no need to take a "side".

Overall I'll repeat comments I made earlier - if you've got an idea then write the code. By all means share code along the way but make sure it does something that adds real functionality to simutrans before requesting it get added to trunk. That way if you decide to make huge disruptive changes at least people will understand there is a need for these.
I guess I have fundamentally misunderstood how the trunk is supposed to be used. I have seen code go in that doesn't work or is still in progress. I made the assumption that I could commit parts of my code that was still in development.

The very problem is that it is impossible to commit small patches that does something. This is new development and there are many pieces that works together. I can't simply submit a patch with a full theme system AND make it small.

I get double messages, make smaller patches, you need to include more into the patch so we understand the context. It doesn't matter what I do, I will get **** for it in the end no matter what I do.


-------------------------

I know I sound very pessimistic, but I wasn't when I started this. I became very defensive and pessimistic when all my hard work isn't respected and instead of asking and let me explain how things are planned, code is just discredited and rewritten. As soon I realized that Prissi already was rewriting it to something else, I lost interest... What is the point when everything I do is discredited, rewritten and not respecting that I happen to have a more object oriented implementation in mind. When my work in progress isn't seen as work in progress, but as unnecessary code not doing anything useful.
When I give the artists more options to work with, I get to here the opposite, that I put in constrains and the artists has less freedom. Things about how my implementation works that isn't true.

Maybe I should just go underground as so many other developers had done before me (I wonder why) and develop this in silence...
Title: Re: [Project] GUI Theme
Post by: Ters on October 18, 2013, 05:33:50 AM
Some general advice, as Max-Max is not the only one to do some of the things pointed out as problematic with his patch:
  • When working on several unrelated things, use different working directories to keep changes for each separate. An alternate solution for when one needs to do a small change, like a bug fix, and only a working directory full of changes is available, is to shelve all changes (in a patch or whatever fancy functionality may be available for this), revert, do the fix, commit and then unselve again. Shelving in a patch won't work if the change involves moving files, or so it seems someone here found out regarding translation patches.
  • Always look through the diff before submitting something, whether it is by committing directly to VCS or by posting a patch. It's not foolproof, but I sometimes find lingering debug things and unrelated changes that way.
  • Patches should preferrably be small and contain only a specific feature. Sometimes, changesets are big no matter what, and I can also see how big patches are needed in order for reviewers to see the big picture. (This also applies to changesets committed directly to VCS, although I am a bit guilty of letting some sometimes unrelated code cleanup free ride on other changesets. My excuse is that it avoids extra CI builds, which can take quite some time at work.)
Title: Re: [Project] GUI Theme
Post by: Sarlock on October 18, 2013, 06:49:31 AM
I'm going to chime in here as a non-coder and state a few observations.

First, I don't think anyone is intending to discredit your hard work, Max.  You've done some fabulous work here and I think everyone appreciates the effort that you have done and what you have accomplished.

With an open source project that is run by volunteers, we're at the mercy of everyone's ability to donate their time to the game.  We should be very appreciative of everyone's time with this and every other patch: the time that you have put in to coding it and the time that Prissi and others have put in to reviewing the code, making suggestions and modifications and attempting to incorporate it in to the main program.  We also have jobs and families to take care of.  Everyone is doing the best they can.

I am going to note something very important: Prissi and others have been around Simutrans A LONG TIME (I've been here a year now and I'm still a neophyte).  They know this code better than anyone else and they have had a lot of experience with things that have caused a lot of trouble and headaches in the future when the original authors have long gone and left the project.  I would defer to them and trust that they are making the right decision for the project.  You may not 100% agree with them, and you probably never will because everyone has their own opinion, but they have done a very wonderful job up to this point so obviously they must know a thing or two about what they're doing.  I'm sure right now their #1 concern (and mine, too) is that you're going to burn out and disappear and they will be left having to maintain your code for many years in to the future.  I think your priority should be to reassure them that that isn't the case.  You certainly can't blame them for wanting to carefully review the code and restructure it in a way that is familiar to them and in a way that will affect other areas of the code as little as possible.  Trust their experience in this area.

What finally reaches Simutrans may not be exactly what you wrote or even 50% but the hard work that you've done is certainly appreciated and will make the game a better place.  That's the nature of this kind of project: we throw things at the wall and see what sticks and what falls off.  If some or all of it falls off, we just shrug our shoulders and move on to the next job.  I can certainly get your defensiveness, but you come across as combative and it's very unlikely that this will benefit the game or community much.

As a side note, long posts where you reply to multiple quotes from other people is the #1 way to start flame wars.  And we don't want that here... let's be progressive and cooperative.  It's far more beneficial and much less stress for everyone involved.

-You wrote a great addition to the game
-Prissi and others have devoted considerable time to reviewing and modifying it when they would most certainly prefer to work on their own projects
-Whatever makes it in to the code will be a benefit to everyone: don't worry about how it is implemented or to what degree or what gets changed - trust that Prissi and the others have the best interests of Simutrans at heart (because they do, the many years have proven this)
-Smile, this is supposed to be fun.  This isn't that important.  Keep coding.  Work positively with any and all changes.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 18, 2013, 11:47:36 AM
When working on several unrelated things, use different working directories to keep changes for each separate. An alternate solution for when one needs to do a small change, like a bug fix, and only a working directory full of changes is available, is to shelve all changes (in a patch or whatever fancy functionality may be available for this), revert, do the fix, commit and then unselve again.
Just a note when I'm working on larger patches, and fix an unrelated bug report I try to remember to only commit the files associated with the bug report itself, eg:
Code: [Select]
svn commit -m "FIX: bug" simworld.cc

-You wrote a great addition to the game
-Prissi and others have devoted considerable time to reviewing and modifying it when they would most certainly prefer to work on their own projects
-Whatever makes it in to the code will be a benefit to everyone: don't worry about how it is implemented or to what degree or what gets changed - trust that Prissi and the others have the best interests of Simutrans at heart (because they do, the many years have proven this)
-Smile, this is supposed to be fun.  This isn't that important.  Keep coding.  Work positively with any and all changes.
I second this (and the rest of what you wrote Sarlock) :)
Title: Re: [Project] GUI Theme
Post by: prissi on October 18, 2013, 07:41:10 PM
-Smile, this is supposed to be fun.  This isn't that important.  Keep coding.  Work positively with any and all changes.
Yes, this is the core why we all work on it.

I tried to keep as much from Max-Max as I could. I did not completely review my patch then, so spaces and some header changes are unneccessary. I freely admid that.

Max-max patch did not compile on unix (and most likely also not on Mac OS) and would also not work (do to using tolower on paths). Instead chdir() and MAX_PATH will work in simutrans. (Actually chdir() is Posix, so it will work on any Posix system.)

We made Simutrans quite portable over more than seven different architectures (DOS, Windows, Unix, Mac OS (Power PC and Intel), Beos/Zeta, (PowerPC)Amiga OS) So the infrastructure is there, MAX_PATH is available. (But with the prevailance of Windows this is quite understandable.)

I certainly will explain again, why I do not like to introduce a new way of image handling instead reusing the skin_besch_t. The main reason is consistency. You have only one kind of system of how images are handling. This is easy to document, to follow, to maintain, and consistent to use (even though it might not the simplest of all solutions). For the same reason the gui_theme_t works like the existing env_t. If you understood the one in Simutrans you can guess the working of the other. Same reasons, less different systems, less to remember. The latter is of outmost importance which such a large project.

About an OOP approach: Fine, but why those _tag stuff? If you want a structure with functions, then make it a class (because it is an object). You are using also an vector with function objects to draw stuff using predefined index. I can do this is C too, so it is also not very OOP, at least in my eyes. Assuming that OOP does not mean very non-linear code.

In the end we are discussing how to draw buttons and scrollbars only(!) while most of the real work is left untouched.
Title: Re: [Project] GUI Theme
Post by: Ters on October 18, 2013, 09:31:25 PM
I finally got time to look at the technical stuff.

-- bild_besch.h why add all the (void) parameter lists
A common misconception for C programmers, is to assume that a function prototyped as follows takes no arguments:
int foo();
In fact, this function is deemed to take an unknown number of arguments. Using the keyword void within the brackets is the correct way to tell the compiler that the function takes NO arguments.

Google it or check a few links.
Is there a difference between foo(void) and foo() in C++ or C (http://stackoverflow.com/questions/51032/is-there-a-difference-between-foovoid-and-foo-in-c-or-c/51044#51044)
int foo (int argc, …) vs int foo() vs int foo(void) in C (http://stackoverflow.com/questions/9784467/int-foo-int-argc-vs-int-foo-vs-int-foovoid-in-c)

I learned to always use foo(void) over foo(), unless you really need to have different implementations of foo with different arguments. foo(void) makes it absolutely clear, 100% that there will not be any parameters what so ever. So I have the habit of filling in the void when I see an foo(). I didn't know this would be a problem worth mentioning to refuse a patch...

I'm a bit surprised that after much complaining that Simutrans isn't C++ enough, that someone actually changes function signatures from C++ style to C style. But habits die hard. People still use #include <stdlib.h> and NULL in C++ even though #include <cstdlib> and 0 is the "correct".

-- scr_coord.h: what is purpose of the typedef tag_size {} size; construct ?
Have you tried to declare a struct referencing itself? The use of tag_ concept is a well known solution to this very problem.

I just tried. It works fine without typedef. Having to typedef structs, and naming the struct itself (the tag_ part) for self-referencing structs, is a C thing. In C++ class and struct is exactly the same thing, except that the default access specifier is private and public, respectively. (The GNU standard C++ library actually uses struct many places where I found have found class more natural. I seem to remember they almostly used struct earlier, but it's mostly class now.)
Title: Re: [Project] GUI Theme
Post by: Markohs on October 18, 2013, 09:39:18 PM
I'd forget and consider against simutrans coding standards function(void), seems unnatural to me, and we use just function() in the whole code, makes no sense adding yet another way to do it.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 18, 2013, 10:54:34 PM
I'd forget and consider against simutrans coding standards function(void), seems unnatural to me, and we use just function() in the whole code, makes no sense adding yet another way to do it.
I'd actually never noticed simutrans missing void from function declarations before. I also notice the simutrans coding style document doesn't make any mention about this - however as you point out function() is used mostly. While like Max-Max I always thought that it was preferable to write function(void) as Simutrans uses function() in preference I don't see changing this as being particularly useful.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 18, 2013, 11:43:04 PM
I'd prefer just using the non-void version and replace all the void occurrences by empty parameter list. Why having two variants in code when we can have just one, and as Max-Max pointed out, C++ suggest us to use a empty parameter list, why going against this recommendation.

So, if noone has anything against this, I'll just apply https://dl.dropboxusercontent.com/u/30024783/void.patch tomorrow and we finish that particular issue forever.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 05:10:08 AM
Max-max patch did not compile on unix (and most likely also not on Mac OS) and would also not work (do to using tolower on paths). Instead chdir() and MAX_PATH will work in simutrans. (Actually chdir() is Posix, so it will work on any Posix system.)

We made Simutrans quite portable over more than seven different architectures (DOS, Windows, Unix, Mac OS (Power PC and Intel), Beos/Zeta, (PowerPC)Amiga OS) So the infrastructure is there, MAX_PATH is available. (But with the prevailance of Windows this is quite understandable.)
Yes, I don't have the possibility to test this on any other system than Windows, so I really appreciate the help here to check this on other platforms.

I certainly will explain again, why I do not like to introduce a new way of image handling instead reusing the skin_besch_t. The main reason is consistency. You have only one kind of system of how images are handling. This is easy to document, to follow, to maintain, and consistent to use (even though it might not the simplest of all solutions). For the same reason the gui_theme_t works like the existing env_t. If you understood the one in Simutrans you can guess the working of the other. Same reasons, less different systems, less to remember. The latter is of outmost importance which such a large project.
The information in skin_besch_t is redundant and only used to pick the skin image number. The theme manager creates an internal structure with additional information for quick access, by using the already implemented bild_t and the global images[] list. In this way the standard display_img_XXX routines can be used to draw them. As I have said all the time skinverwaltung_t::theme is only used to read the PAK file and register the theme elements. This could be done directly by the theme manager or skinverwaltung_t::theme can be destroyed after registration. Nothing else is using skinverwaltung_t::theme because all the images as been registered and recorded by the theme manager.

About an OOP approach: Fine, but why those _tag stuff? If you want a structure with functions, then make it a class (because it is an object).
I have explained several times why I made those as structs and why the tag_ is used. I also have said, fine, use a class but make it all public because it is meant to be a light weight type with some helper functions. There are also pros and cons to use a class or a struct for this. But sure, class is fine by me if it helps to understand the code better...

You are using also an vector with function objects to draw stuff using predefined index. I can do this is C too, so it is also not very OOP, at least in my eyes. Assuming that OOP does not mean very non-linear code.
I think you have missed out the most important design part here. theme_element_t is an ADT (http://www.daniweb.com/software-development/cpp/threads/350108/what-exactly-is-abstract-data-type-or-adt), it's a base class with a pure virtual interface and can't be instanced by itself. The real implementation is in frame_element_t, horizontal_element_t, vertical_element_t and symbol_element_t. These derived classes are coded to follow different rules regarding how a theme element behave to size changes. For the moment each GUI element has this class hard coded, but in the end the artist can chose what rule to apply to each GUI theme element.
For example: The round button.
Now the round button is hard coded to be the frame type, extending the edges in both horizontal and vertical directions.

register_frame ( THEME_ID_BUTTON_UP, SKIN_BUTTON_SIDE_LEFT, SKIN_BUTTON_BODY, SKIN_BUTTON_SIDE_RIGHT );

But what if the button isn't suitable for vertical size changes? Here the artist will be able to say that the button is of horizontal type, only allowing it to extend horizontally.

register_horizontal ( THEME_ID_BUTTON_UP, SKIN_BUTTON_SIDE_LEFT, SKIN_BUTTON_BODY, SKIN_BUTTON_SIDE_RIGHT );

In the registration process a class factory pattern creates the correct derivation of theme_element_t (frame, hoeizontal, vertical etc...) and puts it in a vector list holding pointers of the base class type. In this way all the different types of derivatives can be held in the same list.

Code: [Select]
bool theme_manager_t::register_frame( theme_element_id theme_id, image_id left_id, image_id middle_id, image_id right_id )
{
theme_frame_t *element = new theme_frame_t; // <---------------- Create correct class for a frame behaviour
bool ret;

// delete any previous definition
if (elements[theme_id] != NULL) {
delete elements[theme_id];
}

remove_offset(left_id);
remove_offset(middle_id);
remove_offset(right_id);
if ( false  ==  (ret = element->init(left_id, middle_id, right_id)) ) { // <------ Create images for a frame behaviour (3x3)
delete element;
element = NULL;
}

elements[theme_id] = element; //  <---------------- elements is a theme_element_t vector list, the base class of theme_frame_t.

return ret;
}
The GUI element (such as a button or scrollbar) doesn't need to know how this is drawn or what rule is applied for a specific theme. The theme manager keep a vector list of the base class type theme_element_t, and calls the virtual function draw that is defined in the derived class, different depending on the type.

If this had been a button with the horizontal behaviour...

Code: [Select]
bool theme_manager_t::register_horizontal( theme_element_id theme_id, image_id left_id, image_id middle_id, image_id right_id )
{
theme_horizontal_t *element = new theme_horizontal_t; // <---------------- Create a different class for a horizontal behaviour
bool ret;

// delete any previous definition
if (elements[theme_id] != NULL) {
delete elements[theme_id];
}

remove_offset(left_id);
remove_offset(middle_id);
remove_offset(right_id);
if ( false  ==  (ret = element->init(left_id, middle_id, right_id)) ) { // <------ Create images for a horizontal behaviour (1x3)
delete element;
element = NULL;
}

elements[theme_id] = element; //  <---------------- elements is a theme_element_t vector list, the base class of theme_horizontal_t.

return ret;
}

If we look at these two functions, they are identical except for the created theme class. I have not yet done any optimisation! Because the init() function is a pure virtual function, this can be significantly optimised, but I will do this a little bit further down the road when we have a "real" class factory, controlled by the artist choice of applying theme rule.

As you can see, all these theme classes are ending up in the same vector list elements[] where the index is a specific type of GUI theme element, such as BUTTON UP, BUTTON DOWN, GROUP BOX, FRAME OUTLINE etc... But because it is a base class pointer the implementation of the virtual function Display() are different, as described above.

So the GUI button really doesn't need to know what rule the artist as applied to it, it only tells the theme manager to draw a theme ID, such as BUTTON UP. How this is done, is of no interest for the button.

theme_manager.display( (b_enabled) ? ((pressed) ? THEME_ID_BUTTON_DOWN : THEME_ID_BUTTON_UP) : THEME_ID_BUTTON_DISABLED, frame);
// continue button drawing, such as text...
[/tt]

The theme manager picks up the base pointer from the list and calls the virtual function draw().

Quote
bool theme_manager_t::display ( theme_element_id theme_id, scr_rect frame, control_alignment_t align)
{
   theme_element_t *element = elements[theme_id];

   // Element defined?
   if(element == NULL) {  <-------------- We can implement an emergency-last-resort-fall-back here
      char Buff[5];
      itoa(theme_id,Buff,10);
      DBG_DEBUG(LOCATION "Unknown theme id ", Buff );
      return false;
   }

   // Don't draw themes outside current clip rectangle.
   scr_rect current_clip = display_get_clip_wh();
   if ( RECT_RELATION_OUTSIDE  ==  current_clip.relation(frame) ) {
      return false;
   }

   // Draw theme
   element->display( frame, align ); // <----------------  Call the implementation of the pure virtual function Display()

   return true;
}

As you can see, the GUI button or the theme manager don't need to know if this is a frame, horizontal, vertical, or symbol implementation. The correct routine is called through its ADT interface (the base class).
If we want to add more behaviour rules, we only need to add a new derived class from theme_element_t.

The registration process isn't so forgiving at this moment but after the registration, there is a validation phase.

Code: [Select]
bool theme_manager_t::validate( void )
{
if(elements[THEME_ID_BUTTON_DISABLED] == NULL) {
elements[THEME_ID_BUTTON_DISABLED] = elements[THEME_ID_BUTTON_UP];
}
return true;
}

This is only an example of how this will work. If an element is missing (NULL) it can reuse another elements class instance as fall back. In this case, if there is no definition for a disabled button, the button up behaviour and images will be reused.
If you apply the full patch and put a break point for various GUI controls (using the theme manager) you will see that even if they all use the same vector list, different code is called for the Display() function.

Quote
In the end we are discussing how to draw buttons and scrollbars only(!) while most of the real work is left untouched.
As you can see, my design is very OOP, using polymorphism (http://en.wikipedia.org/wiki/Polymorphism_(computer_science)) to allowing us (artists and users) assign any of the available behaviours to any GUI element.

Please ask me if there is something here that is unclear, or feel free to fill in to explain the OOP aspect in this design.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 09:08:42 AM
Regarding foo(void) and foo() it seems like you all misunderstood me.

I'm, and the recommendation is, in favour for foo(void) because foo() can take anything as a parameter, this is the old C style and C++ allows it for backward compatibility.
foo(void) makes it clear that it can't be anything else than a void. foo() is not the same as foo(void). To ensure cross compiler compatibilities, foo(void) is treated the same across all compilers and enforces type checking. foo() turns of type checking for the parameters.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 19, 2013, 12:07:33 PM
Okay then, another issue we can't reach consensus then. This is not the way to go, imho. Let's have two way of doing yet the same thing in our code.

And this was a small issue to agree on. This makes no sense.

Using (void) on the declaration you avoid being called with parameters, that well, will avoid... Nothing, since they will be just ignored anyway. You are asking for understanding but can't yet agree in such small and irrelevant issues.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 19, 2013, 12:30:12 PM
To spice up the discussion. Here is a small test file in c++:
Code: [Select]
void foo();

struct bla {

        bla();
        bla(int);
        ~bla();
};

int main()
{
        bla a(1);
        foo();
        foo(1);
        foo(1,1);
}
It does all the bad things: functions without arguments, not void put there. Structs with self-references.

Here is what g++ thinks about this:
Code: [Select]
~/ccc> g++ testcpp.cc
testcpp.cc: In function 'int main()':
testcpp.cc:14:7: error: too many arguments to function 'void foo()'
testcpp.cc:2:6: note: declared here
testcpp.cc:15:9: error: too many arguments to function 'void foo()'
testcpp.cc:2:6: note: declared here
It seems that Max-Max and Gnu C++ compiler have different understanding of the language: the struct compiles fine, can reference itself, the function DOES NOT accept more than zero arguments although the declaration is not written as 'void foo(void)'.

@Markohs, please commit your patch.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 19, 2013, 01:05:00 PM
Done @ 6827

Just another tought, I don't like many of the current coding styles of simutrans, Max-Max, I'd use singletons, namespaces and I hate not being able to:

if(cond) do_it();

or

function a(){
}

 Or many other things, but I accept it, it's the way we do it. After all, they are just subtle details that don't forbid you to do what you want to do, that's coding.

 We should restrict our discussions to important things, let's waste time there, and not on this minor details, it's better to all.

 About the other discussions:

 1) I consider completely acceptable using structs with creator functions, in fact there are a lot in our code, it's indeed the way to go imho.
 2) Reading your ADT description, it makes complete sense to me. And given it's a "registration" process, that won't be done *each frame* if I understood correctly, but just on frame creation, I think it's a good idea, and the way to go. If virtual calls are used during frame display as you seem to show on the display function, should be *fast*, very fast code.
 3) As for the 3x3 issue, and having prissi expressed he liked the idea, I guess it's accepted, not more to say on that, I trust him.

 As a general idea, and not knowing much of the details, all the heavy OOP code, should be in the set-up of the windows, and operations that will be done on window creation, management, event processing... At the end this theme management code, should create "data structures", data strectures that a completely data-driven algorithm, a C-Style function is able to just process *each frame*, and draw the items light-speed. Aliginments, positioning, event management... all that kind of stuff *can* be slow, but drawing , the process of displaying all the windows each frame, *must* be fast.

 Why? Because drawing is done 20 to 30 times *per second*, and the other operations are just done *once*, on frame creation, updating, event receiving... much less often.

I have not yet done any optimisation! Because the init() function is a pure virtual function, this can be significantly optimised, but I will do this a little bit further down the road when we have a "real" class factory, controlled by the artist choice of applying theme rule.

 Do it then, asap. It's the best way you can support your code.
Title: Re: [Project] GUI Theme
Post by: prissi on October 19, 2013, 01:14:30 PM
... foo() is not the same as foo(void). To ensure cross compiler compatibilities, foo(void) is treated the same across all compilers and enforces type checking. foo() turns of type checking for the parameters.
Sorry, this is wrong. Look at the C++ standard draft. It is nearly 1350 pages, but on almost any of them you find call with empty parameter lists: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

In C++ f() is identical to f(void) look in the standard! Hence, calling f(bla,i) for something like f() will result in C++ with an error, since functions have name mangling and f() is internally mangled as (void). It would be different, if the functions is called extern "C" int f(); (which is not allowed according to the standard §7.5.7 page 174, btw.). It is actually the same thing as the _tag stuff (which the standard defines on §8.4.2.5 pages 198 as not needed.) This is something only C needs.

Your style and my differ, but is is not required by the standard.  I am with that on Markohs and rather have his patch applied (and amend the documentation). Most void s in the code are relicts from the C to C++ conversion several files underwent about five years ago. So two votes for removing them.

EDIT: goolgeling the standard and all that, I saw it was already submitted.

In order to get this back on track I will try to submit the undisputed parts. Otherwise everything just gets bitrot.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 09:27:40 PM
To spice up the discussion. Here is a small test file in c++...
Okej, this foo( void ) stuff is not really what I wanted to have reviewed, I was only answering why I put in some void. But since you are at it I have to correct an misunderstanding of its use, to not make me look like a complete failure...

You can do a forward declaration in your header file like this: void foo();

Because foo() is not specifying any type, it can be anything in the implementation of the function foo.
For example:

void foo(int bar) {}

There is nothing in the header file indicating that your intention is to actually take an int as parameter.
This behaviour is an old C legacy where you could have one header file specifying foo() and then have different .cpp files (like simgraph16.cc and simgraph0.cc) but with different parameters in the actual void foo() implementation.

So in this case foo() isn't necessarily the same as foo( void ) where you distinct specify that the implementation really don't take any parameter, this is what I was taught... enough about this.

So now when Dwachs and Prissi has spent so much time on this minor insignificant detail, I really would like to hear what you have to say about the design I presented. Have you understood how it works? Any questions?

To follow up on Markohs comments.
Yes, you have got it quite right. The theme manager is preparing all images on theme load. The virtual functions make sure that you can treat all the different types of element rules the same by using the common base interface where the implementation of Display() is doing the drawing according to the set of rules applied for this theme.

In this design there is no need to do any tests to see what rule to apply, just call the virtual function and the rest is done in its final implementation (derived class).

If we didn't use a virtual function and implemented it more like a structural C implementation, we first have to test what rule to apply and then call the right function for it. You achieve the same thing but has to do an extra test first.

When it comes to GUI drawing in general (I'm not counting the karte to GUI drawing), it only needs to be updated when the user interact or a value gets updated. A much faster update approach is to have an off screen buffer of the GUI window (the frame_t). The off screen bitmap is the one updated when the user interacts, then 30 times a second, this off screen buffer is just blitted to the screen memory.

This saves a lot of time because GUI updates are very rare in this context.

One way to even minimize the impact further is to only mark the window as dirty (off screen image needs to be updated), but have a separate thread that updates dirty windows when there is time for it (for this a double buffer might be needed to minimize flicker, maybe not).

I did suggested this approach earlier in the project but got the answer that the GUI drawing stuff takes so little time that it isn't needed. Maybe we should reconsider this solution instead of constrain features in the GUI, if we get to that point.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 19, 2013, 09:44:35 PM
If we didn't use a virtual function and implemented it more like a structural C implementation, we first have to test what rule to apply and then call the right function for it. You achieve the same thing but has to do an extra test first.

 Well, virtual functions trigger a vtable method lookup too, so it's comparable, anyway ofc it's better to do it with virtual functions because it's way more understandable, maintainable, blablabla... Better design.

Quote
(I'm not counting the karte to GUI drawing)

 Yes, ignore that, that's gonne be handled separately.

When it comes to GUI drawing in general (I'm not counting the karte to GUI drawing), it only needs to be updated when the user interact or a value gets updated. A much faster update approach is to have an off screen buffer of the GUI window (the frame_t). The off screen bitmap is the one updated when the user interacts, then 30 times a second, this off screen buffer is just blitted to the screen memory.

 I can understand the blitting, and it's a good idea, *but* I'd not implement it that way.

 Why?

 1) Blitting is not so fast, given we don't have libraries that can rely that blitting to hardware, we don't have DirectX anymore.
 2) You can acheive *almost* the same effect having each GUI unit (a frame, but you can sub-divide the problem), generating a set of primitives to get drawn on the framebuffer, so the draw() method just has to transverse that list and execute them in order.

 Why I suggest this? Because in our current implementation, it's *fast enough*, and, in the (desirable) case we get proper 3D support in the future, we can just get those drawing primitives inside a vertex buffer in the VRAM, and just tell the hardware to render it, with no extra CPU cost.

 It also has one extra advantage, on a small sub-window change, we don't have to re-create the full bitmap again, just update the affected part, faster.

Quote
This saves a lot of time because GUI updates are very rare in this context.

Indeed.

Quote
One way to even minimize the impact further is to only mark the window as dirty (off screen image needs to be updated), but have a separate thread that updates dirty windows when there is time for it (for this a double buffer might be needed to minimize flicker, maybe not).
I did suggested this approach earlier in the project but got the answer that the GUI drawing stuff takes so little time that it isn't needed. Maybe we should reconsider this solution instead of constrain features in the GUI, if we get to that point.

 We'll see what gets of this.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 19, 2013, 09:56:58 PM
Quote
Okej, this foo( void ) stuff is not really what I wanted to have reviewed, I was only answering why I put in some void. But since you are at it I have to correct an misunderstanding of its use, to not make me look like a complete failure...
Please don't think that's what people are trying to do. I'm sure people understand where you are coming from - just understand that the existing simutrans code style is to use foo() not foo( void ), and no matter what the technical merits or otherwise that won't be changing.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 10:02:16 PM
I can understand the blitting, and it's a good idea, *but* I'd not implement it that way.

 Why?

 1) Blitting is not so fast, given we don't have libraries that can rely that blitting to hardware, we don't have DirectX anymore.
 2) You can acheive *almost* the same effect having each GUI unit (a frame, but you can sub-divide the problem), generating a set of primitives to get drawn on the framebuffer, so the draw() method just has to transverse that list and execute them in order.
Hmm, I was referring to software blitting.  So what I meant was the use of memcpy() to just "blit" the off screen memory to the "screen" memory, same memory all display_XXX functions use as destination.

Why I suggest this? Because in our current implementation, it's *fast enough*, and, in the (desirable) case we get proper 3D support in the future, we can just get those drawing primitives inside a vertex buffer in the VRAM, and just tell the hardware to render it, with no extra CPU cost.
Actually in Windows7 and up, all old Win32 GDI API are redirected to use "DirectX", this means old programs using GDI benefits from GPU hardware.
But you get a good point there, when we move to Direct3D ;)

EDIT***
Kierongreen
That wasn't my intention to brag over something, I just wanted to set the record straight. My personal opinion is to be as clear as possible, to specify void when it indeed is a void. But if no one else wants this, fine, put it in the coding rule document so everyone knows, because now it's a mix (not only my code). :)
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 19, 2013, 10:11:23 PM
Latest commit really breaks compiles on linux. Please don't use _MAX_PATH or other Windows API defines. Trying to fix this and other compile errors.

Also overloading of scr_coord and koord breaks. Only way to fix this I can see is changing a whole load of koord to scr_coord in gui headers. I'm not doing this as I assume someone else is better qualified to do this.
Title: Re: [Project] GUI Theme
Post by: prissi on October 19, 2013, 10:15:51 PM
Quote
You can do a forward declaration in your header file like this: void foo();
No, you cannot in C++, not for a function taking an int. Final statement, read the standard!

You know, being taught and so is nice. But Dwachs and me did look up the stuff or tried it out. You could have done too, since you boldly stated wrongly that f() and f(void) are different even in C++. It would be more helpful to admid that you learned something new (as I discover every day {and that is why I looked it up in the standard} ).

But let's get back to topic.

Markohs gave already very good arguments why not double buffering dialogues. Let me add: there are many dialogues whose contents often changes every, sometimes frame, convois (the view, costs,statistics ), stations (view, list of goods, departure board, statistics), finances, and so one. One very few dialogues have no changes at all. With all this, double buffering dialogues does not sound like we would gain much for for the trouble of extra code.

We will never move to Direct3D, since it is not portable. Markohs did a OpenGL port, which was working a little. It should be in the branch when you check out. It suspect however a little dust around there.

By the way, I submitted you changes as much as I could without any disputed part. That will make you patches much smaller. So I am to blame for breaking, sorry.
Title: Re: [Project] GUI Theme
Post by: Ters on October 19, 2013, 10:37:07 PM
My purpose has never been to hand out dunce hats, if that's what anyone thinks. I was sharing my knowledge of how things work, not only for those involved in the thread at the present, but for future readers as well.
We will never move to Direct3D, since it is not portable. Markohs did a OpenGL port, which was working a little. It should be in the branch when you check out. It suspect however a little dust around there.
There are also my two attempts, in which I found that Simutrans is very 3D-unfriendly. Recent changes might clear up the problems in the engine, but the biggest problem is in the way graphics and sub-tile positioning is tied to the 2D rendering.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 10:58:55 PM
No, you cannot in C++, not for a function taking an int. Final statement, read the standard...
My GOD! I think I must be really bad at explaining what I mean, maybe I used the wrong word somewhere or got lost in translation... Just let us drop it, I will not make any more tries to explain what I meant.

I have no problem to admit that I have wrong or if I don't know something. I do ask when I have questions, but it isn't always I get an answer to them.

Markohs gave already very good arguments why not double buffering dialogues...
Well, it was only a suggestion to speed things up a little. To only update a small view is faster than updating a whole window. Maybe I failed to get that through too...

We will never move to Direct3D, since it is not portable. Markohs did a OpenGL port, which was working a little. It should be in the branch when you check out. It suspect however a little dust around there.
Well, I was only making a comment on Markohs "in the (desirable) case we get proper 3D support in the future...", did you notice the smiley I put in there?

By the way, I submitted you changes as much as I could without any disputed part. That will make you patches much smaller. So I am to blame for breaking, sorry.
Well, I can't really update my local trunk until we have agreed on the disputed code. Either way, I will have quite some work to do to get it up in synch. There fore I can't really do anything until then...
Title: Re: [Project] GUI Theme
Post by: prissi on October 19, 2013, 11:00:09 PM
Sorry, it seems I misunderstood. Let's cool this off again.

(Just a short remark on this meanderign thread to 3D: The new "transportGeneral" has somehow transferred an isometric engine sucessfully to 3D. Unfourtunately there is no source, despite strong hitns that GPL'ed code has been involved. But we are getting offtopic.)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 19, 2013, 11:07:20 PM
Although the new "transportGeneral" has somehow transferred an isometric engine sucessfully to 3D. Unfourtunately there is no source, despite strong hitns that GPL'ed code has been involved. (But we are getting offtopic.)
Actually Torque3D and Torque2D has gone open source (https://github.com/GarageGames/Torque2D). I know that Torque2D has great support for isometric rendering (http://youtu.be/5a3yTquEzXY?t=3s).
Title: Re: [Project] GUI Theme
Post by: Markohs on October 19, 2013, 11:55:18 PM
Hmm, I was referring to software blitting.  So what I meant was the use of memcpy() to just "blit" the off screen memory to the "screen" memory, same memory all display_XXX functions use as destination.
Actually in Windows7 and up, all old Win32 GDI API are redirected to use "DirectX", this means old programs using GDI benefits from GPU hardware.
But you get a good point there, when we move to Direct3D ;)

 Even using GDI, I'm afraid it makes no difference. Using memcpy you won't trigger the DirecX hardware blit, you need to do more complex operations, expalined here (http://www.codeproject.com/Tips/66909/Rendering-fast-with-GDI-What-to-do-and-what-not-to) (I just googled it and didn't read it, just to point it's not so simple as memcopy).

 Using our current primitives, display_img_* display_text_* ... we just rle decode a image into a buffer, that's later copied to another buffer, vía GDI, or SDL, whatever. To make use of hardware we'd need to copy uncompressed RGBA 32-bit buffers, from one buffer to others, using blitting. What we do it's not blitting.

 About the 3D implementation, I was not the only author, Ters did maybe even more than me in that subject, and we faced big problems in doing so, given the nature of this game (don't forget this game ran in MS-DOS) . Most of the changes I've been doing so far are trying to ease this problems, so our next try, is hopefully successful. It's not an abandoned project. But I lacked knowledge of the game, something I'm trying to solve, to see how can we blend this game with the 3D game technology, that differ, and quite a lot.

 In fact, the changes I suggested to you are in line in how a modern game handles its GUI, in OpenGL/Direct3D. :)

Actually Torque3D and Torque2D has gone open source (https://github.com/GarageGames/Torque2D). I know that Torque2D has great support for isometric rendering (http://youtu.be/5a3yTquEzXY?t=3s).

 It's way harder than choosing a framework, this problem lies way deeper in the code.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 20, 2013, 12:12:25 AM
Even using GDI, I'm afraid it makes no difference. Using memcpy you won't trigger the DirecX hardware blit, you need to do more complex operations, expalined here (http://www.codeproject.com/Tips/66909/Rendering-fast-with-GDI-What-to-do-and-what-not-to) (I just googled it and didn't read it, just to point it's not so simple as memcopy).
Well, I basically meant that one memcpy() call would probably be faster than have to call all the windows GUI controls. Frame_t on its own is basically doing a full memcopy() already (background) and on top of that each GUI control. However it was only a suggestion if we need to speed things up...

In fact, the changes I suggested to you are in line in how a modern game handles its GUI, in OpenGL/Direct3D. :)
I think we are on the same page here. To test and then call a C like function each frame compared to call a virtual function I think takes the same amount of time. In fact I even think the VTable is faster here because we don't need to do any tests, only fetch the virtual function from the VTable. Most modern compilers of today handles VTables quite good and the overhead that gave virtual functions bad reputations in the beginning is almost gone.

...and if we do need more time, I just made the off screen as a suggestion (and only redraw GUI children that has changed) to save more time. Again this is only a suggestion...
Title: Re: [Project] GUI Theme
Post by: Markohs on October 20, 2013, 12:32:08 AM
 I think the more flexible and viable option, with an acceptable performance in any circumstance is the one we discussed that's:

* Use heavy OOP programming on all the GUI code, window movement, updating, gui elements alignment, event handling and management, but this functions just need to keep up-to-date a list of primitives, not complicated.
* Then, a routine, with little to no OOP just transverses that list and redraws the *whole* gui. This has to be fast, super-fast. It's going to be done ~30 times per second.

 Forget about partial redraws, better to go all-in here, focus on the fastest full redraw. Simutrans and all the games I know of, just redraw the whole UI per-frame, fully.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 20, 2013, 07:30:03 AM
Also overloading of scr_coord and koord breaks. Only way to fix this I can see is changing a whole load of koord to scr_coord in gui headers. I'm not doing this as I assume someone else is better qualified to do this.
should compile again.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 20, 2013, 09:49:30 AM
Does indeed compile now many thanks. However there are still a large number of warnings in gui. Will try seeing what is behind these.
Title: Re: [Project] GUI Theme
Post by: Ters on October 20, 2013, 10:47:00 AM
Here's a patch for the reorder warnings. The other warnings in the GUI are unused parameters and variables, I assume because something isn't finished yet.

Apart from that, Simutrans is surprisingly warning free these days.

Update:
Another patch for a possibly GUI related warning in simstring.cc.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 20, 2013, 11:02:46 AM
Quote
Here's a patch for the reorder warnings. The other warnings in the GUI are unused parameters and variables, I assume because something isn't finished yet.
Thanks :)

Quote
Apart from that, Simutrans is surprisingly warning free these days.
Indeed - want to keep it that way too as it makes debugging much easier!
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 20, 2013, 11:15:18 AM
Thank you, all of this should be now in r6837.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 21, 2013, 01:22:14 PM
updated coding_styles.txt to reflect the (void) issue, if someone wants to make a better description, please do so, my english is not so good. :)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 22, 2013, 09:39:58 PM
So where are we standing here?
I'm not sure if you'll are waiting for me to submit something or if more of the patch is on its way in?
Title: Re: [Project] GUI Theme
Post by: prissi on October 22, 2013, 10:03:59 PM
I though long about how to proceed: I am now convinced that it could be nice to cut the images semi-automatically, as an alternative. But I think makeobj is the right place for the cutting (as Dwachs suggested too).

I could image a command "cutimage[0]=bla.#xFF0000" as alternative (not complete replacement) to "image[0]=m.0.0 image[1]=m.0.1, ..."  which then takes this image and cuts it along the red lines and adds it to a list (either 2, 3, 2x2, 2x3, 3x3, ... according to the lines). It should work also for other stuff, not only buttons (like buildings etc.)

Second thing is, that 3x3 scalable buttons are nice. I am just playing around with them (I append work in progress a patch with the sources and pak for the only skin that is halfway designed. It is an ugly color choice too!) If you want to move the drawing into gui_theme or another file, well I can live with that too.

Apart from how stuff is actually loaded and where the drawing subroutine is located: Many thing are still not finished, when thinking at the original goal. Like to derive posbuttons form a base button, and same for squarebuttons, checkboxes etc, since some need coordinates, some need text, some need text and colors, other need nothing. Also using freetype for text rendering in larger sizes (and the problems of how to get a nice dialogue coping with different sizes).
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 22, 2013, 10:51:56 PM
I think the major problem her is that this "patch" workflow doesn't work for large projects. If patches are to be small, then the project will be submitted in small pieces, where each part might be a temporary state or still in development.

If patches has to be full implementations and reviewed as a finished piece of code, then they become quite large. Either model is working for only one part of us. It is impossible to do both for a larger project.

You can imagine yourself if you have written half your program only to find that the next day someone has rewritten all your code and implemented a different design. That would severely interfere with your planned work ahead...

I think we need to find another workflow to get this project up to speed. I did the mistake to believe a patch could be a working copy of work in progress, but now I understand that you all expect a patch to be a finished patch for code review.

So how do we proceed so the patches doesn't get to big and my work isn't rewritten before I have the chance to finish it myself?
Title: Re: [Project] GUI Theme
Post by: Markohs on October 22, 2013, 11:22:18 PM
My suggestion is:

- As I allways stated, big patches are preferred imho, it gives you the chance to code freely, each patch should be of significance, and be:

 * Significant: Should implement important new aspects of the game, and have a reflection in the user, our players have to be able to see "something new". If it's not visible to the user, and it's just re-design, it has to be of relevance, not minor tweaks.
 * Complete: It's suposed to leave the game in a consistent state, no parts of the game should be incomplete or buggy, no excuses here. If a change has to be done in this patch, it has to be completed fully, not leave parts for future patches. If this forces you to write code just for this patch that will disappear later it doesn't matter, you have to do it anyway.
 * Consolidated: As it's incorporated to the game trunk, it will end being in the nightlies. From that precise moment, bug reports need to be fixed, asap, in live code. Not fixed in the patch, even if that part of the code has been rewritten again in the patch, or the bug makes no sense in the future patch, the bug has to be solved in live code.

- To avoid a posted patch to be "rejected" or in a "to be rewritten" state, like prissi is doing with your patch, I suggest you posting *frequent updates* of your patch for review. prissi and the rest of coders will *suggest*, or *strongly suggest* you to change aspects of the patch. The discussion has to be constructive *by both parts*, but *at the end, it's YOUR responsability* to update the patch, in your computer. Once the patch is completed, it will be sent to trunk, *as you posted*, as you and the rest of developers agreed it to be. Minor modifications can be at place, ofc, but have to be of very low relevance, not significant changes.
- The responsability to keep your patch up-to-date with the trunk is yours too, you need to do it. You are ofc allowed to ask to pospone a change in trunk, it it's going to cause huge troubles to you, but with a valid argument.

 Well, what do you all think? I tried to express some procedure that protects Max-Max and future patchers enough, while allowing the "senior" programmers enough control of the process. But ofc, we have to mind many things already said. All conversations need to stay contructive, people have to mind no member of the community wants to be rude with anybody, and we all respect each other. We also have to mind everybody has somewhat different coding styles, we all should be in the middle, and flexible, but writing quality code. This is not personal, we are just open source programmers, collaborating. :)

 We should, as open source programmers, be positive about changes, and see them as an opportunity. But we are not low quality programmers, and we are supposed to identify when a change is needed and wanted, because it gives to us something worth it, because all additions brings us new bugs, and we'll have to keep maintenance in that new code, forever. That new code has to be worth it, and we need to realize when it's time to throw something to the trash, and start again.
 
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 23, 2013, 12:56:34 AM
Hmm, It all sounds great but every one must sign up to this workflow and as you say respect that we have some different ways of solving problems.

Prissi's addition of one skin_besch_t* skinverwaltung_t::xxxxx for each GUI control completely interferes with my development road. It took me quite some time to restore my code after this addition and now Prissi continues to develop down this path, ignoring that I have a complete different solution in the pipe that already is half implemented and the base for coming theme operations.

In this latest "reworked" patch from Prissi he has also dissected my theme classes further and moved around more code. With these new changes and the one already in trunk makes it very hard for me to keep my code in synch.

I which we could roll back any theme related code to the state it was before Prissi added the theme selector dialogue into the trunk. As it is now, my code is dissected so much that It will take me quite some time to restore it again and my guess is that Prissi will continue his path meanwhile...  :-[

I don't know how these large project are managed, but I take it as the person starting the project is the "project manager" and if people wants to help, at least synch with the project manager, or ask what they can do to help instead of just rewriting code and running their own race in parallel.

How do we proceed from here? I can try to restore my code once again with the current trunk, but it isn't any point if Prissi is going to develop the same things in parallel with me...
Title: Re: [Project] GUI Theme
Post by: Markohs on October 23, 2013, 01:06:22 AM
I guess we are at a stalled point there, I can't do more on this subject.

That's something you and prissi need to solve. :)

But to reach an agreement, allways both parts need to yield something. Both. :)
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 23, 2013, 07:20:04 AM
My honest advice Max Max is to find another area of simutrans to work on. Whatever your vision was of themes is unlikely to be what finally gets implemented. Keeping on developing to reach your original objectives will only be frustrating.

My advice to people submitting patches is similar to Markohs - by all means have other people look at the code and make comments but don't try submitting to trunk until it's finished. At that point accept there may be some changes made (but hopefully not if there's been good dialogue between patcher and dev team).

Hopefully we can all learn from this and avoid something like this happening again. Only rewrite a patch once author is wanting to submit it to trunk (or has abandoned it of course).
Title: Re: [Project] GUI Theme
Post by: prissi on October 23, 2013, 08:57:43 AM
Actually, I did not touch much of your code when submitting the themeselector changes and the other changes to dialogues. I mostly changed the header, and that is it. The olnly other thing is I did not commit the merged alignment parameters, since this obscures too much. I did not touch and of theme files, so there should no changes needed.

My advice is to focus on one thing at a time. I strongly disagree with Markohs, most large patches never make it. But then that is his style. For me, large patches are take it or leave it. So if I or somebody else is not happy it will not be committed until you change what you may not like, and you feel there is lot of work wasted (as there is lot of work wasted with patch review). This does not work out.

If you want to continue on GUI improvement, here my suggestion for smaller patches:

Make a patch for makeobj to cut stuff into imagelists. This can easily survive whatever you do later on the simutrans side.
Make a patch each dialogue at a time.
Make a patch to use the current skinverwaltung_t with you themes (because cutting images in simutrans will not be the way.)
Make a button patch.
Make a patch in simwin.cc to have gui_frame_t the object handled by simwin and not the win struct, i.e. add magics, gadget etc. into gui_frame_t and let it also draw its titleback itselve. This will obviously also move some event haqndling to gui_frame_t, which is probably a good think, since it shringkes simwin and increase the still small gui_frame_t.

All those would be fairly independent from each other.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 23, 2013, 09:25:44 AM
As bottom line, an updated version of your patch would be much appreciated.

I agree with prissi that the code to cut images along lines with a particular color is interesting in its own right and should be implemented as part of makeobj (image_writer and friends) to be available for all the graphic authors.

I agree with Max-Max that the images and so on should be handled by a separate theme class. (independent of or superseding skinverwaltung).

I strongly disagree with Kieron on just giving up: this would be a great waste of time and existing work.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 23, 2013, 05:03:18 PM
Okay, my suggestion is that we halt all the patches for now, I need to clean up this somehow.

I have a questions although:

Why do we need skin_besch_t* skinverwaltung_t::xxxxx other than at loading?
What I have seen so far all display_img_xxxx routines are using the image ID to draw an image. All skin_besch_t* skinverwaltung_t::xxxxx is used for, after loading, is to retrieve this number.
The theme manager groups and holds these image ID's for each theme element and the use of skin_besch_t* skinverwaltung_t::xxxxx is obsolete after loading.
To split skin_besch_t* skinverwaltung_t::xxxxx into one list for each Theme element doesn't really do any difference other than we need to add a new skin_besch_t* skinverwaltung_t::xxxxx every time we add a new theme element. What I can see from this is that all it does is to create more work when we continue to add more theme elements.

What I can see here is that skin_besch_t* skinverwaltung_t::xxxxx can be removed for theme elements and have the theme-pak reader directly in the theme manager, to directly register the images and group the image IDs.
If it is preferable to have the reader in a separate class, it can interact directly with the theme manager instead of using the skin_besch_t* skinverwaltung_t::xxxxx.

Another alternative would be to make the theme related skin_besch_t* skinverwaltung_t::xxxxx dynamic so it can be deallocated after PAK load.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 23, 2013, 05:25:08 PM
I my point of view, the purpose of skinverwaltung is exactly what you described: have a class that holds all the pointers to different skin-besch things, which are essentially a list of images.

Deallocating these kind of things is another payload of work: all the besch-classes lack proper destructors.

Adding an new skin_besch_t*  member to skinverwaltung seems to be still less work than to implement a complete pair of reader / writer for theme-paks.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 23, 2013, 06:07:38 PM
Adding an new skin_besch_t*  member to skinverwaltung seems to be still less work than to implement a complete pair of reader / writer for theme-paks.
This is what I have now. At first Prissi added one new skin_besch_t* member called theme, this is the one I'm using now. However, later Prissi added a new skin_besch_t* member for each GUI theme element. Imho it creates more work when we add more GUI theme elements. The skin indexes becomes local for each GUI theme element, where an index number means different things depending on theme element. When referring to a theme element, it isn't enough to use one index, but also the right skin_besh_t* member.

I would like to continue to use one skin_besch_t* member for all theme elements because we can treat all gui theme elements as one, not have to know what theme element we are dealing with.
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 23, 2013, 07:17:17 PM
I would like to continue to use one skin_besch_t* member for all theme elements because we can treat all gui theme elements as one, not have to know what theme element we are dealing with.
You have the choice: either have a lot of named skin_besch_t* members or an array of skin_besch_t* with named indices. Seems like the last method is more comfortable: one pak file and one besch to rule them all.
Title: Re: [Project] GUI Theme
Post by: prissi on October 23, 2013, 08:42:45 PM
I think a list with all stuff in the same object is a monster. With the proposed 9x9 buttons a normal button has 27 (on off disabled) and a color button 9x4=36 images. Add gadgets and arrow buttons, posbuttons, checkboxes, and scrollbars and you have a obj=menu with 93 predefined images. How big a list do you want?

Or you can have one
obj=skin
name=posbutton
with three images ...

Apart from the cleaner approach to find a check box image under skinverwaltung_t::check_button and not under skinverwaltung_t::theme number 54 to 57. If we get rid of the old system that did exactly this, I want to improve the format.

The implementation now has all different objects in one pak, since makeobj can merge paks together (and can also unmerge them easily). That way even a user can exchange certain images, which is also not possible with a monolytic pak.

Furthermore, apart from the ground tile code simutrans internally did not used the bild_t members. Those were just added quite late to move the blending of images into the climate ground code. All other code is geared for the image numbers.

For this reason I am not fond of a single skin, and much less of a new mechanism for skins. Keep it simple!

As it goes, either me or Max-Max will waste work, as my way of implemetation is different from his. I.e. I did reuse the skinverwaltung_t, and just added three functions to display_* to display stretched image and ellipse text (the prior was also invented of by Max-Max).

Anyway, updated patch is attatched, as well as a standardpak (EDIT: now with the paks) THis shoudl take care of the nine image buttons and should be fully scaleable. Just add gui_button_height=20 will give you larger buttons.)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 23, 2013, 09:42:36 PM
I think a list with all stuff in the same object is a monster. With the proposed 9x9 buttons a normal button has 27 (on off disabled) and a color button 9x4=36 images. Add gadgets and arrow buttons, posbuttons, checkboxes, and scrollbars and you have a obj=menu with 93 predefined images. How big a list do you want?
I'm more and more convinced to put the cutting in the them manager.

1)
The artist only needs to supply one image per GUI theme and state. This can be one image with guard lines (cutting lines) or just a plain image if the default cutting is enough. The default cutting works fine for irregular shapes as long the irregularities are within the auto cutting.

2)
By letting the theme manager do the cutting, we only need one image per element and state, not 3x3xn states. If the artist doesn't paint in cutting lines, it can still be configured to be cut as a 1x3, 3x1 or 3x3. The advantage of this is that the Artist can for example configure it to only be horizontally resized, but the user can override this and have it both horizontal and vertical (maybe he needs it for touch screen). This also speaks for the theme manager to do the cutting.

Or you can have one
obj=skin
name=posbutton
with three images ...
...or as I explained only one image. But 2 or 3 are also possible, everything for the artist to chose.

Apart from the cleaner approach to find a check box image under skinverwaltung_t::check_button and not under skinverwaltung_t::theme number 54 to 57. If we get rid of the old system that did exactly this, I want to improve the format.
The whole point with the theme manager is that a GUI control should not know what images to use, it tells the theme manager to draw a specific theme. The manager created an internal list, grouping the image ID (not the skinverwaltung_t index, since they are not used at all after PAK load). The theme manager use the image ID from the big images[] list directly in the calls to display_img_xxxx

The implementation now has all different objects in one pak, since makeobj can merge paks together (and can also unmerge them easily). That way even a user can exchange certain images, which is also not possible with a monolytic pak.
It sounds like a good idea, but splitting and Merging PAK, isn't that a typical makeobj functionality that could be developed further to extract and repack images from another PAK. I thinkn this should be an extended developent of the makeobj, not the theme system, so it can be used with any kind of images in a PAK.

Furthermore, apart from the ground tile code simutrans internally did not used the bild_t members. Those were just added quite late to move the blending of images into the climate ground code. All other code is geared for the image numbers.
The theme manager is using the image numbers (image ID) and the already in place display_img_xxxx functions, so yes, the theme manager is working with image numbers already, it's al in my original code.

For this reason I am not fond of a single skin, and much less of a new mechanism for skins. Keep it simple!
If you refer to the old one-image-all-controls, you can't have opened the theme source I posted together with the patch. All controls have their own bitmaps, they don't need to be in one single image, neither did they need to do this in the past either. People for some reason just put all of it into one image. This also makes it possible to share single controls and their graphics. It's all in there...
Your implementation of one skin_besch_t* member for each theme element makes all previous skin-PAK and formats obsolete and needs to be redone. My patch use the current skin PAK format, nothing has changed! Everything is exactly as before, you can even use your old skin files and PAK if you like.

As it goes, either me or Max-Max will waste work, as my way of implemetation is different from his. I.e. I did reuse the skinverwaltung_t, and just added three functions to display_* to display stretched image and ellipse text (the prior was also invented of by Max-Max).
Well, my implementation is object oriented and encapsulate the skin drawing from the GUI control. The GUI control doesn't know what images are used or what rule has been applied by the artist. The theme manager can reroute themes to use the same single set of images, a technicality the GUI control doesn't need to know.
The theme manager also use stack oriented clip rectangles, meaning clipping can be nested over several function calls always clipped to the previous rectangle to prevent children from drawing outside their parent's client area.

I'm now even more convinced that the theme manager should do the cutting, to use one skin_besch_t* member for all theme images (because it is only used at PAK load and never again) and keep track of the image numbers directly for drawing. All this contributes to a simpler way to define the graphic, more freedom to the artist and continue building on the already used system in Simutrans (image ID).
Title: Re: [Project] GUI Theme
Post by: prissi on October 24, 2013, 09:42:56 AM
You are convinced to cut the images in Simutrans, Me and also Dwachs adviced agaist. Either adhere to this advice, or we can only agree that we disagree.

I cut the images in makeobj, and it took me less than 10 minutes compared to the time it took me to draw them it is nothing. With color lines it would be even easier to cut, but ok, cutting by hand works fine too.

The GUI elements are object oriented, the drawing is not. At a certain points there will be a break, since the OS is not object oriented (apart for Zeta/BeOS). In simutrans all objects themselves call display_xxx functions to do their drawing is a routine called display or zeichnen. Doing different in the GUI from all other objects in the game will add to confusion.

I also fail to see how adding another layer will make things more simple: I compare

display_stretch_image( gui_theme_t::imagename, place )

to

theme_manager->display_element( GUI_MAGIC_NUMBER, place );

One magic parameter to get the image information, and one location. Only that the second code jumps through some hoops to finally call the first function anyway.

And stacking clipping works quite well, otherwise the objects on scrollpanes would not clip. They exactly clip their children. But maybe I misunderstood again.

The only critic on my patch so far from Markohs was using too long constants which I shortened. Well I fixed this. I am happy to here some other critice apart from "Well that is boring like the rest" It is ment to be like the rest.

But this is going in circles now for so long now. It would nice if there is a decision, since otherwise Max-Max and me are not getting happier.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 24, 2013, 05:28:51 PM
I think we need to break down this in small steps because I'm not sure you have understood the purpose of the theme manager or I'm not understanding what you try to replace it with. I think I have explained this many times before and all I can do is to try one more time.

What is a theme element?
A theme element is is the graphical visualisation of a whole GUI control or a part of it. Several GUI controls can share the same graphical theme elements. One example of this might be all GUI controls with a frame. A button use the frame as a background and lays text on top of it. A group box can use the same frame and put text in the upper corner. The window has a frame defining its borders. An edit control has a frame, listbox, combobox etc... So the frame in this example is an element of a control's graphical visualization. Another theme element can for example be a symbol drawn inside a button. The basic idea is to let all GUI controls have their own theme images, but many times they can share the same images and in this case doesn't need to be specified at all.

The theme element itself can be mad up of 1 to 9 images for frames, or even more if it is a more specialized GUI element. All these images doesn't need to be specified or cut by the artist, nor does the GUI control itself need to know what images to use or how many they are.

Where does the skin enum fit into all this?
The skin enum identifies the individual graphical images in the PAK file. In the end there should be enough to only define one image per control and state, meaning less SKIN_XXXX enums than now. A theme element can be an aggregation of several skin images but identifies an element by one THEME_ID_XXXX enum as a whole, regardless of how many images it was composed of. The internally cut images doesn't need any enum because they are created and managed by the theme manager and doesn't need an enum for each little individual image.

What is an element rule?
A button with a rectangular theme element can be sized both horizontal and vertical to fill the bounding box and this works fine as long the theme element is made for this. But as you said yourself in the artist theme forum (http://forum.simutrans.com/index.php?topic=12522.msg124101#msg124101), it doesn't work for rounded buttons. To solve the fact that some design can handle both horizontal and vertical and some can't, the artist/user can if he wish, apply a rule that tells how the theme element is drawn. At this moment there are 4 rules available: Horizontal, Vertical, Symbol and Frame (both Horizontal & Vertical).

The Horizontal rule
Even if the GUI control change in both directions (vert and horiz), it will centre the element vertically and only size it horizontally left-right in the control's bounding box.

The Vertical rule
Even if the GUI control change in both directions (vert and horiz), it will centre the element horizontally and size it vertically top-bottom in the control's bounding box.

The Frame rule
When the GUI control change in both directions (vert and horiz), it will size it both horizontally and vertically to the control's bounding box.

The Symbol rule
Even if the GUI control change in both directions (vert and horiz), the element will not change in size at all, instead it is centred both horizontally and vertically in the controls bounding box. This will for example be used in gadgets and toolbars.

Further down the road I have an idea of be able to add different resolutions of the same symbol and the theme manager will pick the one best suitable for the requested bounding box size. Before you star to tell me how ridiculous this is, this is only a brain storm thought to keep high quality on both low and hires screens. I believe you can compare it to mipmaps (http://en.wikipedia.org/wiki/Mipmap) and windows has been using this technique for decades in their icons. I will also make it clear that this wouldn't be mandatory, it is up to the artist!

So the GUI control is still drawing itself in the ziechnen() function but use the theme manager as a service to draw the elements it is built up by. It still draws the text and other non-theme related details. It can even layer several theme elements. For example a tool button first draws the theme for tool buttons and on top of it the theme symbol. The symbol will automatically fit in the button and even increase resolution if supported and needed. All this without the GUI control's know how.
Because the artist/user can specify one of the above 4 drawing rules for a GUI control, it doesn't know what images to use and how to use them, it always draw itself the same way regardless of this. This is where the theme_element_t base class comes in. This is the base class for all the 4 rules and are created when the theme PAK loads.

(http://forum.simutrans.com/index.php?action=dlattach;topic=11956.0;attach=22749)

This is somewhat how the GUI control and theme manager cooperate:

(http://simutrans-germany.com/files/upload/ThemeManager.png)

The actual drawing is done in the derived element class' virtual function display(). By this approach, the GUI control itself can call the same function regardless of what rules has been applied.

I have several times also stated that none of these patches has been the full theme system, it is still in development and more things will come. I did the huge mistake to believe that I could submit work in progress. I know better now and first we need to clean up the mess that this has become to be, before I can carry on and then submit a completed theme patch.


You are convinced to cut the images in Simutrans, Me and also Dwachs adviced agaist. Either adhere to this advice, or we can only agree that we disagree.
I cut the images in makeobj, and it took me less than 10 minutes compared to the time it took me to draw them it is nothing. With color lines it would be even easier to cut, but ok, cutting by hand works fine too.
Cutting all images in makeobj you still end up with a all the magic numbers you thought needed to be specified from the beginning (27,36 and 93) to find these images in the PAK file. By cutting them in the manager you only need one image and no more magic numbers because the manager knows best where they are located. If the User wants to use another rule the manager can cut them different or prepare them in another dynamic way at load. Sure this can be done if they are pre-cut, but first the image needs to be reassembled (well for images with cut lines this is needed anyway)...

The GUI elements are object oriented, the drawing is not. At a certain points there will be a break, since the OS is not object oriented (apart for Zeta/BeOS). In simutrans all objects themselves call display_xxx functions to do their drawing is a routine called display or zeichnen. Doing different in the GUI from all other objects in the game will add to confusion.
I have explained this so many times now; the GUI is still drawn in the zeichnen() routine, exactly how can this be confusing and for whom? Why isn't a call to display_ddd_proportional_clip_cl() or any other function also confusing?

I also fail to see how adding another layer will make things more simple: I compare

display_stretch_image( gui_theme_t::imagename, place )

to

theme_manager->display_element( GUI_MAGIC_NUMBER, place );

One magic parameter to get the image information, and one location. Only that the second code jumps through some hoops to finally call the first function anyway.
It is about encapsulation, to isolate the theme responsibilities. If you study the code carefully you will see that display() is a pure virtual function and it is the derived implementation that is called. Since the artist/user can define this behaviour for each element, the GUI control doesn't know what Display() function to call. The right implementation of Display() is called through polymorphism. If the requested element is missing the theme manager can substitute it or draw a proxy instead. By putting this logic in the manager, we don't need to do this in each GUI control.

And stacking clipping works quite well, otherwise the objects on scrollpanes would not clip. They exactly clip their children. But maybe I misunderstood again.
The stacked clip routines in the manager is cascading, meaning all pushed clip rectangles are clipped against the previous pushed rectangle. This prohibit a any child clip region to draw outside the parent's clip region.

The only critic on my patch so far from Markohs was using too long constants which I shortened. Well I fixed this. I am happy to here some other critice apart from "Well that is boring like the rest" It is ment to be like the rest.
But this is going in circles now for so long now. It would nice if there is a decision, since otherwise Max-Max and me are not getting happier.
Back in the early days we saved code space by using short names, because we had limited amount of memory and the customer paid per line of code. This also created a lot of cryptic acronyms only known to the initiated.
Today when the memory isn't an issue any more and cut&paste operations goes easy and fast, there is no need to shorten stuff down. Of course some common sense has to be used and using_whole_sentences_as_names should be avoided.
I have used a namespace like nomenclature to organize the skin and theme elements into a logic structure. I'm not saying it is the best but this is my explanation to why it was implemented the way it was.

It seems like I have failed to explain the virtual Display() function and why it is implemented the way it is. MAybe some one else can explain this polymorphic construction better than me.
I only did the mistake to share my thoughts and code to early, when it is still in development and everything doesn't make 100% sense yet, due to unwritten code that will be developed further down the road.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 24, 2013, 07:04:59 PM
I took the time to read your description fully now and I like the design. Just some questions, and not related to if this is included in simutrans or not, because we already know the status of that.

 Why is text handled not as theme_element_t? Can't it be abstracted as a text_element_t?

 I share some of prissi's thoughts respecting zeichnen and virtual calls, but not for the same reasons that him, I think. I just think as I told you before the process you describe in zeichnen should be named "generate_primitives", called on window update, that generates a list of the primitives to draw. Anyway, not having that infrastructure in our project, your solution is good enough, and easily refactorable to the one I propose, in the future.

 I also understand and share your comments about encapsulation and responsability isolation.

 About magic numbers, when I looked at that section of the code, it just understood it's an enumeration of frame classes, I don't really know what's so magical about them. But I might not have understood it fully, I guess. They just look like handlers. :)

 Well, about the code, my personal advise is that if you feel that you want to do this, and it ends not being accepted or too modified, you can allways create your own fork of simutrans in github, and implement it. Once you have it finished and working, maybe the community changes his oppinion. I made a fork the other day to learn how git works, and quite easy to work with, you lose nothing trying.

 And to prissi, I'd just suggest another way of handling this. Just give green light to Max-Max to implement this on his way, and when it's finished, if you don't like it, you can allways rollback his changes and change his code. Looking how things are, looks like it's the only realistic option we have now. Seems like prissi and Max-Max getting an agreement is almost impossible.
Title: Re: [Project] GUI Theme
Post by: Ters on October 24, 2013, 07:45:35 PM
And to prissi, I'd just suggest another way of handling this. Just give green light to Max-Max to implement this on his way, and when it's finished, if you don't like it, you can allways rollback his changes and change his code. Looking how things are, looks like it's the only realistic option we have now. Seems like prissi and Max-Max getting an agreement is almost impossible.

Roll back? If it's committed to trunk, I'm pretty sure it won't be rolled back. If it's done, it will likely be done by rolling back all revisions on trunk since the GUI "went in the wrong direction", baby, bathwater and all, and starting over from there. Trying to roll back changes from a multitude of individual commits interspersed with other changes that should not be rolled back is simply too much work.

This is what branches are for, but merging such a branch back into trunk is no different than a big patch. It's a bit easier for others to follow what's going on, though.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 24, 2013, 07:57:38 PM
Ofc it's not so easy as pressing two buttons. But it's not rocket science, it's just code. But well, you are probably right, a branch is better suited for this.
Title: Re: [Project] GUI Theme
Post by: prissi on October 24, 2013, 08:02:46 PM
Yes, I think getting an agreement is impossible.

The sole purpose of gui_frame_t is to assemble gui_elements in their positions. The drawing is entirely up to the elements. So what do I gain by having another layer, which is called to do the drawing?

You say the elements should have rule. Fine, but then these rules (or its positions) need to be changed in gui_frame_t (and within the element) to reflect the actual positions. Or you can click outside a button and still trigger it, which is not what should happen.

So what does the theme manager service provides in the end? Something like a graphic primitive to draw a button with alignment out of nine (or how many) images, and maybe labels. I fail to see the need for another layer.

If you really want a radical new GUI, one should rather go to a portable GUI lib, which would be better integrated into the OS anyway. Maybe even use Java, since with the dominance of Andriods, a Java frontend might became handy anyway.

But as Markohs said, go ahead. I keep the patch in sync, and I may make some other skins for my patch. But those are easily reused for whatever is applied in the end.

I would start to separate the buttons into different classes, but that will give quite lots of conflicts, until this is resolved. SO I may go back on the scrolled lists.
Title: Re: [Project] GUI Theme
Post by: Ters on October 24, 2013, 08:12:51 PM
But it's not rocket science, it's just code.
I actually wish it was rocket science. That could be fun.
Looks like I should stop holding my breath waiting to see if the new GUI would get rid of the Go to depot button bug.
 
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 24, 2013, 11:35:23 PM
I took the time to read your description fully now and I like the design. Just some questions, and not related to if this is included in simutrans or not, because we already know the status of that.

 Why is text handled not as theme_element_t? Can't it be abstracted as a text_element_t?
Sure it could be handled just like any other theme element but I have no intentions at this time to do this. But I see your thought here and it is an interesting design proposal to even abstract away the theme from the GUI control further. Maybe it would be more beneficial if we have hardware support and text can be done in the GPU. Let us all put that thought back in our heads to see if it grows...  ;)

I share some of prissi's thoughts respecting zeichnen and virtual calls, but not for the same reasons that him, I think. I just think as I told you before the process you describe in zeichnen should be named "generate_primitives", called on window update, that generates a list of the primitives to draw. Anyway, not having that infrastructure in our project, your solution is good enough, and easily refactorable to the one I propose, in the future.

 I also understand and share your comments about encapsulation and responsability isolation.
Sorry, I forgot to comment you on that one.
Well, as for now the manager is only dealing with images, not primitives like rectangles or circles. I guess the images would be textures in a design using the GPU later on.
But as you pointed out, we don't have such system in place and with this abstraction it wouldn't be too hard to modify the theme manager to work in this way.

About magic numbers, when I looked at that section of the code, it just understood it's an enumeration of frame classes, I don't really know what's so magical about them. But I might not have understood it fully, I guess. They just look like handlers. :)
The THEME_ID_XXXX is a way for a GUI control to tell the theme manager what theme element to draw. The manager is mapping the requested theme ID (or handler if you prefer this term) to the actual instance of the derived theme_element_t class. Because the manageris doing the mapping, because it knows what is available, several THEME_ID_XXXX may use the very same instance (if they draw the same graphics and rule). The instance may also end up in reusing the same small cut images if they use the same graphics, but different rules.

Well, about the code, my personal advise is that if you feel that you want to do this, and it ends not being accepted or too modified, you can allways create your own fork of simutrans in github, and implement it. Once you have it finished and working, maybe the community changes his oppinion. I made a fork the other day to learn how git works, and quite easy to work with, you lose nothing trying.
I'm mostly used to use TortoiseSVN and the patch thing is nothing I have used before until now. Even if I know how to update my local tree, I still have some difficulties sometimes to keep in synch. To use Github would probably slow me down even more, if I don't fail completly  :o

You say the elements should have rule. Fine, but then these rules (or its positions) need to be changed in gui_frame_t (and within the element) to reflect the actual positions. Or you can click outside a button and still trigger it, which is not what should happen.
If you look into my original patch you will out that there is a virtual member:

virtual scr_rect  get_client ( void ) = 0;

This returns the element's client rect, adjusted to the element's current rules so hit test can be done properly. So, yes, I have thought about this too. The filter button is using this to position the text, still implemented more like a proof of concept to work with the old skin format.

So what does the theme manager service provides in the end? Something like a graphic primitive to draw a button with alignment out of nine (or how many) images, and maybe labels. I fail to see the need for another layer.
Try to read my previous post again, where I explain what it does. There are in fact several post where I explain this.

...since with the dominance of Andriods, a Java frontend might became handy anyway.
Just a side note, you can develop in C/C++ on Android, you need to use the official NDK (http://developer.android.com/tools/sdk/ndk/index.html).

But as Markohs said, go ahead. I keep the patch in sync, and I may make some other skins for my patch. But those are easily reused for whatever is applied in the end.
Okay so, how do you want me to do this. Develop everything into one big beta patch for testing, or smaller chunks, even if you don't see the full context of it as long it doesn't break anything?

I would start to separate the buttons into different classes, but that will give quite lots of conflicts, until this is resolved. SO I may go back on the scrolled lists.
This is the path that lead me to the theme manager.

I started with the dialogue TITLE_HEIGHT thing and discovered that most dialogues where using hard coded numbers and even GUI functions that should be its own class. I came to the conclusion that I need to restructure the GUI classes to make better use of them.

So I started to look at the GUI, trying to make use of polymorphism and create the GUI controls that weren't GUI objects, but should have been. So In order to do this, since all GUI controls should be themed, I started with the theme manager so I can use it when I restructure the GUI classes.

...and it is here we are now...
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 25, 2013, 08:48:24 AM
Max-Max, thank you for explaining your idea about the themes. It is a well-thought concept imho.

Let me rephrase it to see whether I understood it right. You are proposing an extra layer of theme-elements that handle the display of gui-components frames. The idea behind this is to have a unified way of displaying those frames. This has potential (like buttons that could handle different font sizes ?). But I share prissi's concern: Where this is useful besides using this for the button classes and window frames? I mean, which of the components in gui/components would benefit from the theme layer?

I agree with you about the need for more gui-components (for instance to take care of texts in a way that switching languages does not make the gui look messy). If this theme stuff is the price to pay to get gui-code refactored, better maintainable, easier exentable (different font size, no absolute pixel coordinates) etc. I am willing to pay it.

The way you described it, this theme thing consists of two fairly independent parts: First, the communication gui component <-> theme classes, and second, the communication theme manager <-> pak files/ besch system. Both are controversial, as the need for the theme manager is discussed as well as the structure of a potential new pak/besch/cutting system.

My proposal would be the following: Could you provide an updated patch(1) that contains the theme-related code, implements the theme for the gui-components, and does not introduce a new pak/cutting system (ie which uses the existing skinverwaltung stuff for compatibility)? That way we would have a smaller patch to discuss. Maybe you posted such a patch earlier - I did not notice as I did not follow this topic from the very beginning.

For development, I suggest to you to use git: mirror the simutrans-project at github: github.com/aburch/simutrans . This tool has a learing curve ofc, but it is so much better in handling branches than svn. I myself started with developing against a checked out svn repository. But then switched to git to develop larger patches (for instance the scripted scenarios).

(1)A patch that contains that contains exactly one feature: the theme manager and its relation to the gui components. No white-space changes in unrelated files, no debug code for makeobj, no change to resource file etc.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 25, 2013, 09:45:47 AM
Well, as for now the manager is only dealing with images, not primitives like rectangles or circles. I guess the images would be textures in a design using the GPU later on.
But as you pointed out, we don't have such system in place and with this abstraction it wouldn't be too hard to modify the theme manager to work in this way.

 Indeed a image in your current code whould be 2 triangles with a texture applied in a 3D world.
(http://meandmark.com/blog/wp-content/uploads/2013/01/Quad-Example1.png)

 You can generate a hardware vertex buffer (http://en.wikipedia.org/wiki/Vertex_Buffer_Object) when the frame is created, and just keep it updated when changes come to the frame, using a texture with all the theme images on it, a atlas (http://en.wikipedia.org/wiki/Texture_atlas).

Example of an atlas:

(http://brain.wireos.com/wp-content/uploads/sprites2.png)

 If you have the hardware vertex buffer updated, given it's physically stored on the video card memory, with the texture atlas, drawing it costs almost 0 CPU, as it's done entirely by the GPU.

 The only problem is keeping that buffer updated, that's a IO-dependant iperation (travels by the PCI bus), and shoudn't be done each frame, just from time to time, when it's really needed.

 Rendering text it's done in a similar fashion, you load the fonts in the texture atlas and map the letters to objects.

 You are not designing that now, I'm just asking you to have in mind that idea is going there when we can, so try to avoid decisions that go against this idea.
Title: Re: [Project] GUI Theme
Post by: prissi on October 25, 2013, 12:28:22 PM
I think this is rather how display_img must work, since it is low level drawing.

Since we only use handles (image ids) I think the exchange to a different drawing mechanism is the task of simgraph and not some upper GUI layer.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 25, 2013, 03:25:40 PM
Let me rephrase it to see whether I understood it right. You are proposing an extra layer of theme-elements that handle the display of gui-components frames. The idea behind this is to have a unified way of displaying those frames. This has potential (like buttons that could handle different font sizes ?). But I share prissi's concern: Where this is useful besides using this for the button classes and window frames? I mean, which of the components in gui/components would benefit from the theme layer?
Buttons and frames was only examples because they are simple and easy to understand, the system is meant to handle all theme related drawing, as a service to all GUI controls. The purpose is to let the GUI control to focus more on its function and less on theme adaptation, meaning a simpler way of drawing in the GUI control. The theme manager takes care of adjustments against the current selected theme.

I agree with you about the need for more gui-components (for instance to take care of texts in a way that switching languages does not make the gui look messy). If this theme stuff is the price to pay to get gui-code refactored, better maintainable, easier exentable (different font size, no absolute pixel coordinates) etc. I am willing to pay it.
With small screens in mind the priority for a dialogue should be to not resize the dialogue to its content. This would have the effect that it might take up the whole screen and extend beyond it. Instead the dialogue content has to adapt to the given space by its parent. For this I proposed the collapse system that will resize children with focus on user interaction. This means that cosmetic GUI elements are likely to collapse first to give space for elements that are user interactions. For a normal Desktop this isn't a problem and collapsing will only happen if the user shrink the dialogues to much. The collapse system is described in this, somewhat, outdated document (http://mkdevelopment.se/simutrans/SimutransTheme.pdf). This document can also be found in the very first post of this thread, under "project documentation".

Regarding text, it is truncated to its parent's client area, displaying an ellipse sequence to indicate truncated text. This will guarantee that all text stays inside the client and does not spill over. This is already in place for the most GUI controls. Again, this sin't really a problem on a Desktop but still handles the different lengths between languages. If you happen to select a language with generally longer strings, you only need to resize the dialogues until the ellipses disappear.

I have not put so much further thought about text, but it is an interesting idea to adapt the default button size to the most common button text length. The calculation of the adapted text length would be in the translator I guess and the theme manager can use this information to calculate the default button size, because the frame thickness also has to be in the mix.

The way you described it, this theme thing consists of two fairly independent parts: First, the communication gui component <-> theme classes, and second, the communication theme manager <-> pak files/ besch system. Both are controversial, as the need for the theme manager is discussed as well as the structure of a potential new pak/besch/cutting system.

My proposal would be the following: Could you provide an updated patch(1) that contains the theme-related code, implements the theme for the gui-components, and does not introduce a new pak/cutting system (ie which uses the existing skinverwaltung stuff for compatibility)? That way we would have a smaller patch to discuss. Maybe you posted such a patch earlier - I did not notice as I did not follow this topic from the very beginning.
Yes, it is about encapsulation and unifying handling. My original patch was still using the current skin-PAK system as a base and added more flexibility. You can still use the "old" skin images. I originally even used the skin object in the .dat file to be 100% compatible. Prissi added the new theme object and removed the old skin object. Since I had plan to do this myself further down the road I kept the theme object, so all you need to do is a small edit in the theme .dat file, change the object from skin to theme. However after that Prissi started to ad a new object for each GUI element, and because the object itself is only used at PAK load it made things a lot more complicated and extra work if new elements where added in the system.

In my original patch I had changed everything back to use only one theme object for all elements. There is no support for cut lines, but the concept has been brought up to spread light on why things are done as they are. the cells are used as vertical cut lines as a way to be compatible with he current skin system with the addition that one, two or three cells can be used, depending on how many cut lines you want to use. the remaining undefined cuts are handled by the theme manager.

For development, I suggest to you to use git: mirror the simutrans-project at github: github.com/aburch/simutrans . This tool has a learing curve ofc, but it is so much better in handling branches than svn. I myself started with developing against a checked out svn repository. But then switched to git to develop larger patches (for instance the scripted scenarios).
Well, I did installed and tried to fork the experimental and had somewhat success. I found a TortoiseGIT but the nomeclature is quite different from SVN so I didn't understood really how to do the things I'm used to do in SVN.

(1)A patch that contains that contains exactly one feature: the theme manager and its relation to the gui components. No white-space changes in unrelated files, no debug code for makeobj, no change to resource file etc.
Maybe we should try to stabilize the current patch before I star to mess around with GitHUB, I can try to isolate the stuff into smaller and more defined patches or do we want things forked first? How does it work on gitHub, should I create patches or just announce a revision for review?
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 25, 2013, 03:31:53 PM
...a atlas (http://en.wikipedia.org/wiki/Texture_atlas).
Yes, I'm familiar with the atlas concept...

You are not designing that now, I'm just asking you to have in mind that idea is going there when we can, so try to avoid decisions that go against this idea.
Yes, I will agree with Prissi here, this is on a low level and might be better off to implement in the low level layer if display_img_XXXX.
But I will keep this in mind for further design...
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 25, 2013, 05:50:26 PM
Split the posts about git & friends, please continue the git related discussion here:
http://forum.simutrans.com/index.php?topic=12770
Title: Re: [Project] GUI Theme
Post by: prissi on October 26, 2013, 08:18:02 PM
Ok, the latest version with scaleable buttons is now at github: https://github.com/prissi/simutrans/tree/scaleable-gui It is essentially the one above, only with the images.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 26, 2013, 10:13:32 PM
Wait, wait, wait.... What's going on her?

Is this Githhub link the one I should use, or should I do one of my own?
I'm in the middle of trying to restore my patch to what it once where, I thought we all agreed on letting me do my design?
Title: Re: [Project] GUI Theme
Post by: prissi on October 26, 2013, 11:12:07 PM
Now really. This is just the patch I made earlier, on a personal branch in github (as was suggested in the other thread). Nothing changed there, just instead of a patch file a branch which contains also the graphics.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 27, 2013, 12:12:10 AM
Now really. This is just the patch I made earlier, on a personal branch in github (as was suggested in the other thread). Nothing changed there, just instead of a patch file a branch which contains also the graphics.
Hmm, it sounded worse than I meant  :-[

I was just wondering if that was the GitHub I should use or if I should fork a new one, from the standard?
Title: Re: [Project] GUI Theme
Post by: Dwachs on October 27, 2013, 08:18:09 AM
if I should fork a new one, from the standard?
you should fork a new one, from the aburch/simutrans repository. This is the semi-official git-repository, which is continuously updated against the svn repository. Prissi registered moments ago at github and started his branch very recently ;)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 27, 2013, 11:40:27 AM
Prissi registered moments ago at github and started his branch very recently ;)
So this means we are two developers developing the same thing in parallel, on different implementation paths...  :o
Title: Re: [Project] GUI Theme
Post by: Ters on October 27, 2013, 12:47:46 PM
So this means we are two developers developing the same thing in parallel, on different implementation paths...  :o

It's not the first time that's happened in open source. In fact, Git and Mercurial were both written in parallel to become the replacement VCS for Linux.

But as I read it, it's only the branch that is new. The changes in it is old, and something prissi apparently has shared with us earlier.
Title: Re: [Project] GUI Theme
Post by: kierongreen on October 27, 2013, 01:42:09 PM
I would also interpret this as prissi indicating this is the expected starting point for future patches. i.e. git branch is the planned implementation.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 27, 2013, 05:48:25 PM
It seems like I have managed to restore my patch, at least it compiles again. I think I have managed to keep all the other updates that was made.

I have to convert the theme colour loading to the new colours system with RGB, then I might be able to isolate the patches a bit.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 29, 2013, 01:09:38 PM
Some advice needed...

To my understanding we are going to move away from colour index to use the direct RGB565 value instead. I need to store the system colours somewhere and since we use direct RGB valuse I don't need to add them into the same index table as the other special colours.

There is a simcolor.h only with colour defines. Wouldn't it be logical to use this module for colour management, storing colour tables etc... Display.h has grown quite big and imho should only contain low level implementations.

So the question is; should I put my system colour storage + conversion routines in a simcolor.cc ?
Title: Re: [Project] GUI Theme
Post by: prissi on October 29, 2013, 01:21:34 PM
One can indeed argue that color management can go into its own module. But on the other hand the display routine access the color tables a lot, so the data needs these as globals (as they are now as well). It could as well have the infrastructure for conversion etc. I would place such a file still in display though, since it is low level.

Since this is somewhat a little away from the topic of GUI, perhaps better continue this in a new thread.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 29, 2013, 01:26:55 PM
It can still be global, just placed in its own module. I'm touching this subject here because the theme manager is reading in the system colours from the theme and my first implementation stored this in the theme manager itself.

With the new RGB system I need to change my implementation and I thought this can go into a global array of PIXVAL. I don't intend to move around anything from the simgraph, but if we are to move over this I can do my implementation in a simcolor.cc instead of putting in more stuff in simgraph...
Title: Re: [Project] GUI Theme
Post by: prissi on October 29, 2013, 01:34:31 PM
Then do a patch which moves this to simcolor.cc first. (I would not use an array though, I recommend to use single variables.)
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 29, 2013, 01:35:42 PM
Then do a patch which moves this to simcolor.cc first. (I would not use an array though, I recommend to use single variables.)
Why single variables?
Title: Re: [Project] GUI Theme
Post by: Ters on October 29, 2013, 04:36:20 PM
Why single variables?

Avoiding magic indicies is one good reason I can think of. Even if the indicies are defined in an enum, I don't think a debugger will do a reverse look up.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 29, 2013, 07:36:52 PM
Avoiding magic indicies is one good reason I can think of.
To collect them in an array prevents that new system colours are put in different places.
If we decide to change the type, it is easier to maintain.
One legal way to remove magic numbers is precisely to use enums or constants.
If we further down the road decides to turn this into a class, the operator[] can be used so we don't need to change "everywhere".

Even if the indicies are defined in an enum, I don't think a debugger will do a reverse look up.

Yes, the most debuggers do this, at least the ones I have been using, both PC and embedded.
Title: Re: [Project] GUI Theme
Post by: Ters on October 29, 2013, 07:53:42 PM
Yes, the most debuggers do this, at least the ones I have been using, both PC and embedded.

For array indicies? Variables can be typed to the enum, so that's expected, but that debuggers know which arrays use which enum, if any, as indicies is something I did not expect.

To collect them in an array prevents that new system colours are put in different places.

Why is that a problem? It can in fact be an advantage, as it restricts the ability to parasitize on other existing system colors when one rather should define one's own. But, yes, it's a double-edged thing, which can also interfere with legitimate sharing of settings.
Title: Re: [Project] GUI Theme
Post by: prissi on October 29, 2013, 09:38:00 PM
When I learned programming (which was more like 30+ years back I have to admid) then the purpose of any data structure is to collect data that is used together. However, using a text color does not mean I will use the player color next. So I fail to see an intrinsic connection between these data.

In the code I would still use symbolic constants HIGHLITE_TEXT_COLOR and the like, since the predefined COLOR_RED (and complemented by RGB_RED maybe) is still easier to see (and type) than simcolor_t::gui_color[TEXT_HIGHLITE].

Finally an array is prone to errors: You may end up using ints or whatever (TEXT_HIGHLITE+1) which could later get you into trouble. So save practice is to avoid the unnecessary array.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 29, 2013, 10:52:40 PM
Well, I have a complete different view of this, how this in the end can be turned into a colour list object further down the road. But I guess "This isn't the Simutrans way", so I will rip out my RGB system colour code because I can see that no one would ever consider to implement it...
Title: Re: [Project] GUI Theme
Post by: Ters on October 30, 2013, 06:22:49 AM
For me, it's not that it isn't the Simutrans way (arguably, it very much is), it's just that I haven't seen any arguments making a monolithic master array a better choice. There can certainly be compelling arguments for it, but I can only speculate what they are.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 30, 2013, 02:45:08 PM
Thy are all colours, the same type of data, used in the same way. If we are to create a colour manager that can operate on a list of colours, regardless of what they are used for, some sort of list is needed.

An array can be turned into an object seaming less via the index operator[]. A colour manager can operate on the list such as blending colours, create colour ramps etc... It would also allow a system where the artist can define their own colour ramps (as I proposed in another thread).

If they where to be separate variables, they would still be defined and manipulated in the same spot by the same code anyway. To do an operation on several colours would mean that each colour variable has to be hard coded, and easily forgotten when new are added.

Think colour as in A colour that can be manipulated and organised, not its actual colour, purpose or use...
Title: Re: [Project] GUI Theme
Post by: Ters on October 30, 2013, 03:51:14 PM
A colour manager can operate on the list such as blending colours, create colour ramps etc... It would also allow a system where the artist can define their own colour ramps (as I proposed in another thread).

If they where to be separate variables, they would still be defined and manipulated in the same spot by the same code anyway. To do an operation on several colours would mean that each colour variable has to be hard coded, and easily forgotten when new are added.

Color ramps should perhaps be a distinct class, regardless of how everything else is solved.

As for blending colors, I would think
Code: [Select]
result = blend(my_color, BLACK, 50%)
is more flexible than
Code: [Select]
color_manager.set(MY_COLOR, my_color)
result = color_manager.blend(MY_COLOR, BLACK. 50%)

There could be a color manager to load some special_colors.dat file, rather than have color definitions scattered among configurations for components and what not. But once loaded, operations like blending should be possible regardless of whether the colors are from there or not. Reading colors out of that color manager into other long term variables (like member variables and globals) will probably be trading space for very little benefit.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 30, 2013, 05:10:47 PM
The idea of a colour manager isn't only to get a specific colour, it is also to encapsulate colour handling. When I request a colour, I don't need to know if it is a night/day colour, factory colour, player colour, animated colour etc... If the colours are ordered in internal lists, the colour manager updates them when needed. The colour ramp is hidden inside the colour object hence you only need to get a specific colour, nothing else.

The manager updates the internal colour on every animation tick, season tick, day/night, specific clock interval etc... Have some visions and think forward of what we can have. How ever my point is that if they are collected in arrays, these can later on be turned into objects.

Well, but I guess this is too object oriented for Simutrans, so we stick with variables all over the place instead... I will rewrite my already functioning colour code...
Title: Re: [Project] GUI Theme
Post by: Ters on October 30, 2013, 06:48:43 PM
The idea of a colour manager isn't only to get a specific colour, it is also to encapsulate colour handling. When I request a colour, I don't need to know if it is a night/day colour, factory colour, player colour, animated colour etc... If the colours are ordered in internal lists, the colour manager updates them when needed. The colour ramp is hidden inside the colour object hence you only need to get a specific colour, nothing else.

The manager updates the internal colour on every animation tick, season tick, day/night, specific clock interval etc... Have some visions and think forward of what we can have. How ever my point is that if they are collected in arrays, these can later on be turned into objects.

I rather believe things would be much more clear if there was a color manager for each type of color. Only when doing indexed colors in images is it a necessary evil to combine everything into one list, or rather one list per player (though only one of the lists exists at any one time).
 
The one asking for a color must know what kind of color it's asking for. If your doing GUI, you don't normally want a color that's changing with the day-night cycle. When asking for a player color, you have to specify which player. It's apples and oranges.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 30, 2013, 09:41:23 PM
If there was a colour list object, then there could be one instance for each type of colours; player, system, gui, tiles etc...
I never said that ALL colours should be in one single list...

But I will remove this from my code...
Title: Re: [Project] GUI Theme
Post by: prissi on October 30, 2013, 11:18:18 PM
In order to make Simutrans a little more tablet enabled (and for those with single button mouse), I enabled dragging with the left mouse button, if the query tool "a" is active. (I could make it that any non-dragable tool will activate world dragging but I am not sure this will cause more confusion.)
Title: Re: [Project] GUI Theme
Post by: Ters on October 31, 2013, 06:00:05 AM
If there was a colour list object, then there could be one instance for each type of colours; player, system, gui, tiles etc...
I never said that ALL colours should be in one single list...

Tiles are images, they are not colors (they may contain player colors and lights). Apart from that, and the fact that the GUI (ab)uses colors meant for the world, Simutrans already has this. Even the list with all colors. It's an hierarchical thing, with a manager for player colors, a manager for lights, and a manager combining this into one list along with all possible colors, using one set of player colors, and applying day/night darkening. With the exception of player colors, none of this is of relevance to the GUI. Doing something to this code strewn through simgraph?.cc so that it's easier to follow is a good idea, but that is almost wholly off-topic for a GUI theme discussion.
Title: Re: [Project] GUI Theme
Post by: prissi on October 31, 2013, 01:31:17 PM
I though so too, that this is fairly independent from the ongoing discussion. Hence the suggestion to make an independent patch. As a first step I would just collect the working code though.
Title: Re: [Project] GUI Theme
Post by: Max-Max on October 31, 2013, 03:22:24 PM
It is relevant because the GUI uses system colours that needs to be loaded somewhere by the theme manager.

I have an idea and vision of what can be done with such a colour object, giving the artist more possibilities than now. But this is the wrong thread to discuss this. My point was originally that an array can easily be turned into an object further down the road. If colour management is never to be updated there is indeed no point make a transition to object oriented management easy...

How ever, as I said, I will rip out the colour loading I have now and put back all the variables.
Title: Re: [Project] GUI Theme
Post by: Markohs on October 31, 2013, 05:36:03 PM
I suggest just implement it with the current trunk code (not your GUI patch, just current trunk with the proposed change), and post it as a independent issue. If it's worth it and improves current simutrans in any way, who whould say no.

 But only if you decide it's worth doing it or not. :)
Title: Re: [Project] GUI Theme
Post by: Ters on October 31, 2013, 06:00:09 PM
For those interested, here's a topic on how colors are handled in Simutrans: http://forum.simutrans.com/index.php?topic=12796.0
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 04, 2013, 03:29:07 AM
I have honestly tried to make a theme manager patch with the utter most essential files included so it can compile and run. If you want a smaller patch than this, I have to chop it up in smaller pieces that won't compile because of missing updates...

Even if this is the bare minimum, you need the simstring patch I posted here (http://forum.simutrans.com/index.php?topic=12806.msg127106#msg127106)

*** DO READ THIS BEFORE COMMENTING ON THE PATCH ***
1. ThemeManager_Part1 This is the bare minimum to make it compile. A smaller patch will not compile without errors.
2. The colour update isn't included 100%, only files that are needed for the theme manager to compile are included. The result is that when run, all colours are screwed up because they expect an RGB value but get an index instead. ThemeManager_Part2 will contain the colour update for the remaining theme related files. I will post Part 2 shortly...
3. No, I have not done anything about the dialogues yet. To be able to post one patch for each dialogue, we need the theme manager in place first... I will get right to it as the next thing on the list...
4. Do not rewrite the code before we have discussed it!
5. Do not rewrite the code before we have discussed it!
6. Do not rewrite the code before we have discussed it!

Theme Manager Part 1 (http://simutrans-germany.com/files/upload/ThemeManager_Part1.zip)

For a quick test, use the theme files I posted earlier. Drop them into Simutrans/themes

-"The theme pak format is back to the old format, you will need these new ones. I have built both default and aero in this archive ready to drop in and use.
Ready to use theme paks (http://simutrans-germany.com/files/upload/ThemPaks.zip)

Here are the photoshop source to the themes
New aero theme source (http://simutrans-germany.com/files/upload/aero_theme_source.zip)
New default theme source (http://simutrans-germany.com/files/upload/default_theme_source.zip)
"


These themes are for reference, I'm sure Prissi will replace them with his version...
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 04, 2013, 04:01:22 AM
This is part 2 of the theme manager patch with the remaining update for rgb colours (only theme related).

*** DO READ THIS BEFORE COMMENTING ON THE PATCH ***
1. No, I have not done anything about the dialogues yet. To be able to post one patch for each dialogue, we need the theme manager in place first... I will get right to it as the next thing on the list...
2. Do not rewrite the code before we have discussed it!
3. Do not rewrite the code before we have discussed it!
4. Do not rewrite the code before we have discussed it!

Now as soon this is in, I can continue to update the dialogues and fix any related issues...
Title: Re: [Project] GUI Theme
Post by: prissi on November 04, 2013, 11:30:36 AM
Sorry, this is a little deja vue. I though you was preparing a color manager patch. Instead it is the old theme manager with a color manager added to it. I though Dwachs and me asked to divide images in makeobj instead in simutrans.

But I will first do your makeobj patch before looking more deeply.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 04, 2013, 12:27:13 PM
Sorry, this is a little deja vue. I though you was preparing a color manager patch. Instead it is the old theme manager with a color manager added to it.
But I was told to repost it in smaller updates... So I posted the makeobj in one patch and the simstring in another and then tried my best to post the theme manager and colour handling in two patches.
There is no colour manager in the code, but meanwhile we had a month long debate about object oriented design the colour system was updated with rgb colours, so I had to adjust my code to it and this made the patch even bigger because of the non indexed system colours you wanted.

I though Dwachs and me asked to divide images in makeobj instead in simutrans.
But I will first do your makeobj patch before looking more deeply.
I did what Dwachs suggested me to do...
My proposal would be the following: Could you provide an updated patch(1) that contains the theme-related code, implements the theme for the gui-components, and does not introduce a new pak/cutting system (ie which uses the existing skinverwaltung stuff for compatibility)? That way we would have a smaller patch to discuss. Maybe you posted such a patch earlier - I did not notice as I did not follow this topic from the very beginning.
...
(1)A patch that contains that contains exactly one feature: the theme manager and its relation to the gui components. No white-space changes in unrelated files, no debug code for makeobj, no change to resource file etc.
Title: Re: [Project] GUI Theme
Post by: Dwachs on November 04, 2013, 02:50:27 PM
The patches now mix (a) new color system, (b) cutting of images, and (c) theme manager.

The patch to move the color system to full rgb colors should come first imho, then the theme manager.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 04, 2013, 03:15:13 PM
The patches now mix (a) new color system, (b) cutting of images, and (c) theme manager.
(a) not my fault, I wanted to build on the existing array system to minimize the impact.
(b) The guard colour cutting is not in there, it uses the current way of designing a skin with he exception of the theme object type in the .dat file (that Prissi added and no one objected about it, even if all previous skin-PAK files became useless) and there is no theme management if the images isn't cut.
To keep the current format without the manager to do the 3x3 grid and still be able to do a frame is impossible!

The more we debate about how this patch is being submitted, more stuff will be updated in trunk forcing me to update my patch and it will grow bigger and bigger...

You guys are telling me to submit small patches with context and working. It is quite impossible to do all this at once. Either you will have small patches (as I started to submit) out of context and maybe even not able to compile or you get a larger one that can be compiled.

The patch to move the color system to full rgb colors should come first imho, then the theme manager.
A new colour system isn't in the scope of my project, I simply asked if I should continue on the colour array or not. I was told that it was a stupid idea and everything should be separate variables in RGB, so I did and now I get the blame for doing as I was told  :o

It doesn't matter what I do, or what advice I follow, I feel like the escape goat for everything here...
I really don't think it's my fault this patch has grown this big and as soon it has been implemented I can continue with much smaller patches... We have wasted far too much time already...
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 08, 2013, 04:29:56 PM
Now when the makeobj patch has been incorporated, what is the status on this one? Are some one looking at it or is it hanging in limbo?
I'm just asking so there isn't any misunderstanding on what is going to be done as the next step...
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 10, 2013, 05:43:32 PM
Hello?

Should I take this as no one is working or intend to work on my patch?
Title: Re: [Project] GUI Theme
Post by: prissi on November 10, 2013, 10:38:36 PM
There was an internal questioning how to proceed. As you know there is your and my version on implementing themes. In the end it was two votes for mine, one abstained, and one that my patch should also get proper code review (which certainly not a bad idea).

As it currently stand I am the only one working on the GUI at the moment. As such I am obviously biased for the "classical" way to incorporate skins (and leave the cutting to makeobj). However, I am also still working on some theme designs to have a really useful choice (and to finalize a theme format, which can be the same until the next stable release and is future-proofed. I would of course also welcome code review). So I did not yet commit it.

The other reason I did not commit is simple: I fear by doing the commit you might consider leaving the community, which I would like to avoid (as mentioned several times, you have some original ideas and contributed a lot already). Hence, I would still like to develop the simutrans GUI for tablets, and I would also look forward to semiautomatic cutting in makeobj. Also a more consistent color management is certainly welcomed.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 11, 2013, 11:35:22 PM
There was an internal questioning how to proceed. As you know there is your and my version on implementing themes. In the end it was two votes for mine, one abstained, and one that my patch should also get proper code review (which certainly not a bad idea).
Has it been a closed voting? Is this "internal" process public or above my head? I have explained my goals and design many times, but it seems like only a few actually has read and/or understood it. How do you know that your design will not interfere with my plans? I have said this so many times now; this isn't the final theme code.

As it currently stand I am the only one working on the GUI at the moment. As such I am obviously biased for the "classical" way to incorporate skins (and leave the cutting to makeobj). However, I am also still working on some theme designs to have a really useful choice (and to finalize a theme format, which can be the same until the next stable release and is future-proofed. I would of course also welcome code review). So I did not yet commit it.
So making new themes is a higher priority than incorporating the basic design first? Finalizing the theme format?!? How can you do that when you don't know what it has to be capable of?
...and useful choices? I provided 2 very useful choices, both as PAK files and full source, but that was of course for my working theme code. What was wrong with them? Based on your arguments, I actually suspect that you never looked at them at all.

The other reason I did not commit is simple: I fear by doing the commit you might consider leaving the community, which I would like to avoid (as mentioned several times, you have some original ideas and contributed a lot already). Hence, I would still like to develop the simutrans GUI for tablets, and I would also look forward to semiautomatic cutting in makeobj. Also a more consistent color management is certainly welcomed.
Regarding cutting, how do you achieve this if all cutting is made in makeobj?
The artist has put a horizontal constraint on a GUI element, but the user needs it to be of the frame type so he can use his big fingers on a touch screen. Now, all images are already cut so Simutrans needs to reassemble them into one image again and then do a new cut. By cutting in make object, you get 8 times more image indexes, something you feared earlier. By cutting in makeobj, you need to recompile makeobj everytime there is an update in how theme images are handled.

By doing the cut in Simutrans we only need one image (resulting in less indexes than we have now per GUI element). We can freely introduce new ways of logic in the cutting without having to update makeobj. This would not make current theme-PAK files obsolete, instead Simutrans can apply the new/updated handling on already generated theme-PAK. So in the end, PAK files becomes smaller and less sensitive to changes compared to a pre cut PAK file.

So let us turn this around. Why is it so much more beneficial to let makeobj generate a myriad of indexed tiny images? Should the theme logic really be in makobj? Isn't makeobj a PAK tool? How these theme images are used is up to Simutrans, not makeobj.

I started this project and invited any one to join me, but no one else was interested. On the contrary I was encouraged because no one really liked to do the GUI stuff I was told. It feels like you have hijacked my project as your own. If we are going to shed sweat and tears over every single little detail, I will eventually give up and just walk away. I don't see any point in investing more than 400 hours in something that is refused because some one doesn't like my object oriented design, have functional code rewritten without even asking, or not take the time to even try understand my work. Not even just apply the full patch and try it out to see how it works...

It doesn't feel fair and square that you guys can commit whatever you like without a single line of critique, even when things break. Prissi changed the Skin format so all skin-PAK files became obsolete and no one even mentioned it. While my working code, still used the same skin-PAK files for backward compatibility was rewritten without even asking a single question about it.

However I did accept the new theme Object because I had planned to introduce this myself, but later down the road when I had a text node in place so we could leave the index based variables...

If I leave or not is entirely up to you... If my work was respected I would feel more encouraged to continue. If you change my implementation you have successfully thrown away my entire project and my visions and I just can't continue...
We have wasted by far too much time already...
Title: Re: [Project] GUI Theme
Post by: Ters on November 12, 2013, 06:17:10 AM
The artist has put a horizontal constraint on a GUI element, but the user needs it to be of the frame type so he can use his big fingers on a touch screen. Now, all images are already cut so Simutrans needs to reassemble them into one image again and then do a new cut. By cutting in make object, you get 8 times more image indexes, something you feared earlier. By cutting in makeobj, you need to recompile makeobj everytime there is an update in how theme images are handled.

By doing the cut in Simutrans we only need one image (resulting in less indexes than we have now per GUI element). We can freely introduce new ways of logic in the cutting without having to update makeobj. This would not make current theme-PAK files obsolete, instead Simutrans can apply the new/updated handling on already generated theme-PAK. So in the end, PAK files becomes smaller and less sensitive to changes compared to a pre cut PAK file.

So let us turn this around. Why is it so much more beneficial to let makeobj generate a myriad of indexed tiny images? Should the theme logic really be in makobj? Isn't makeobj a PAK tool? How these theme images are used is up to Simutrans, not makeobj.

Makeobj is always recompiled whenever how ways, vehicles, buildings, goods and factories are handled changes, so that's not something new. The underlying design principle is effectively that Simutrans is just the game, with virtually no error handling. All data must be passed in a pre-processed form. The exception I'm aware of is ground tiles, which are actually assembled in-game at start-up.

I started this project and invited any one to join me, but no one else was interested. On the contrary I was encouraged because no one really liked to do the GUI stuff I was told. It feels like you have hijacked my project as your own. If we are going to shed sweat and tears over every single little detail, I will eventually give up and just walk away. I don't see any point in investing more than 400 hours in something that is refused because some one doesn't like my object oriented design, have functional code rewritten without even asking, or not take the time to even try understand my work. Not even just apply the full patch and try it out to see how it works...

The problem, as I see it (others may have completely different views and issues), is that work on the GUI is very much welcommed, but it has spilled over into the common ground of rendering, image handling, color management and pak files. In hindsight, it was perhaps unavoidable, but it's also areas where changes are more controversial, and consequences more far-reaching, than in the GUI itself. The Simutrans community is very spare-time based. (I've hardly started Simutrans since spring, let alone looked at the code.) That may be an extra cause of conservativism, as people want to be able to recognize how thing are done when comming back after six months, although this is just speculation on my part. I'm more or less just a consultant developer of sorts.
Title: Re: [Project] GUI Theme
Post by: prissi on November 12, 2013, 02:42:04 PM
Regarding the cutting: In the original proposal there was a cutting indicated by color lines. This is probably the best choice, as this is will work on asymmetric boxes and similar. As such is can go into the general list cutter, maybe just specified cutimage instead of image. Just image a button like the attached (following the recent pak192.comic tool design). The green help line would prevent wrong cutting and would still allow makeobj to generate correct images.

And what Ters wrote about the code is very much true. If thing change too much, there is much work for all other to follow it. That and large projects (not only simutrans) tends to stick to working code, i.e. not changing (and reusing) what was already working. Obviously this is not always possible, and the benefit of change must be weighted against the advantages of having a working and understood (if only be getting used to it even) system.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 12, 2013, 03:12:50 PM
Makeobj is always recompiled whenever how ways, vehicles, buildings, goods and factories are handled changes, so that's not something new. The underlying design principle is effectively that Simutrans is just the game, with virtually no error handling. All data must be passed in a pre-processed form. The exception I'm aware of is ground tiles, which are actually assembled in-game at start-up.
...and just because Simutrans don't do error handling, this is a good thing that never should be improved?

The problem, as I see it (others may have completely different views and issues), is that work on the GUI is very much welcommed, but it has spilled over into the common ground of rendering, image handling, color management and pak files. In hindsight, it was perhaps unavoidable, but it's also areas where changes are more controversial, and consequences more far-reaching, than in the GUI itself. The Simutrans community is very spare-time based. (I've hardly started Simutrans since spring, let alone looked at the code.) That may be an extra cause of conservativism, as people want to be able to recognize how thing are done when comming back after six months, although this is just speculation on my part. I'm more or less just a consultant developer of sorts.
Hmm, lets do a recap on what happen here...
- I used the current skin-PAK format, no changes at all. Prissi introduced a new system that broke all previous skin-PAKs.
- I used the indexed colour system for my new system colours. I was told it was stupid and a new RGB system should be used, so I ripped out my working indexed system colours to replace them with the RGB system, that I didn't introduce.
Again, no one complained about these changes, saying that people wouldn't recognise the code after 6 month...

My questions has still not been answered:
Has it been a closed voting? Is this "internal" process public or above my head?
How do you know that your design will not interfere with my plans?
So making new themes is a higher priority than incorporating the basic design first?
Finalizing the theme format?!? How can you do that when you don't know what it has to be capable of?
...and useful choices? I provided 2 very useful choices, both as PAK files and full source, but that was of course for my working theme code. What was wrong with them? Based on your arguments, I actually suspect that you never looked at them at all.
Regarding cutting, how do you achieve this if all cutting is made in makeobj?
The artist has put a horizontal constraint on a GUI element, but the user needs it to be of the frame type so he can use his big fingers on a touch screen. Now, all images are already cut so Simutrans needs to reassemble them into one image again and then do a new cut. By cutting in make object, you get 8 times more image indexes, something you feared earlier. By cutting in makeobj, you need to recompile makeobj everytime there is an update in how theme images are handled.

By doing the cut in Simutrans we only need one image (resulting in less indexes than we have now per GUI element). We can freely introduce new ways of logic in the cutting without having to update makeobj. This would not make current theme-PAK files obsolete, instead Simutrans can apply the new/updated handling on already generated theme-PAK. So in the end, PAK files becomes smaller and less sensitive to changes compared to a pre cut PAK file.

So let us turn this around. Why is it so much more beneficial to let makeobj generate a myriad of indexed tiny images? Should the theme logic really be in makobj? Isn't makeobj a PAK tool? How these theme images are used is up to Simutrans, not makeobj.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 12, 2013, 03:21:26 PM
Regarding the cutting: In the original proposal there was a cutting indicated by color lines. This is probably the best choice, as this is will work on asymmetric boxes and similar. As such is can go into the general list cutter, maybe just specified cutimage instead of image. Just image a button like the attached (following the recent pak192.comic tool design). The green help line would prevent wrong cutting and would still allow makeobj to generate correct images.
It is still the current proposal. But you want this in small updates, so I do what I can to make this transformation as painless as possible. There WILL be coloured cut lines and with my current patch the very example you bring up can be achieved by using 2 or 3 images (as before, in the current skin-PAK format). I have explained this so many times now. So I ask you this:
Do you really read all my posts?
Do you understand them?
Have you tried my full patch, to see how it works?
Have you looked at the themes I provided in both source and PAK?

You seems to think that this is it, this is the final theme patch, no more development beyond this point. I have said this so many times now, NO it isn't! It is work in progress because you wanted it to be in small updates.
Title: Re: [Project] GUI Theme
Post by: Ters on November 12, 2013, 05:03:17 PM
Hmm, lets do a recap on what happen here...
- I used the current skin-PAK format, no changes at all. Prissi introduced a new system that broke all previous skin-PAKs.
- I used the indexed colour system for my new system colours. I was told it was stupid and a new RGB system should be used, so I ripped out my working indexed system colours to replace them with the RGB system, that I didn't introduce.
Again, no one complained about these changes, saying that people wouldn't recognise the code after 6 month...

As I wrote, I have not been looking much at code lately, so the "spilling" I mentioned was based on the discussions. Discussions which included a radically different pak format in general.

When it comes to indexed colors vs RGB, indexed colors are a shared resource the GUI can't freely modify to it's own advantage. If the GUI themes are to be able to freely specify their own colors, these colors must be stored somewhere else and a way to get them from there to the screen was needed.
Title: Re: [Project] GUI Theme
Post by: kierongreen on November 12, 2013, 08:08:55 PM
Ok, I guess I'll be the one to raise my head above the parapet then:

Yes there was a vote.
Yes it was above your head because you refused to accept a consensus opinion.
Yes the people who voted read your posts.
No they weren't convinced.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 12, 2013, 09:06:24 PM
Ok, I guess I'll be the one to raise my head above the parapet then:

Yes there was a vote.
Yes it was above your head because you refused to accept a consensus opinion.
I didn't know there was a consensus opinion. As I understood, my solution was accepted by those who actually took the time to read the original code.

Yes the people who voted read your posts.
For some reason I have hard time to believe that because I can still see the same arguments based on false facts about my implementation.

No they weren't convinced.
Not convinced? So who tried to convince then, since I wasn't invited to explain my code and what to come down the road?
How many has tried my original patch, read the original code and understood where it will lead?

It feels like a trial where I wasn't invited to defend myself... not a democracy.

I'm very close to just walk away from all this, and I guess this is what you all want. But I will cool down a bit and see how I feel about it later...
Title: Re: [Project] GUI Theme
Post by: Ters on November 12, 2013, 10:06:12 PM
I don't remember the no longer so secret "vote" being about Max-Max's patch, or Max-Max, directly. It was about whether prissi should do the changes to Simutrans he wanted, which would affect (at least parts of) what  Max-Max has been doing or wants to do. In any case, the statements from either side had already been made, and the jury in a sense retreated into a private room to reach their verdict.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 18, 2013, 12:12:20 AM
So what is going on here? I'm waiting for the trunk merge so I can continue... (if it is possible after the merge).
I'm kind'a losing focus and interest by this waiting...
Title: Re: [Project] GUI Theme
Post by: prissi on November 19, 2013, 12:20:19 AM
Sorry it took so long. Git is not to easy to let its data go back. It took me a while the get a patch mingw could apply, and also get the binary files right.
Title: Re: [Project] GUI Theme
Post by: Markohs on November 19, 2013, 09:00:57 AM
in simgraph.h there is a new macro defined, PUSH_CLIPRECT . I think we have more than enough macros, in my oppinion it's not a good solution.

The patch is quite big, I'd like to hear Max-Max oppinion on this new code, since I'm quite lost reading it. :)
Title: Re: [Project] GUI Theme
Post by: prissi on November 19, 2013, 12:13:27 PM
PUSH_CLIPRECT was a leftover from the code from Max-Max ... I can remove it.

Most of this patch was around for more than three weeks btw.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 12:47:03 AM
Since I wasn't invited to the "secret" meeting I have no idea why Prissi's structured C code was implemented over mine object oriented implementation (don't you think simgraph has enough C functions as it is?).
Can some one please state why Prissi's implementation was chosen over mine?

I'm currently looking at the implementation, but so far I can't see how I can use this code to achieve my goals.
Title: Re: [Project] GUI Theme
Post by: Ters on November 20, 2013, 05:43:50 AM
Since I wasn't invited to the "secret" meeting I have no idea why Prissi's structured C code was implemented over mine object oriented implementation (don't you think simgraph has enough C functions as it is?).

The secret meeting was just a round of votes and a few comments on the situation. At least the part I was involved in. All the arguments are in this very topic.
Title: Re: [Project] GUI Theme
Post by: Dwachs on November 20, 2013, 06:55:53 AM
First of all, prissi's patch is valid C++ (at least in MSVC terms - g++ complains).
Can some one please state why Prissi's implementation was chosen over mine?
Because prissi's implementation was (a) complete and (b) did not mix different things in one patch, of course this is just my personal opinion. Imho your patches above are not complete and mix different changes. Look at these two patches you posted some time ago: First patch: the big theme patch plus some incomplete rgb stuff. Second patch: the rest of the rgb patch. I would not call either of these patch files complete. And they mix different things at the same time.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 05:40:31 PM
So no one didn't actually looked at the design, just that it was "incomplete"? The reasons stated here are mostly not true. This is why I always ask the question if my post are read at all. There are a lot of assumptions about how my code work, it seems like no one really had looked at it.

The major problem here is that some of you say, don't submit code out of context.
Other says, don't submit to large patches, better to do small ones.

It is impossible to do both in this project. If the sole reason is that it was "incomplete", why didn't I get the chance to "complete" it? Prissi's code has been submitted without any code review and I haven't seen any one discussing pros and cons with hour different solutions.

Just because code runs through a C++ compiler doesn't make it object oriented. Object oriented design can be applied to many things, not only code. If the reason is that there are very few people that really know object oriented design, just say so and try to learn something instead.

Prissi's code do not use polymorphism (http://en.wikipedia.org/wiki/Polymorphism_(computer_science)). If we are to add more behaviours or dynamically assign different behaviours to the same object, we need to go down and make the object aware of the differences. With polymorphism, the object itself doesn't need to know anything of this. It is easier to manage, maintain and extend.

My goals include the possibility to change behaviours for various objects, dynamically. This isn't possible with Prissi's design (well it is, but it will be a quite cumbersome job to track down all places that needs to be updated). With polymorphism we can just derive from a previous behaviour and add this to the structure with a few lines of code, all in the same place.
Title: Re: [Project] GUI Theme
Post by: Ters on November 20, 2013, 07:06:56 PM
Object oriented programming is not a goal in itself. In fact, functional programming is apparently the new "One True Path". There is also nothing in simgraph that will benefit from runtime polymorphism, at least not within the scope of a GUI makeover. (It has compile time polymorphism, without much fluff, which is enough for now. Most of the macro hell have to do with a changeable interface, which OOP can't solve.) Furthermore, simgraph is at the very core of the system, and has seen extensive profiling over the years. Non-trivial changes there is too risky or costly. What prissi did didn't affect existing functionality from what I can see. But one of the issues of discord here is that simgraph is being discussed, beyond requests for new functions for drawing special things.

As for the GUI things, I very much agree that it is difficult, perhaps too difficult, to make small changesets that both work and make sense. At work, we would never ever have considered doing stuff comparable to this on trunk. But I am getting more and more worried that if this had been done on it's own branch, so much code beyond the GUI itself would have been changed, that we wouldn't be able to merge it back to trunk.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 07:23:49 PM
My original code didn't add much to simgraph. I used the current simgraph functions. The polymorphism isn't about Simgraph, it is behavioural patterns to how GUI elements resize and further down the road collapse.

The RGB colour aspect wasn't me. I wanted to use the existing system to minimize the impact, but no one was even interested in looking at it. Again assumptions was made of how this was implemented and I was told to use the new RGB system instead.

I tried to submit smaller patches, just because it would be easier to merge into the trunk and gradually update the system, but I was told it was out of context.

Anyone working against the trunk will always have an easier solution to implement compared to every one else. But is this a reason to refuse "outside" development that might require a little bit of work?

The current workflow with smaller patches, that are complete implementations is only possible for bug fixes and smaller tweaks. For larger projects this workflow can't be used and as long these criteria are held higher than the purpose, we will never be able to do larger projects.
Title: Re: [Project] GUI Theme
Post by: Dwachs on November 20, 2013, 08:05:12 PM
From reading your posts that contain the patch files I got the impression that these patch files are snapshots of work-in-progress. This I meant by 'incomplete'. The rgb patch was mixed into the theme patch ('all colours are screwed up') and a second part was in an extra file. Do you expect somebody to commit these patches as they are?

I am out of this discussion, in fact I joined it just for to purpose of moderating between the competing parties here.
Title: Re: [Project] GUI Theme
Post by: Ters on November 20, 2013, 08:31:40 PM
My original code didn't add much to simgraph. I used the current simgraph functions. The polymorphism isn't about Simgraph, it is behavioural patterns to how GUI elements resize and further down the road collapse.

Then maybe I misunderstood you when you wrote:

[...] Prissi's structured C code was implemented over mine object oriented implementation (don't you think simgraph has enough C functions as it is?).

The GUI itself is already OOP (although perhaps not very good OOP, I haven't looked much at it), and should continue to be so (perhaps even better). However, I'm a pragmatic person, and don't do something just because a book, fourteen speakers at conferences, and one thousand forum posts and blogs advocate it. Because in my limited experience, five-ten years down the road, a book and fourteen speakers (perhaps even some of the previous fourteen), and one thousand forum posts and blogs advocate against it (at least in the form adapted by the majority). It seems that when programmers get a tool, they use it for everything, sometimes leading to less maintainable systems than before. This is what shapes my opinions.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 09:24:09 PM
From reading your posts that contain the patch files I got the impression that these patch files are snapshots of work-in-progress. This I meant by 'incomplete'.
Yes, it was limited to keep the patch smaller since this was an earlier argument to not look at it. Others has committed work in progress,  code that break functionality or missing files. So I don't understand why I have to submit fully finished patches when you guys don't? I thought the same rules applied to all of us :o

The rgb patch was mixed into the theme patch ('all colours are screwed up') and a second part was in an extra file.
I had to because someone else (as in not me) implemented the RGB system and I was told to not use the indexed system and that broke my patch so I had to update it to use the new RGB system to make my patch to work again.

Do you expect somebody to commit these patches as they are?
Yes, after checking that it doesn't break anything horribly bad, gives compile errors or make the game unplayable.
If you had applied the patches and tried it out you would have seen that they in fact worked. I need this base platform to get up to speed. As I also mentioned, the remaining issues will be dealt with ASAP and the patches can be made smaller as soon the base platform is in place.

I split the patch into two parts, on your own request, one dealing with colours and one with themes.

I am out of this discussion, in fact I joined it just for to purpose of moderating between the competing parties here.
I take this as you never looked at my original code and how it was implemented. I also take this as you never read any of my documents or goal descriptions.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 09:38:36 PM
Then maybe I misunderstood you when you wrote:
"[...] Prissi's structured C code was implemented over mine object oriented implementation (don't you think simgraph has enough C functions as it is?)."
The GUI itself is already OOP (although perhaps not very good OOP, I haven't looked much at it), and should continue to be so (perhaps even better). However, I'm a pragmatic person, and don't do something just because a book, fourteen speakers at conferences, and one thousand forum posts and blogs advocate it. Because in my limited experience, five-ten years down the road, a book and fourteen speakers (perhaps even some of the previous fourteen), and one thousand forum posts and blogs advocate against it (at least in the form adapted by the majority). It seems that when programmers get a tool, they use it for everything, sometimes leading to less maintainable systems than before. This is what shapes my opinions.
I start to suspect that Prissi's and my code are confused. The code in the Trunk is far away from my original code, most of it comes from Prissi. I'm not using OOP just because. I use it when I can benefit from the OOP that C++ has to offer. My design is build up around the fact that a class can be derived and extended without changing the basic interface.

Encapsulation also contributes to a cleaner solution, less vulnerably to changes. An object can easily be replaced with another, or derived without breaking the interface to those using the object.
Title: Re: [Project] GUI Theme
Post by: prissi on November 20, 2013, 10:15:18 PM
Ok, this is very much stuff together.

Max-Max you used and index to an array of object to get the drawing function. What kind of polymorphism is this? All gui_xyz stuff is based on gui_komponente, so there is already polymophism. Same for vehikel_basis_t and obj_t, and a lot of other stuff. But those are virtual functions, not arrays of objects.

Anyway, programming is about a solution to a problem. Drawing bitmaps is not somethign that needs much derivation, any interface should be in gui_komponente (and indeed there is zeichnen which is a polymorphism).

And the best solution is the most simple solution (whatever simple is ... ) For me it is least changed lines, or least additional classes (since there is already a huge codebase to maintain). Your mileage may vary, and as Ters said, also personal preferences change over time (and of course with the language used).

simgraph is almost exclusively C code, since it was a C-file and got never converted. Some of the macro hell could be indeed solved by default parameter, and cleaning up simgraph is a good idea (although it certainly is better done in another thread than the GUI one).

I just added two functions (and also you added the ellipse one then). My reasoning for doing the stretch display in simgraph: This is also needed for window background, so I could reuse the function even further.

You were offered hints, like doing the cutting automatically (on demand) in makeobj. You insist aparently on doing it in simutrans, just because. Ever considered this best of both worlds? One does not exclude the other; in fact you convinced me way back that nine part button graphics are a good idea.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 20, 2013, 11:14:31 PM
Ok, this is very much stuff together.

Max-Max you used and index to an array of object to get the drawing function. What kind of polymorphism is this? All gui_xyz stuff is based on gui_komponente, so there is already polymophism. Same for vehikel_basis_t and obj_t, and a lot of other stuff. But those are virtual functions, not arrays of objects.
This statements make me believe that you don't understand the code. It isn't a list of the same object. The list is used to map a theme ID to its assigned behaviour class.

The list is indeed holding the same object type pointer, but if you look carefully this is the pointer to a base class. This base class defines a common interface and has some pure virtual functions, like Display.
No, the polymorphism isn't in the array, it is the objects stored in the array, but since they all share the same base class they can be stored in the same list and used in the same way without the GUI component need to know exactly what derivative of the base class has been assigned for that particular theme ID. In this way we can add new behaviours without any need to update the GUI Component code.

The derived class defines the pure virtual functions different depending on what rule to apply to an element, this is polymorphism. I have showed this class diagram a couple of times now.

(http://forum.simutrans.com/index.php?action=dlattach;topic=11956.0;attach=22749)

So when you get the pointer from the array, it isn't a theme_element_t object it is one of the derived classes, accessed by the common interface in the base class, so they can all be treated the same way, even if they do things different. This is the polymorphism I'm talking about all the time, not the array mapping theme ID to its class.

When It comes to the GUI components, I haven't yet started on this work and to be frank, I'm not sure I want to do it either. If this simple theme class design is making such a fuzz, then a rework of the GUI components would be a nightmare... so I have been scared of there...
Title: Re: [Project] GUI Theme
Post by: prissi on November 20, 2013, 11:58:17 PM
Yes that is true, the theme objects are polymorph. However, the code does not call the object directly, it just provides an index, which is looked up and then called the object in the theme manager. If indexes are polymorphism, then our definitions differ (which is the case).

My basic critic to this is, that this does not need any polymorphism at all. It just display a bitmap in the end! All my code does is calling "display_stretch_bitmap" and this relatively short routine figures (and its subroutine) figure out all the needed (and possible) stretching on its own (which is not that hard). If I have to choose between a 50 line function and a base class and several derivations, I have to have a very good reason to use the complex solution. And just "because it is OOP" is not enough. Maintaining simutrans is hard enough as it is now.

If you want stretching the component sizes and alignment, then it has to be in gui_komponenete_t (which already had the align function added from your patch).
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 21, 2013, 03:21:28 AM
Yes that is true, the theme objects are polymorph. However, the code does not call the object directly, it just provides an index, which is looked up and then called the object in the theme manager. If indexes are polymorphism, then our definitions differ (which is the case).
I have never claimed that the array is polymorphic! It is you that brings up this subject up all the time. I have no clue where you got this from?

I have explained this before and I will do it again and can only hope that folks are reading it, all of it.

For those who wonder what a theme ID is or a theme element etc.. read this previous (http://forum.simutrans.com/index.php?topic=11956.msg126583#msg126583) description.

A GUI control knows that It should use theme ID x,z and y to draw itself. It doesn't know what images are used in this process, neither does it know how this is drawn in the client area. So it just tells the Theme manager, "hey, I want theme ID x to be drawn in this client rect.".

Now if we back up a bit, when a theme is loaded by the theme manager. The theme-PAK provides the manager with images located on specific indexes (because we can't give them names) and parameters of how these should be drawn. This gives the artist full freedom to decide for himself how various GUI elements are resized, and eventually mipmap levels for a specific control.

So depending on these parameters different classes can be assigned to various GUI elements. In one theme a button, for example, may only be resized horizontally and in another theme both ways (frame). This is why we have a base class and then derive different behaviours from it.

So back to our GUI control again. The theme manager maps the theme ID x in the list and gets the assigned class as its base pointer and calls the virtual function Display(). Now the correct code will be used without any tests at all of what type of rule the artist has assigned the control. It is simple and straight forward.

Since nowhere in this Display process any tests has been made of what rule to apply, everything is done the same way and no one (neither the GUI Control itself or the theme manager) needs to do any special handling. If we want to add more behaviour classes we simply derive it from the base class and add it to the theme load process. Simple as that! No need to update any GUI controls or do any tests on the way.

Back to the theme manager and theme loading again. If several theme IDs share the same image and rule set, there is no need to store them several times, just insert the same object pointer in the theme ID array and they will all reuse the same object and images.

If a theme ID image is missing the theme manager can easily reuse another object as a fall back, in a pre defined fall back scheme. This is not only handy for fall back, but also minimizes the amount of images needed if several GUI elements can share the same resources. This also prevents a theme-PAK to break when we add more and more theme images. For example: We have 4 arrow images for now. But later on we may add more "arrow" images specific for edit box, combobox, scrollbars etc... Maybe the Artist wants to use the same arrow images for everything? He doesn't need to supply the specialised images because the fall back will be to the generic.

My basic critic to this is, that this does not need any polymorphism at all. It just display a bitmap in the end! All my code does is calling "display_stretch_bitmap" and this relatively short routine figures (and its subroutine) figure out all the needed (and possible) stretching on its own (which is not that hard). If I have to choose between a 50 line function and a base class and several derivations, I have to have a very good reason to use the complex solution. And just "because it is OOP" is not enough. Maintaining simutrans is hard enough as it is now.
It is not just drawing, there is more to it as I have explained so many times now. The use of a base class allows us to use a common interface regardless of the end result. This separates the Theme from the physical GUI control allowing the theme to develop without the GUI Controls knowledge or need of know how.

If you want stretching the component sizes and alignment, then it has to be in gui_komponenete_t (which already had the align function added from your patch).
Now, don't confuse theme elements and their theme ID with the GUI Component's aliment to its surrounding GUI Controls. This is two different things and has little to do with themes.

Questions?
Title: Re: [Project] GUI Theme
Post by: Ters on November 21, 2013, 05:56:17 AM
I start to suspect that Prissi's and my code are confused. The code in the Trunk is far away from my original code, most of it comes from Prissi.

I am not cofusing the code, because I've hardly looked at it. I do however feel confused by some other thing(s) I can't really put my finger on. While I follow the broad outlines of Max-Max's last post, there are some details that I'm worried about. I've brought up those issues earlier.
Title: Re: [Project] GUI Theme
Post by: Dwachs on November 21, 2013, 07:12:57 AM
Quote from:
prissi
My basic critic to this is, that this does not need any polymorphism at all. It just display a bitmap in the end! All my code does is calling "display_stretch_bitmap" and this relatively short routine figures (and its subroutine) figure out all the needed (and possible) stretching on its own (which is not that hard). If I have to choose between a 50 line function and a base class and several derivations, I have to have a very good reason to use the complex solution. And just "because it is OOP" is not enough. Maintaining simutrans is hard enough as it is now.
I can only agree with that.

Max-Max, I read your posts and patches. Hence my comments. Your patches were not ready for inclusion imho. As I explained several times, they had unrelated changes in it, adding commented out code etc. This cleanup work is duty of the patch author imho.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 21, 2013, 11:48:11 AM
Max-Max, I read your posts and patches. Hence my comments. Your patches were not ready for inclusion imho. As I explained several times, they had unrelated changes in it, adding commented out code etc. This cleanup work is duty of the patch author imho.
Afaik the only function that was commented out that I brought in again was display_set_base_image_offset() which I announced in this thread (http://forum.simutrans.com/index.php?topic=12524.msg124030#msg124030) before I reinserted it for the simple reason that I used it.

I did remove the makeobj changes.
I did separated the theme and colour changes as good I could.
Everything else is connected and can't produce any working code without another, and working code in a context has been the reason earlier to refuse my code so I really don't know how to submit this and keep it small, in context, working and contributing something new at the same time.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 25, 2013, 09:32:07 PM
This isn't the project I once started any more. The goals are more short termed and not in line with my original goals.

I have spent hundreds of hours in this project and got almost nowhere because my code is constantly rewritten in a way that will move away from my goals. At one point I got the comment "But I am not sure how I could do the cherry picking with this.". This shows how the "inner circle" view contributors. We are merely just a library of function they can pick and chose from freely as they wish. If they can't, they implement your idea in their own way, not respecting what you try to accomplish.

I find it quite pointless to contribute if my work isn't respected. I have spent numerous amount of hours explaining how things work and why they are implemented the way they are. Still, old assumptions are used as arguments and this makes me believe that these people don't take the time to read my explanations, less the code. In private messages I have got support for my ideas and even my implementations and I'm very thankful for that, without them I would have given up this long time ago.

I have decided to go underground with this project based on the following.

 - Decisions are mostly made on assumptions, not functional code.
 - Secret discussions are held behind my back without giving me any chance to validate the "facts".
 - There is a small group of people that stands above the "rules". If I do a mistake, there can be a whole thread about it, but if a member in this "inner circle" introduce compiler errors, it goes by unnoticed.
 - The "inner circle" doesn't have a structure of adopting the same rules. One group complains about X and when I do X another group complains about Y. It doesn't matter what I do, someone is always complaining and my code is refused.
 - It is just not possible to create a major project and make both X and Y happy. This model works fine for bug fixes, refactoring and very small and limited functions.

The "inner circle" really needs to work out a workflow that can handle larger projects without internal conflicts in the way a patch should be submitted, what to review and how much can be rewritten without the authors permission. Until then I fear that developers will come and go away...

With risk that the trunk will diff to much from my project when I eventually post my "final" implementation, there might just be to much work involved to implement it. I tried to avoid this by posting smaller patches, but this wasn't accepted by group X of the reason "it is out of context". I think I have given plenty of chances to do this as painless as possible, but this hasn't been accepted, so one big mega-complete-all-patch is the only thing left to do now. I will post some screen shots and keep updates of how I progress but I can't guarantee that any of it will be implemented. That decision isn't in my hands...

I might post spin-off effects from my project as small isolated patches along the way.

So again, for those that have supported me, thank you but I will follow one of the early advices to just make this in "secret".
Title: Re: [Project] GUI Theme
Post by: Ters on November 25, 2013, 10:09:32 PM
The "inner circle" really needs to work out a workflow that can handle larger projects without internal conflicts in the way a patch should be submitted, what to review and how much can be rewritten without the authors permission. Until then I fear that developers will come and go away...
That's the biggest problem with Simutrans as a project. The "inner circle" apparently, and at least partly admitted, doesn't have the ability (time, skill or whatever) to deal with large, or even medium sized, projects by non-inner circlers.

- Decisions are mostly made on assumptions, not functional code.
I can understand you on that one, despite being at least somewhat guilty myself.

- Secret discussions are held behind my back without giving me any chance to validate the "facts".
You can't validate any facts about how we feel about you and where this was heading, or how we feel about how we feel about you and where this was heading.

- There is a small group of people that stands above the "rules". If I do a mistake, there can be a whole thread about it, but if a member in this "inner circle" introduce compiler errors, it goes by unnoticed.
Other people's errors don't go unnoticed. They get fixed. If they don't get fixed, then we've concluded that they aren't errors. Sometimes it may take a while to find the right fix that works on an platforms and compilers, and for the person responsilble to have some spare time with a computer.

- It is just not possible to create a major project and make both X and Y happy.
That's the curse of every software project. Normally, you have a boss selecting one solution. Simutrans tends to usually do both what X and Y wants (for small things usually), with all the extra maintenance cost that implies, or neither (for big things).
Title: Re: [Project] GUI Theme
Post by: Markohs on November 25, 2013, 11:29:16 PM
... so one big mega-complete-all-patch is the only thing left to do now.

 I think you should have started doing this long time ago, seeing how things are evolving.

 The best defense for ideas is implemented, working, code, with features not present already in the game. And mostly, when you are facing so much difficulties getting your ideas accepted.

 Implement it, make if functional so we developers can't understand why don't we have that already in our code, and working. Show how your code can do things that prissi's and the community current projected patch can't do, or can do way better. And don't forget about performance, it has to be at least as fast as prissi's code.

 Whatever the output of this comes, the community will get better, because you either prove prissi and we the rest of developers by extension were right, or we get your project implemented and included in the game.

 Good luck, I really hope you are successful. ;)
Title: Re: [Project] GUI Theme
Post by: kierongreen on November 25, 2013, 11:32:14 PM
Quote
I will post some screen shots and keep updates of how I progress but I can't guarantee that any of it will be implemented.
Indeed - I hope you are able to post really impressive screenshots :)

Quote
Secret discussions are held behind my back without giving me any chance to validate the "facts".
Arguments were made, facts were given, given again, and given again once more. You appeared to not accept anyone disagreeing with you, insisting that anyone who did was a poor coder and didn't understand what you were doing. Try to understand how this might appear to people that have worked with the simutrans code for the best part of a decade. Concluding the discussion in private allowed people to freely express their opinions as to a way forward which would hopefully not caused to much offence. Obviously in the circumstances this is nigh on impossible, but we tried our best.


While you might feel the code in simutrans now differs greatly from that you first submitted please remember that we wouldn't have made this progress without your input. It is very much appreciated, and I hope that you do find time to work on other areas of simutrans maybe as well as the gui as a different set of eyes sometimes does improve the game by leaps and bounds. I do sincerely hope that further development by you adds great features. However by the same token I wouldn't want you to waste time merely refactoring existing code as unless there are noticeable improvements for players I fear it unlikely a patch would be incorporated.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 27, 2013, 01:06:56 PM
Arguments were made, facts were given, given again, and given again once more. You appeared to not accept anyone disagreeing with you, insisting that anyone who did was a poor coder and didn't understand what you were doing.
Too my understanding there was never an agreement on what "version" to implement. I constantly had to correct false assumptions and based on the arguments I saw, I could only come to the conclusion that the code wasn't understood since I got the answer that my post was read and code was reviewed.

My code was also judged from the assumption that it was "finished". I said several times it wasn't, it was a smaller update to keep trunk in synch, as I had seen you guys do it before me. The best would have been to just admit that we can't handle partial progress of a large project and wait until I finished the whole project. The current state of the Trunk goes down a completely different path and keeping the trunk in synch with my local copy is near impossible now.
Title: Re: [Project] GUI Theme
Post by: Ters on November 27, 2013, 04:22:58 PM
The current state of the Trunk goes down a completely different path and keeping the trunk in synch with my local copy is near impossible now.

Ironically, Simutrans has always been criticized for not doing big changes since it would break all the patches under development. But your big GUI project, in combination with the half-height patch, meant that we for once have started doing big changes that have long been postponed.

My code was also judged from the assumption that it was "finished". I said several times it wasn't, it was a smaller update to keep trunk in synch, as I had seen you guys do it before me. The best would have been to just admit that we can't handle partial progress of a large project and wait until I finished the whole project.

I think your patches was judged as finished because only finished patches are accepted. The problem is that you need to 100% complete a small feature, that might be part of something bigger, but that works on its own. (Judging from you comments, you seem to jump from feature to feature. I don't know if you do the same with the coding.) More seasoned Simutrans developers may get away with bigger patches in one go, but that's because they have built up the trust to do things right over time. I fear that if you complete all the things you've written about, it will be a patch so big that nobody will take the time to look through it and submit it.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 27, 2013, 05:05:41 PM
I think your patches was judged as finished because only finished patches are accepted.
If find this very surprising because I wrote this several times and it was said that all my post was read :o

The problem is that you need to 100% complete a small feature, that might be part of something bigger, but that works on its own. (Judging from you comments, you seem to jump from feature to feature. I don't know if you do the same with the coding.)
I have touched the colours because I needed to load system colours. I proposed a colour manager to be developed further down the road. It was never my intention to develop a colour manager at this point, or even by me. I did use the current indexed system but was told it is a bad idea, even without seeing my current implementation, but based on assumptions of what I might have done. I didn't bother to even show what I had done and ripped it out to replace it with the RGB system (that was not implemented by me) and due to the ripple effect it had a lot of updates in the GUI.

I said that I have a candidate for a Canvas class if someone is interested in using it. The format is the same as for the main screen so with some small modifications all graphich functions can operate on it.

The makeobj debug update was because I needed to debug my theme-PAK files.

Just because I participate in a discussion or lay out a proposal, doesn't mean I'm implementing it. I'm pretty much inside the borders of my project.

More seasoned Simutrans developers may get away with bigger patches in one go, but that's because they have built up the trust to do things right over time.
If "trusted" isn't based on working code, but more or less on the coding style (that isn't even documented that well), I can't see how somewhat different ideas can be contributed. The focus seems to be more on code formatting rather than on working code.

I fear that if you complete all the things you've written about, it will be a patch so big that nobody will take the time to look through it and submit it.
So it is pointless to continue this project then? No one will implement it due to its size, nor am I allowed to send small updates of work in progress or check it in myself into the trunk...
Title: Re: [Project] GUI Theme
Post by: prissi on November 27, 2013, 05:32:47 PM
You patch was judged as a patch. I cannot judge your ideas, I can only judge your code. It was a more complex way to draw images than needed, so I decided to implement a simplier version.

However, the way button images are draw changes absolutely nothing on how the GUI elements are arranged for different sized boxes. In the latter there was no progress for a long time, which is the real show stopper for any themable UI. Well that will most likely be my task for now it seems.
Title: Re: [Project] GUI Theme
Post by: Ters on November 27, 2013, 05:56:13 PM
If "trusted" isn't based on working code, but more or less on the coding style (that isn't even documented that well), I can't see how somewhat different ideas can be contributed. The focus seems to be more on code formatting rather than on working code.

Nobody writes 100% working code all the time once the code passes a certain size, even more so when code has to work on multiple platforms with multiple compilers. Products like Jenkins wouldn't exist otherwise. And we assume developers themselves are focused on getting their code to run. So what's important to discuss, is how Simutrans is coded, so that the style converges on something that looks familiar, and the architecture of Simutrans.

I did use the current indexed system but was told it is a bad idea, even without seeing my current implementation, but based on assumptions of what I might have done.

You did complain that you felt restricted by the existing special colors and that prissi's feature for finding the nearest special color to a given RGB wasn't what you wanted. As many things depend on the special colors, not just the GUI project, the special colors in simgraph likely won't change anytime soon. So the available options for the new GUI is to either stick to the 256 colors from the 8-bit days, or do something completely new and let the rest of the code follow in time, if possible, until the old special colors can die. Hopefully, any new stuff can avoid mixing up colors that have nothing to do with each other, which I find very confusing with the current arrays in simgraph. My RGB drawing primitives was a low impact change that among other things made it possible to do a new color management system. With real colors, it also seems most right to do color management above fundamental drawing primitives, rather than below them, as doing it below is more limiting in what you can do.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on November 27, 2013, 06:24:44 PM

I've been on this forum long enough to realize that the innovative concepts not so well accepted in simutrans.


So, how it is intended reach mobile platforms, Touchpad and even HTML5? ???
Title: Re: [Project] GUI Theme
Post by: Ters on November 27, 2013, 06:51:47 PM
Simutrans won't reach HTML5. That's like asking when your car will become a segway. It theoretically possible to make a segway out of a car, but it's far easier to just forget the car and just make a segway. (Pak sets could possibly be reused.)

The problem with innovative consepts is that they are time-consuming and risky. Simutrans is actually doing innovative things at the moment, but it has led to many errors and a long period without any stable builds (and there is still a long way to go). We simply don't have much time.

And Simutrans is open-source. Anyone who wants is free to make their own fork and do whatever they want. But I don't think the few forks do any better, despite getting promotion and their own boards on simutrans.com (one has since asked to be removed).
Title: Re: [Project] GUI Theme
Post by: Dwachs on November 27, 2013, 06:57:55 PM
Quote from:
Max-Max
The focus seems to be more on code formatting rather than on working code.
My focus is on having a stable program, without bugs, that compiles without serious warnings. My focus is on working on clean patches, that change one thing at a time. My focus is to help people who report bugs and work on patches. My focus is not on white-space changes and not on enforcing a coding style up to the byte level. My focus is not to argue about licenses, c++, and oo programming. My focus is not on having endless arguments of this-is-better-than-that. I have to admit this does not work hundert percent of the time, sadly.

What is your focus?
Title: Re: [Project] GUI Theme
Post by: Ters on November 27, 2013, 07:02:11 PM
Looks like both sides may see the other as rambing on about coding style and design patterns.
Title: Re: [Project] GUI Theme
Post by: Max-Max on November 27, 2013, 09:00:02 PM
My focus is on having a stable program, without bugs, that compiles without serious warnings...
If you had tested my full patch you would have found it without compiler errors and working. For warnings, well there are a bunch of warnings present since before I joined, why not focus on them?

What is your focus?
Do I sense a trace of sarcasm here?

You patch was judged as a patch. I cannot judge your ideas, I can only judge your code. It was a more complex way to draw images than needed, so I decided to implement a simplier version.
But I told you and every one else that it wasn't a "patch" patch, it was work in progress for the sole reason that you wanted small updates. If you won't accept a patch like that, then you should have said, no we will not look at it, finish the project first.

However, the way button images are draw changes absolutely nothing on how the GUI elements are arranged for different sized boxes.
That is because you refused to look beyond the patch. I said the patch was the base structure for the theme system that I will build on. I did explained how this was going to be used, but I still got old assumptions as replies (in best case, usually no reply at all).

In the latter there was no progress for a long time, which is the real show stopper for any themable UI. Well that will most likely be my task for now it seems.
So is it my fault that I had to wait for you to implement stuff in the trunk? What should I have done? My way to respect your efforts where to not post a new patch every week that cancels the patch you worked on. Instead I waited for you to implement them before I continued. So this isn't really in my hands...

I had planned to finish this before Christmas, but that was with the assumption that my code went straight in to the trunk (or whatever)... Instead I have wasted weeks in waiting and now it is my fault?
Title: Re: [Project] GUI Theme
Post by: Ters on November 27, 2013, 09:32:57 PM
But I told you and every one else that it wasn't a "patch" patch, it was work in progress for the sole reason that you wanted small updates. If you won't accept a patch like that, then you should have said, no we will not look at it, finish the project first.

They didn't say that because, as they wrote (even quite early on if I remember right), they didn't want you to finish the entire complete rewrite of the GUI before accepting a patch from you. Such a patch would have been refused as being too large, as some of your work in progress were apparently already becomming too large. They wanted you to complete one small part, submit a patch, complete another small part, submit a patch, and so on. Instead they got a patch with a little bit of work on several things (or so they claim at least). Unfortunately, as has already been briefly mentioned, it's hard to see the big picture when it's served in small parts.
Title: Re: [Project] GUI Theme
Post by: Yona-TYT on May 01, 2014, 01:11:08 AM



Theme Windows 7 http://forum.simutrans.com/index.php?topic=11956.msg126496#msg126496
It is possible to repair it?


(https://www.mediafire.com/convkey/acd8/p9a17p367uwhalx6g.jpg)
Title: Re: [Project] GUI Theme
Post by: prissi on May 01, 2014, 08:36:31 AM
Certainly, but it was never completely finished, or rather never really optimized. You can do this yourself, it is very simple. Just look at the source provided there.