The International Simutrans Forum

Development => Patches & Projects => Incorporated Patches and Solved Bug Reports => Topic started by: Ves on October 08, 2016, 07:09:24 PM

Title: Clickable button in "obj_t::info" window
Post by: Ves on October 08, 2016, 07:09:24 PM
I am trying to create a clickable button in a signals infowindow as well as in a buildings (namely speaking an experimental signalbox) infowindow. They both use "void signal_t::info(cbuffer_t & buf, bool dummy) const" (buildings use "gebaeude_t" instead of "signal_t") to show their infowindows. I suspect that to have a button will demand some extra resources, or what you would call it, as some of the other windows that already contains buttons (such as the convoy window, factory window etc) appears to use "void convoi_detail_t::draw(scr_coord pos, scr_size size)" along with the "action triggeded" section.

I have tried boldly to just copy over some of the button entries from the vehicle window to the signals window, along with their definitions but this tends to end with errors I have no clue how to resolve.

Is it possible to create buttons with "void signal_t::info(cbuffer_t & buf, bool dummy) const"?
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 08, 2016, 07:48:00 PM
What is the purpose for such a button? If it is for something sensible I could look into it as a feature. Or is this for experimental Simutrans as part of one of its signalling systems?
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 08, 2016, 08:11:05 PM
The initial purpose of the button is to locate the signals signalbox on the map. Much like clicking on a supplier in the factorywindow takes the map to that specific position on the map.
From the buildings persective, the initial thought was to have a similar button, but due to the possible long list of signals, I would rather here make one button in the building window that opens another window containing the list of signals with their respective location buttons. But again, I need the button in the info window in the first place.

Other potential uses of the button is to, in similar ways, locate stops that a building is served by (I don remember if standard simutrans also shows connected stops or walking distance to stops?), one can create a button that locates which train is reserving a piece of track, and just in general, one can add more tools to make diagnosing the game eisier.
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 08, 2016, 09:40:35 PM
Quote
I have tried boldly to just copy over some of the button entries from the vehicle window to the signals window, along with their definitions but this tends to end with errors I have no clue how to resolve.
Compile time errors or run time errors? If it is compile time then perhaps you can post the problematic code and the errors being thrown.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 08, 2016, 10:14:37 PM
I copied the following from "factorylist_stats_t" over to "signals_t" in the mentioned ::info
bool selected = sel == 0 || welt->get_viewport()->is_on_center(gb->get_pos());
display_img_aligned(gui_theme_t::pos_button_img[selected], scr_rect(offset.x, yoff, D_POS_BUTTON_WIDTH, LINESPACE), ALIGN_CENTER_V | ALIGN_CENTER_H, true);
sel--;


I resolved all errors I could, changing the names etc. and end up with one red underline under "welt".
The error it produces:

Severity Code Description Project File Line Suppression State
Error C1903 unable to recover from previous error(s); stopping compilation Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 127
Error C2082 redefinition of formal parameter 'buf' Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 127
Error (active) pointer to incomplete class type is not allowed Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 385


Also, what is the difference between "compile time errors" and "run time errors"?
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 08, 2016, 11:03:18 PM
There appears to be two errors, one at line 127 (or above) and the other at line 385 (or above). Assuming this uses latest experimental GIT maybe a difference file would be useful for spotting what is wrong.

Quote
Also, what is the difference between "compile time errors" and "run time errors"?
Compile time errors are thrown when you try to build (compile) the code, before it can be run. In the case of C++ they can also include compile and link time errors as both occur before the final program or library is produced. Runtime errors occur when the program or library is actually executing. Runtime errors can remain hidden to users as the program may appear to function perfectly except under certain conditions.

Compile time errors usually come in three types. Most common are syntax errors where code is typed incorrectly in a way it makes no sense to the compiler. The next most common is where there is a language specification violation, which need not reflect incorrect or wrong syntax for example conflicts with sized delete method. The final sort are link or dependency errors where by a resource required to build the project cannot be found or is incompatible.

