show navigable buttons linking to callers and callees

This commit is contained in:
2025-08-31 14:38:48 -05:00
parent c4f2c2cb9d
commit 12d834fdee
4 changed files with 89 additions and 4 deletions

View File

@@ -6,7 +6,7 @@
<text name='title' size='large' top='6' left='50' width='158' height='16'>Edit Special Node</text>
<text top='8' left='222' width='90' height='14'>Node number:</text>
<text name='num' top='8' left='314' width='38' height='14'/>
<text top='147' left='469' width='125' height='124'>
<text name='tip' top='147' left='519' width='125'>
Enter properties for this special encounter node.
For a detailed description of how this window works, see the documentation.
</text>
@@ -124,4 +124,31 @@
<button name='okay' type='regular' top='494' left='522'>OK</button>
<button name='cancel' type='regular' top='494' left='456'>Cancel</button>
<button name='back' type='large' top='494' left='10'>Go Back</button>
<text name='cb' relative='pos-in pos' anchor='tip' top='8' left='0'>Called By</text>
<text relative='pos-in pos' anchor='tip' top='8' left='100'>Calls</text>
<!-- There is NO limit to how many things could call a node. Only the designor's sanity.
But let's hope this is enough for most cases. -->
<button name='calledby0' type='tiny' relative='pos-in pos' anchor='cb' top='2' left='0'/>
<button name='calledby1' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby2' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby3' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby4' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby5' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby6' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby7' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby8' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby9' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby10' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby11' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby12' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calledby13' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<!-- There is a limit to how many nodes a node can call. I think it's 3, for the
if-elseif-else conditionals. -->
<button name='calls0' type='tiny' relative='pos-in pos' anchor='cb' top='2' left='100'/>
<button name='calls1' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calls2' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<button name='calls3' type='tiny' relative='pos-in pos' rel-anchor='prev' top='4' left='0'/>
<text name='tooltip' framed='true' ellipsis='true' width='200' height='24' relative='pos-in pos' anchor='calledby13' top='4' left='0'>Editor hint</text>
</dialog>

View File

@@ -1121,7 +1121,7 @@ short cSpecial::get(eSpecField fld) {
}
}
static cSpecial* get_spec_ref(cScenario& scenario, node_stack_t& stack, size_t which, int town_num_or_out_x = -1, int out_y = -1) {
cSpecial* get_spec_ref(cScenario& scenario, node_stack_t& stack, size_t which, int town_num_or_out_x, int out_y) {
int mode = (out_y >= 0 ? 1 : (town_num_or_out_x >= 0 ? 2 : 0));
for(auto it = stack.rbegin(); it != stack.rend(); ++it){
if(it->mode == mode && it->which == which)

View File

@@ -140,6 +140,7 @@ struct editing_node_t {
typedef std::vector<editing_node_t> node_stack_t;
cSpecial* get_spec_ref(cScenario& scenario, node_stack_t& stack, size_t which, int town_num_or_out_x = -1, int out_y = -1);
std::vector<graph_node_t> global_node_graph(cScenario& scenario, node_stack_t& edit_stack);
std::vector<graph_node_t> local_node_graph(cScenario& scenario, node_stack_t& edit_stack, int town_num_or_out_x, int out_y = -1);

View File

@@ -804,6 +804,31 @@ static void setup_node_field(cDialog& me, std::string field, short value, const
}
}
static std::string label(node_id_t id) {
std::string lbl = std::to_string(id.which);
if(id.town_num_or_out_x < 0) lbl = "G" + lbl;
else if(id.out_y < 0) lbl = "T" + lbl;
else lbl = "O" + lbl;
return lbl;
}
static void put_spec_enc_in_dlog(cDialog& me, node_stack_t& edit_stack);
static void push_spec_enc_in_stack(cDialog& me, node_stack_t& edit_stack, node_id_t id) {
cSpecial* spec = get_spec_ref(scenario, edit_stack, id.which, id.town_num_or_out_x, id.out_y);
if(spec == nullptr){
throw std::string{"This should never happen"};
}
editing_node_t stack_frame;
stack_frame.which = id.which;
stack_frame.mode = (id.out_y >= 0 ? 1 : (id.town_num_or_out_x >= 0 ? 2 : 0));
stack_frame.node = *spec;
stack_frame.is_new = false;
edit_stack.push_back(stack_frame);
me["back"].show();
put_spec_enc_in_dlog(me, edit_stack);
}
static void put_spec_enc_in_dlog(cDialog& me, node_stack_t& edit_stack) {
cSpecial& spec = edit_stack.back().node;
@@ -820,11 +845,43 @@ static void put_spec_enc_in_dlog(cDialog& me, node_stack_t& edit_stack) {
std::vector<graph_node_t> locals = local_node_graph(scenario, edit_stack, cur_town);
which = locals[edit_stack.back().which];
}
int i = 0;
for(node_id_t from_id : which.from_nodes){
LOG(fmt::format("({}, {}, {}) -> ({}, {}, {})", from_id.which, from_id.town_num_or_out_x, from_id.out_y, which.id.which, which.id.town_num_or_out_x, which.id.out_y));
if(me.hasControl(fmt::format("calledby{}", i))){
me[fmt::format("calledby{}", i)].setText(label(from_id));
me[fmt::format("calledby{}", i)].show();
// TODO setTooltipText
me[fmt::format("calledby{}", i)].attachClickHandler([from_id, &edit_stack](cDialog& me, std::string, eKeyMod) -> bool {
push_spec_enc_in_stack(me, edit_stack, from_id);
return true;
});
}else{
LOG("Warning! Ran out of buttons to show callers!");
break;
}
++i;
}
for(; me.hasControl(fmt::format("calledby{}", i)); ++i){
me[fmt::format("calledby{}", i)].hide();
}
i = 0;
for(node_id_t to_id : which.to_nodes){
LOG(fmt::format("({}, {}, {}) -> ({}, {}, {})", which.id.which, which.id.town_num_or_out_x, which.id.out_y, to_id.which, to_id.town_num_or_out_x, to_id.out_y));
if(me.hasControl(fmt::format("calls{}", i))){
me[fmt::format("calls{}", i)].setText(label(to_id));
me[fmt::format("calls{}", i)].show();
// TODO setTooltipText
me[fmt::format("calls{}", i)].attachClickHandler([to_id, &edit_stack](cDialog& me, std::string, eKeyMod) -> bool {
push_spec_enc_in_stack(me, edit_stack, to_id);
return true;
});
}else{
LOG("Warning! Ran out of buttons to show nodes it calls!");
break;
}
++i;
}
for(; me.hasControl(fmt::format("calls{}", i)); ++i){
me[fmt::format("calls{}", i)].hide();
}
// Show which node is being edited and what type of node it is