Runtime errors generally fall into 2 classes. Fatal errors which crash the program during execution, either out right or soft lock or any way where the program becomes inoperable. Then there are logical errors which manifest in incorrect behaviour of functionality and possibly have obscure trigger conditions.

Examples of compiler error fixes are commits 7893 and 7894 of standard. In 7893 a case typo with the one variable names was fixed. In 7894 a more complex language feature conflict was fixed.

Examples of runtime error fixes is commit 7892 of standard. In it a logical error with resizing of scrolled list GUI elements was fixed so that the list position updates with the scroll bar position during a resize. A fatal error involving unintended selection of invalid elements was also fixed by fixing a logic error with the list hitbox detection being mal-aligned.

Compile time errors are mostly the result of incorrect code where as runtime errors are the result of correct code that is logically incorrect.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 08, 2016, 11:43:15 PM
Thank you very much for taking time and answering about runtime and compile time errors!

Quote from: DrSuperGood on October 08, 2016, 11:03:18 PM
There appears to be two errors, one at line 127 (or above) and the other at line 385 (or above). Assuming this uses latest experimental GIT maybe a difference file would be useful for spotting what is wrong.

I have pushed a branch on my github, you can have a look here:
https://github.com/VictorErik/Simutrans-Experimental-Ves/commit/ce6ce555a8337e98b690ce7ed0b78b9489b9c914 (https://github.com/VictorErik/Simutrans-Experimental-Ves/commit/ce6ce555a8337e98b690ce7ed0b78b9489b9c914)
Thank you!
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 09, 2016, 12:49:18 AM
Line 127 variable name conflicts with a parameter from the function declaration at line 122. There are two "buf" variables in the same name space, one a function parameter the other a static variable. This is not allowed for the logical reason that the compiler has no idea which buf to use.

Rename the static buf variable, and everywhere it is used, to another name such as "buf2" or preferably something more readable.

The error at like 385 is probably due to a missing header file. It is pointing to a class type which has been declared just with the class declaration, rather than as a full class declaration like usually found in class headers. This is not allowed because the compiler has no idea about the memory layout of the class type.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 09, 2016, 10:42:50 AM
Thanks! The buffer, I have renamed, but think actually that have made its way to this file by a misstake. Commenting that out for a moment.

How do I make the error at 385 point to a full class? when rightclicking the "welt" and find definition, it takes me to simobj.cc, but that file is already defined in both the signal.cc and signal.h.

Title: Re: Clickable button in "obj_t::info" window
Post by: Dwachs on October 09, 2016, 01:24:52 PM
It seems an

#include "../simworld.h"

is missing.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 09, 2016, 01:53:41 PM
Thank you Dwachs, I included the simworld.h to signal.h, but it made no difference. Incidentally, there appears to be a simworld.h in the signal.cc file already.

Can you guys say if I approached this the right way to begin with?
Title: Re: Clickable button in "obj_t::info" window
Post by: Dwachs on October 09, 2016, 03:27:13 PM
include display/viewport.h?
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 09, 2016, 04:04:01 PM
Thank you very much, that made me come one step further!

Now the error I get is this:
Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol "public: virtual void __thiscall signal_t::info(class cbuffer_t &,bool)const " (?info@signal_t@@UBEXAAVcbuffer_t@@_N@Z) Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\signal.obj 1
Error LNK1120 1 unresolved externals Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\simutrans\Simutrans-Experimental.exe 1
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 09, 2016, 05:47:24 PM
Quote
Now the error I get is this:
Some piece of code is trying to call a method with no definition (only declared)? Hence it is unresolved since there is no code to link to.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 09, 2016, 06:45:04 PM
Thanks, however, I have a feeling that i am approaching this in the wrong way. If you where to do it, where would you start? Is it something that should be done inside the "signal_t::info" alone or is it something that must be applied on a much larger scale, ie "obj_t::info"?
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 11, 2016, 07:11:44 PM
I have tried an alternative way of making the button, which I think is a better way:

I have copied entries from convoi_frame.cc /.h to the signal.cc /.h which appears to resemble a button as well as added a signal_T::action_triggered section, which currently is empty.

The exact changes I have made can be seen in this commit on github: https://github.com/VictorErik/Simutrans-Experimental-Ves/commit/42c09e04aad90b73da3e11fda6dae6809fc622dc (https://github.com/VictorErik/Simutrans-Experimental-Ves/commit/42c09e04aad90b73da3e11fda6dae6809fc622dc)

and the errors it produce:
Severity Code Description Project File Line Suppression State
Error C3861 'add_component': identifier not found Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 377
Error C2663 'button_t::init': 2 overloads have no legal conversion for 'this' pointer Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 375
Error C2662 'void gui_action_creator_t::add_listener(action_listener_t *)': cannot convert 'this' pointer from 'const button_t' to 'gui_action_creator_t &' Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 376
Error (active) argument of type "const signal_t *" is incompatible with parameter of type "action_listener_t *" Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 376
Error (active) identifier "add_component" is undefined Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 377
Error (active) no instance of overloaded function "button_t::init" matches the argument list and object (the object has type qualifiers that prevent a match) Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 375
Error (active) the object has type qualifiers that are not compatible with the member function "gui_action_creator_t::add_listener" Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc 376


I have troubble making out the error explanations, would you mind to help me?
Title: Re: Clickable button in "obj_t::info" window
Post by: prissi on October 11, 2016, 09:11:13 PM
Back to you original purpose: Usually in Simutrans you go to the position by clicking on the world view in a disloge or you have the likke eye icon in the titlebar. Both should work without effort for things.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 11, 2016, 09:27:37 PM
Quote from: prissi on October 11, 2016, 09:11:13 PM
Back to you original purpose: Usually in Simutrans you go to the position by clicking on the world view in a disloge or you have the likke eye icon in the titlebar. Both should work without effort for things.

The purpose is still the same: In a signal window, I want a button to make the world view change to the connected signalbox's location. The world view (the picture of the object?) takes me to the signal it self and so does the little eyeview. I just currently struggle to figure out how to make the initial clickable button in the infowindow.
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 11, 2016, 09:33:04 PM
The errors seem mostly like type mismatches...

Quote
Error   C3861   'add_component': identifier not found   Simutrans-Experimental   C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc   377   
No method or function called "add_component" for this type or within the current compilation unit (the signal.cc file). You are trying to call something that does not exist. Maybe it is meant to be used on another object or an implementation added to the current type.

Quote
Error   C2663   'button_t::init': 2 overloads have no legal conversion for 'this' pointer   Simutrans-Experimental   C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc   375   
Not sure, but maybe scr_coord and scr_size cannot be resolved for this type or within the current compilation unit (the signal.cc file). Also possible the argument types mismatch the declaration of the function.

Quote
Error   C2662   'void gui_action_creator_t::add_listener(action_listener_t *)': cannot convert 'this' pointer from 'const button_t' to 'gui_action_creator_t &'   Simutrans-Experimental   C:\Users\Victor\Documents\GitHub\simutrans-experimental\obj\signal.cc   376   
Type mismatch. The "this" type is 'const button_t' while it is expecting 'gui_action_creator_t &'. You are trying to pass the function an object of a type it cannot accept.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 11, 2016, 09:45:33 PM
Thank you DrSuperGood!

How do I add the "add_component" function/method? When comparing it to where I got it from I fail to find anything special for it. If not the problem in it self is that it is used under "void signal_t::info(cbuffer_t & buf, bool dummy) const". I have taken the code from this:
convoi_frame_t::convoi_frame_t(player_t* player) :

Do you mean that it might be so that the signal_t::info..... might not be able to utilize "scr_coord" and "scr_size"? How to check that?

Regarding the last error,  how do I make it expect the "gui_action_creator_t &" instead of the "const button_t"?
Title: Re: Clickable button in "obj_t::info" window
Post by: DrSuperGood on October 11, 2016, 10:51:38 PM
I think the problem you are having is you are trying to use functions you do not understand what they are doing. Try stepping through calls to them with the debugger in a debug build to get some idea of what is going on, what values the arguments are and what the results are.

Blindly throwing code together usually does not end well and is a common cause of bugs.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 11, 2016, 11:12:44 PM
Quote from: DrSuperGood on October 11, 2016, 10:51:38 PM
I think the problem you are having is you are trying to use functions you do not understand what they are doing. Try stepping through calls to them with the debugger in a debug build to get some idea of what is going on, what values the arguments are and what the results are.

Blindly throwing code together usually does not end well and is a common cause of bugs.

I will try that!
Title: Re: Clickable button in "obj_t::info" window
Post by: TurfIt on October 12, 2016, 01:10:24 AM
Quote from: Ves on October 08, 2016, 07:09:24 PM
Is it possible to create buttons with "void signal_t::info(cbuffer_t & buf, bool dummy) const"?
No.  ::info can only handle plain text.


Quote from: Ves on October 11, 2016, 07:11:44 PM
I have copied entries from convoi_frame.cc /.h to the signal.cc /.h which appears to resemble a button as well as added a signal_T::action_triggered section, which currently is empty.
Why signal.cc/.h ?   If you want a button, ie a gui element, you need to modify the gui/* files... Specifically create a new signal_info_t class derived from obj_infowin_t.
gui/trafficlight_info.cc/.h would be a simple template - it takes the basic info win and adds the numberinputs to the bottom - replace the numberinputs with plain button.
You'll also need a signal_t::show_info to open the new window - look at roadsign_t
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 12, 2016, 01:35:23 PM
Thank you very much TurfIt! Following your steps, I have now a signal infowindow with clickable buttons!

The buttons appears now to get inside the text, but I suppose that is adjustable. Will be playing around with it for a while now!
Title: Re: Clickable button in "obj_t::info" window
Post by: Yona-TYT on October 12, 2016, 05:42:32 PM
Excellent.  ;D
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 12, 2016, 11:27:57 PM
There is a clickable button and I am working on the part that holds the magic: The actual movement of the map.

To do this, I use in the signal_info_t::action_triggered section the
welt->get_viewport()->change_world_position(koord3d(k, welt->min_hgt(k)));;
I understand that the "k" value is the one that should hold the position and that this value should be "koord".
However, I am struggling to translate the signalbox "koord3d" position to only "koord" as the "welt->get_view......" to my big confusion must have "koord" in order to work. I understand that koord is 2D coordinates and koord3d is 3D coordinates on the map?
Can you tell me how to get the "koord" value of the signalbox (a part of gebaeude_t) instead of koord3d?
Title: Re: Clickable button in "obj_t::info" window
Post by: TurfIt on October 12, 2016, 11:56:12 PM
Looking at the definition of koord3d in dataobj/koord3d.h should reveal how to convert to a koord. However, the variant of change_world_position you want takes the koord3d directly... the others are more for internal use.
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 13, 2016, 06:33:15 AM
QuoteHowever, the variant of change_world_position you want takes the koord3d directly

I think I have done the linkings right when setting it up like this:
bool signal_info_t::action_triggered( gui_action_creator_t *comp, value_t)
{
if (comp == &signalbox_button)
{
signal_t* sig = (signal_t*)this;
koord3d sb = sig->get_signalbox();
welt->get_viewport()->change_world_position(koord3d(sb, welt->min_hgt(sb)));;
return true;
}
}

"koord3d sb = sig->get_signalbox();" is already used elsewhere by Jamespetts to find the coordinates of the signalbox.

However the error produced is the following:
Severity Code Description Project File Line Suppression State Detail Description
Error C2664 'sint8 karte_t::min_hgt(koord) const': cannot convert argument 1 from 'koord3d' to 'koord' Simutrans-Experimental C:\Users\Victor\Documents\GitHub\simutrans-experimental\gui\signal_info.cc 47
Error (active) no instance of constructor "koord3d::koord3d" matches the argument list Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\gui\signal_info.cc 47             argument types are: (koord3d, sint8)
Error (active) no suitable user-defined conversion from "koord3d" to "koord" exists Simutrans-Experimental c:\Users\Victor\Documents\GitHub\simutrans-experimental\gui\signal_info.cc 47

Title: Re: Clickable button in "obj_t::info" window
Post by: TurfIt on October 14, 2016, 01:36:07 AM
Quote from: Ves on October 13, 2016, 06:33:15 AM
bool signal_info_t::action_triggered(
signal_t* sig = (signal_t*)this;

What makes you think you can turn a signal_info_t* into a signal_t*  ?   i.e. 'this' is a signal_info_t* in the context.


signal_info_t should be something like:

class signal_info_t : public obj_infowin_t, public action_listener_t
{
private:
signal_t* sig;
        button_t  signalbox_button;

public:
signal_info_t(signal_t* s);
...


with the constructor:

signal_info_t::signal_info_t(signal_t* s) :
obj_infowin_t(s),
sig(s)
{
...


then when you open the dialog with:

void signal_t::show_info()
{
create_win(new signal_info_t(this), w_info, (ptrdiff_t)this );
...


you can use:

bool signal_info_t::action_triggered( gui_action_creator_t *comp, value_t)
{
if (comp == &signalbox_button)
{
welt->get_viewport()->change_world_position( sig->get_signalbox() );
...


Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 14, 2016, 07:34:03 AM
Thank you very much for taking the time and explain what is needed. It is very helpful! I am going away for almost a week, but I will test it when I get back again!
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 21, 2016, 08:10:52 PM
Thank you TurfIt, It now WORKS! Clicking the button now changes the world position to the signalbox that is controlling said signal!

I could not use your sollution directly, I had to modify the following bit:

koord3d sb = sig->get_signalbox();
welt->get_viewport()->change_world_position(koord3d(sb));


Copy pasting your sollution directly generated an error on the "welt->get_vie....." line that a "&" was missing somewhere.
After messing a bit around, I came up with the above which works as intended!


My next mission is to make the button appear where I want it to: The last entry in the window on the same line with the name of the signalbox.
I guess there are several ways to achieve this:

1 - Make only the button in the signal_info_t and all the text in signal_t -> difficulties: How to count the lines so the button appears on the correct line? Also, there might be some gui theme related issues with this approach?

2 - Make also the signalbox name be displayed from signal_info_t -> difficulties: As above, how to count the number of lines so the entry appears on the correct line? Also, when writing "buf.append(.....)" in signal_info_t creates no texts whatsoever. I guess there need to be something defined?

3 - Move the entire section, containing the entire infowindow, to signal_info_t. Somehow this feels more right, but is it too big a thing to do just to achieve a button? Again, "buf.append" probably needs something defined.


Regarding option 1 and 2, I guess the "LINESPACE" is to be used. But how to count the number of lines in the first place?
Thanks for your help!
Title: Re: Clickable button in "obj_t::info" window
Post by: Ves on October 26, 2016, 11:37:57 PM
I found out that I could use get_windowsize() and subtract the needed amount in order to make the button always appear at the bottom, so now that dialog is actually fully working and finnish! :D

If I would want to add a button inside the text, however, would there be any way to make the button "float" together with the text? Im not concerned with the text underneath the button (as I can always use "/n" where the button is located) however, make the button not static to the window would be of huge benefits!