diff --git a/gui/components/sortable_table.cc b/gui/components/sortable_table.cc index b818ff9e60..010a0e9145 100644 --- a/gui/components/sortable_table.cc +++ b/gui/components/sortable_table.cc @@ -12,6 +12,7 @@ #include "../../simworld.h" #include "../../simcolor.h" #include "../../display/simgraph.h" +#include "../../display/viewport.h" #include "../../dataobj/translator.h" @@ -61,11 +62,12 @@ void table_cell_item_t::draw(scr_coord offset) -text_cell_t::text_cell_t(const char* text_, PIXVAL col, align_t align_) +text_cell_t::text_cell_t(const char* text_, PIXVAL col, align_t align_, bool underlined_) { text= text_; color= col; align=align_; + underlined = underlined_; min_size = scr_size(proportional_string_width(translator::translate(text)), LINESPACE); set_size(min_size); } @@ -76,22 +78,74 @@ void text_cell_t::draw(scr_coord offset) offset+=pos; display_proportional_clip_rgb(offset.x+ draw_offset.x, offset.y+ draw_offset.y, translator::translate(text), ALIGN_LEFT, color, false); + if (underlined) { + display_fillbox_wh_clip_rgb(offset.x + draw_offset.x, offset.y + draw_offset.y + LINESPACE-1, min_size.w, 1, color, false); + } } -coord_cell_t::coord_cell_t(const char* text, koord coord_, PIXVAL color, align_t align) - : text_cell_t((text==NULL && coord_!=koord::invalid) ? coord.get_fullstr() : text, color, align) + +coord_cell_t::coord_cell_t(const char* alt_text, koord coord_, align_t align_) { coord = coord_; - min_size = scr_size(proportional_string_width(translator::translate(get_text())), LINESPACE); + align = align_; + if (alt_text != NULL) { + buf.printf("%s", alt_text); + } + else { + buf.append("-"); + } + min_size = scr_size(proportional_string_width(buf), LINESPACE); set_size(min_size); } +coord_cell_t::coord_cell_t(koord coord_, align_t align_) +{ + coord = coord_; + align = align_; + if (coord != koord::invalid) { + buf.printf("%s", coord.get_str()); + show_posicon = true; + } + else { + buf.append("-"); + } + min_size = scr_size(proportional_string_width(buf) + (D_POS_BUTTON_WIDTH + 2) * show_posicon, show_posicon ? max(LINESPACE, D_POS_BUTTON_HEIGHT) : LINESPACE); + set_size(min_size); +} -value_cell_t::value_cell_t(sint64 value_, gui_chart_t::chart_suffix_t suffix, align_t align_, PIXVAL col) +void coord_cell_t::draw(scr_coord offset) +{ + table_cell_item_t::draw(offset); + + offset += pos; + PIXVAL text_col= SYSCOL_TEXT; + if (world()->get_viewport()->get_world_position() == coord) { + text_col=SYSCOL_TEXT_HIGHLIGHT; + if (show_posicon){ + display_color_img(skinverwaltung_t::posbutton->get_image_id(SKIN_BUTTON_POS_PRESSED), offset.x + draw_offset.x, offset.y + (size.h-D_POS_BUTTON_HEIGHT)/2, 0, false, false); + } + } + display_proportional_clip_rgb(offset.x + draw_offset.x + (D_POS_BUTTON_WIDTH+2) * show_posicon, offset.y + draw_offset.y, buf, ALIGN_LEFT, text_col, false); + if (coord != koord::invalid) { + display_fillbox_wh_clip_rgb(offset.x + draw_offset.x + (D_POS_BUTTON_WIDTH + 2) * show_posicon, offset.y + draw_offset.y + LINESPACE - 1, min_size.w - (D_POS_BUTTON_WIDTH + 2) * show_posicon, 1, text_col, false); + } +} + + +value_cell_t::value_cell_t(sint64 value_, gui_chart_t::chart_suffix_t suffix_, align_t align_, PIXVAL col) { color = col; align = align_; - value=value_; + suffix= suffix_; + + set_value(value_); + set_size(min_size); +} + +void value_cell_t::set_value(sint64 value_) +{ + value = value_; + buf.clear(); switch(suffix) { @@ -173,7 +227,10 @@ value_cell_t::value_cell_t(sint64 value_, gui_chart_t::chart_suffix_t suffix, al break; } min_size = scr_size(proportional_string_width(buf), LINESPACE); - set_size(min_size); + if (min_size.w> (size.w - L_CELL_PADDING*2) ) { + dbg->warning("value_cell_t::set_value", "Cell's text width has been changed to %i, exceeding the column width of %i.", min_size.w, size.w); + } + set_width(size.w - L_CELL_PADDING*2); // recalc draw_offset.x } void value_cell_t::draw(scr_coord offset) @@ -185,21 +242,27 @@ void value_cell_t::draw(scr_coord offset) } -values_cell_t::values_cell_t(sint64 value_, sint64 sub_value_, PIXVAL col) - : value_cell_t(value_) +values_cell_t::values_cell_t(sint64 value_, sint64 sub_value_, PIXVAL col, bool single_line_) { - buf.clear(); - sub_buf.clear(); - color = col; min_size.h = LINESPACE; align = centered; + single_line = single_line_; + + set_values(value_, sub_value_); + + set_size(min_size); +} - sub_value=sub_value_; +void values_cell_t::set_values(sint64 value_, sint64 sub_value_) +{ + value = value_; + sub_value = sub_value_; - bool two_lines = false; + buf.clear(); + sub_buf.clear(); - if (value==0 && sub_value==0) { + if (value == 0 && sub_value == 0) { buf.append("-"); color = SYSCOL_TEXT_WEAK; } @@ -208,31 +271,40 @@ values_cell_t::values_cell_t(sint64 value_, sint64 sub_value_, PIXVAL col) } if (sub_value != 0) { if (value != 0) { - // display two lines - sub_buf.printf("(%i)", sub_value); - min_size.h += LINESPACE; - two_lines = true; + if (single_line) { + buf.printf(" (%i)", sub_value); + } + else { + // display two lines + sub_buf.printf("(%i)", sub_value); + min_size.h += LINESPACE; + sub_draw_offset_x = proportional_string_width(sub_buf) / 2; + min_size.w = max(proportional_string_width(buf), sub_draw_offset_x * 2 + 1); + } } else { buf.printf("(%i)", sub_value); } } - if (two_lines) { - sub_draw_offset_x = proportional_string_width(sub_buf) / 2; - min_size.w = max(proportional_string_width(buf), sub_draw_offset_x * 2 + 1); - } - else { + if (single_line) { min_size.w = proportional_string_width(buf); } - set_size(min_size); + if (min_size.w > (size.w - L_CELL_PADDING * 2)) { + dbg->warning("values_cell_t::set_value", "Cell's text width has been changed to %i, exceeding the column width of %i.", min_size.w, size.w); + } + set_width(size.w - L_CELL_PADDING * 2); // recalc draw_offset.x } void values_cell_t::set_width(scr_coord_val new_width) { - const scr_coord_val row1_width = proportional_string_width(buf); - size.w = new_width + L_CELL_PADDING * 2; - draw_offset.x = (size.w - row1_width) / 2; + if (single_line) { + draw_offset.x = (size.w - min_size.w) / 2; + } + else { + draw_offset.x = (size.w - proportional_string_width(buf)) / 2; + } + } void values_cell_t::draw(scr_coord offset) @@ -320,6 +392,19 @@ int gui_sort_table_row_t::compare_text(const table_cell_item_t* a, const table_c return STRICMP(a_text, b_text); } +int gui_sort_table_row_t::compare_coord(const table_cell_item_t* a, const table_cell_item_t* b) +{ + int cmp = 0; + const coord_cell_t* cell_a = dynamic_cast(a); + const coord_cell_t* cell_b = dynamic_cast(b); + cmp = cell_a->get_coord().x - cell_b->get_coord().x; + if (cmp == 0) { + cmp = cell_a->get_coord().y - cell_b->get_coord().y; + } + return cmp; +} + + int gui_sort_table_row_t::compare(const table_cell_item_t* a, const table_cell_item_t* b) { sint64 cmp = 0; @@ -336,6 +421,9 @@ int gui_sort_table_row_t::compare(const table_cell_item_t* a, const table_cell_i case table_cell_item_t::cell_text: cmp = gui_sort_table_row_t::compare_text(a, b); break; + case table_cell_item_t::cell_coord: + cmp = gui_sort_table_row_t::compare_coord(a, b); + break; case table_cell_item_t::cell_no_sorting: default: // nothing to do diff --git a/gui/components/sortable_table.h b/gui/components/sortable_table.h index f545b6702b..92da9d66ee 100644 --- a/gui/components/sortable_table.h +++ b/gui/components/sortable_table.h @@ -26,7 +26,8 @@ class table_cell_item_t : virtual public gui_component_t cell_no_sorting = 0, cell_value = 1, cell_values = 2, - cell_text = 3 + cell_text = 3, + cell_coord = 4 }; enum align_t { @@ -65,10 +66,11 @@ class text_cell_t : public table_cell_item_t { const char* text; // only for direct access of non-translatable things. Do not use! PIXVAL color; + bool underlined; // bool is_bold; public: - text_cell_t(const char* text = NULL, PIXVAL color = SYSCOL_TEXT, align_t align = left); + text_cell_t(const char* text = NULL, PIXVAL color = SYSCOL_TEXT, align_t align = left, bool underlined = false); const uint8 get_type() const OVERRIDE { return cell_text; } @@ -79,14 +81,21 @@ class text_cell_t : public table_cell_item_t // Hold the coordinates and click a cell to jump to the coordinates. -class coord_cell_t : public text_cell_t +class coord_cell_t : public table_cell_item_t { koord coord; + cbuffer_t buf; + bool show_posicon=false; public: - coord_cell_t(const char* text = NULL, koord coord=koord::invalid, PIXVAL color = SYSCOL_TEXT, align_t align = left); + coord_cell_t(const char* alt_text = NULL, koord coord=koord::invalid, align_t align = left); + coord_cell_t(koord coord = koord::invalid, align_t align = left); koord get_coord() const { return coord; } + + const uint8 get_type() const OVERRIDE { return cell_coord; } + + void draw(scr_coord offset) OVERRIDE; }; @@ -94,6 +103,7 @@ class coord_cell_t : public text_cell_t // Can specify a suffix. class value_cell_t : public table_cell_item_t { + gui_chart_t::chart_suffix_t suffix; protected: cbuffer_t buf; PIXVAL color; @@ -103,8 +113,13 @@ class value_cell_t : public table_cell_item_t public: value_cell_t(sint64 value, gui_chart_t::chart_suffix_t suffix= gui_chart_t::STANDARD, align_t align = left, PIXVAL color = SYSCOL_TEXT); + // When resetting the value, care must be taken not to increase the column width. + virtual void set_value(sint64 value); + sint64 get_value() const { return value; } + void set_color(PIXVAL color_) { color = color_; } + const uint8 get_type() const OVERRIDE { return cell_value; } void draw(scr_coord offset) OVERRIDE; @@ -112,18 +127,25 @@ class value_cell_t : public table_cell_item_t // The cell holds two values for sorting // There is no suffix -class values_cell_t : public value_cell_t +class values_cell_t : public table_cell_item_t { protected: - cbuffer_t sub_buf; - sint64 sub_value; + cbuffer_t buf, sub_buf; + PIXVAL color; + sint64 value, sub_value; scr_coord_val sub_draw_offset_x = 0; + bool single_line; public: - values_cell_t(sint64 value, sint64 sub_value, PIXVAL color = SYSCOL_TEXT); + // single_line: Displaying two values ​​on the same line + values_cell_t(sint64 value, sint64 sub_value, PIXVAL color = SYSCOL_TEXT, bool single_line=false); void set_width(scr_coord_val new_width) OVERRIDE; + // When resetting the value, care must be taken not to increase the column width. + void set_values(sint64 value, sint64 sub_value=0); + + sint64 get_value() const { return value; } sint64 get_sub_value() const { return sub_value; } const uint8 get_type() const OVERRIDE { return cell_values; } @@ -138,6 +160,7 @@ class gui_sort_table_row_t : public gui_container_t, public gui_scrolled_list_t: static sint64 compare_value(const table_cell_item_t* a, const table_cell_item_t* b); static sint64 compare_values(const table_cell_item_t* a, const table_cell_item_t* b); static int compare_text(const table_cell_item_t* a, const table_cell_item_t* b); + static int compare_coord(const table_cell_item_t* a, const table_cell_item_t* b); protected: diff --git a/gui/components/sortable_table_header.cc b/gui/components/sortable_table_header.cc index 984faf3274..5df5db4064 100644 --- a/gui/components/sortable_table_header.cc +++ b/gui/components/sortable_table_header.cc @@ -129,7 +129,7 @@ bool gui_sort_table_header_t::infowin_event(const event_t* ev) { bool swallowed = gui_container_t::infowin_event(ev); - if (IS_LEFTRELEASE(ev) && getroffen(ev->mouse_pos)) { + if (!swallowed && IS_LEFTRELEASE(ev) && getroffen(ev->mouse_pos)) { uint idx=0; for (auto& cell : owned_cells) { if (cell->getroffen(ev->mouse_pos)) { diff --git a/gui/signalboxlist_frame.cc b/gui/signalboxlist_frame.cc index c6522846ac..97deba1a8c 100644 --- a/gui/signalboxlist_frame.cc +++ b/gui/signalboxlist_frame.cc @@ -3,231 +3,199 @@ #include "signalboxlist_frame.h" #include "gui_theme.h" -#include "../simsignalbox.h" #include "../simskin.h" +#include "../simcity.h" #include "../dataobj/translator.h" #include "../descriptor/skin_desc.h" #include "../descriptor/building_desc.h" #include "../utils/simstring.h" +#include "../display/viewport.h" -enum sort_mode_t { by_type, by_coord, by_connected, by_capacity, by_radius, by_region, by_built_in, SORT_MODES }; -int signalboxlist_stats_t::sort_mode = by_connected; -bool signalboxlist_stats_t::reverse = false; -uint16 signalboxlist_stats_t::name_width = D_LABEL_WIDTH; +static const char* const sb_header_text[signalboxlist_row_t::MAX_COLS] = +{ + "sb_type", + "sb_connected", + "Max. signals", + "Radius", + "koord", "by_region", "City", "Fixed Costs", "Built in" +}; + +int signalboxlist_row_t::sort_mode = SB_BUILT_DATE; +bool signalboxlist_row_t::sortreverse = false; bool signalboxlist_frame_t::filter_has_vacant_slot = false; static karte_ptr_t welt; -signalboxlist_stats_t::signalboxlist_stats_t(signalbox_t *sb) + +signalbox_radius_cell_t::signalbox_radius_cell_t(uint32 radius) + : value_cell_t((sint64)radius, gui_chart_t::DISTANCE, centered) { - this->sb = sb; - // pos button - set_table_layout(6,1); - gotopos.set_typ(button_t::posbutton_automatic); - gotopos.set_targetpos(sb->get_pos().get_2d()); - add_component(&gotopos); - label.set_min_size(scr_size(D_LABEL_WIDTH * 3 / 2, D_LABEL_HEIGHT)); - add_component(&label); - - add_component(&lb_connected); - add_component(&lb_radius); - add_component(&lb_region); - new_component(); - - update_label(); + set_value(radius); + set_size(min_size); } - -void signalboxlist_stats_t::update_label() +void signalbox_radius_cell_t::set_value(sint64 value_) { - // name - cbuffer_t &buf = label.buf(); - buf.append( translator::translate(sb->get_name()) ); - const scr_coord_val temp_w = proportional_string_width(translator::translate(sb->get_name())); - if (temp_w > name_width) { - name_width = temp_w; - } - label.update(); - - // connected / capacity - lb_connected.buf().printf(" %3d/%3d,", - sb->get_number_of_signals_controlled_from_this_box(), sb->get_capacity() ); - lb_connected.update(); + value = value_; + buf.clear(); - // signalbox radius - uint32 radius = sb->get_tile()->get_desc()->get_radius(); - if (radius == 0) { - lb_radius.buf().append(translator::translate("infinite_range")); + if (value == 0) { + buf.append(translator::translate("infinite_range")); } - else if (radius < 1000) { - lb_radius.buf().append(radius); - lb_radius.buf().append("m"); + else if (value < 1000) { + buf.append(value); + buf.append("m"); } else { - const double max_dist = (double)radius / 1000; - const uint8 n_max = max_dist < 20 ? 1 : 0; - char number_max[10]; - number_to_string(number_max, max_dist, n_max); - lb_radius.buf().append(number_max); - lb_radius.buf().append("km"); + const uint8 digit = value < 20000 ? 1 : 0; + buf.append((double)value / 1000.0, digit); + buf.append("km"); } - lb_radius.buf().append(" "); - lb_radius.update(); - - // region name (pos) - if (!welt->get_settings().regions.empty()) { - lb_region.buf().printf("%s ", translator::translate(welt->get_region_name(sb->get_pos().get_2d()).c_str())); - } - lb_region.buf().printf("%s", sb->get_pos().get_2d().get_fullstr()); - lb_region.update(); + min_size = scr_size(proportional_string_width(buf), LINESPACE); + set_width(size.w - L_CELL_PADDING * 2); // recalc draw_offset.x } - -void signalboxlist_stats_t::set_size(scr_size size) +signalboxlist_row_t::signalboxlist_row_t(signalbox_t *sb) { - gui_aligned_container_t::set_size(size); - label.set_fixed_width(name_width); -} + assert(sb != NULL); + this->sb = sb; + // 1. name + new_component(sb->get_name()); + // 2. connected + old_connected = sb->get_number_of_signals_controlled_from_this_box(); + const uint16 sb_capacity = sb->get_capacity(); + new_component((sint64)old_connected, gui_chart_t::STANDARD, table_cell_item_t::right, old_connected==sb_capacity ? COL_DANGER : COL_SAFETY); + // 3. capacity (static) + new_component((sint64)sb_capacity, gui_chart_t::STANDARD, table_cell_item_t::right); + // 4. radius + new_component((sint64)sb->get_tile()->get_desc()->get_radius()); + // 5. coord + const koord sb_pos = sb->get_pos().get_2d(); + new_component(sb_pos, table_cell_item_t::centered); + // 6. region + new_component(welt->get_settings().regions.empty() ? "" : translator::translate(welt->get_region_name(sb_pos).c_str())); + // 7. city + stadt_t* c = welt->get_city(sb_pos); + new_component(c ? c->get_name() : "-", c ? c->get_center() : koord::invalid); + // 8. Fixed Costs + sint64 maintenance = sb->get_tile()->get_desc()->get_maintenance(); + if (maintenance == PRICE_MAGIC) + { + maintenance = sb->get_tile()->get_desc()->get_level() * welt->get_settings().maint_building; + } + new_component((double)welt->calc_adjusted_monthly_figure(maintenance), gui_chart_t::MONEY, table_cell_item_t::right); + // 9. Built date + new_component((sint64)sb->get_purchase_time(), gui_chart_t::DATE, table_cell_item_t::right); -bool signalboxlist_stats_t::is_valid() const -{ - return signalbox_t::all_signalboxes.is_contained(sb); + // init cells height + for (auto& cell : owned_cells) { + cell->set_height(row_height); + } } - -bool signalboxlist_stats_t::infowin_event(const event_t * ev) +void signalboxlist_row_t::draw(scr_coord offset) { - bool swallowed = gui_aligned_container_t::infowin_event(ev); - - if( !swallowed && IS_LEFTRELEASE(ev) ) { - sb->show_info(); - swallowed = true; + if (old_connected != sb->get_number_of_signals_controlled_from_this_box()) { + old_connected = sb->get_number_of_signals_controlled_from_this_box(); + value_cell_t* cell = dynamic_cast(owned_cells[SB_CONNECTED]); + cell->set_value((sint64)old_connected); + cell->set_color( old_connected==sb->get_capacity() ? COL_DANGER : COL_SAFETY); } - return swallowed; + gui_sort_table_row_t::draw(offset); } - -void signalboxlist_stats_t::draw(scr_coord pos) +bool signalboxlist_row_t::infowin_event(const event_t* ev) { - update_label(); - - gui_aligned_container_t::draw(pos); + bool swallowed = gui_scrolled_list_t::scrollitem_t::infowin_event(ev); + if (!swallowed && sb) { + if (IS_RIGHTRELEASE(ev)) { + for (auto& cell : owned_cells) { + if (cell->get_type() == table_cell_item_t::cell_coord && cell->getroffen(ev->mouse_pos)) { + const coord_cell_t* coord_cell = dynamic_cast(cell); + const koord k = coord_cell->get_coord(); + if (k != koord::invalid) { + world()->get_viewport()->change_world_position(k); + return true; + } + return false; + } + } + } + } + return swallowed; } - -bool signalboxlist_stats_t::compare(const gui_component_t *aa, const gui_component_t *bb) +bool signalboxlist_row_t::compare(const gui_component_t* aa, const gui_component_t* bb) { - const signalboxlist_stats_t* fa = dynamic_cast(aa); - const signalboxlist_stats_t* fb = dynamic_cast(bb); - // good luck with mixed lists - assert(fa != NULL && fb != NULL); - signalbox_t *a=fa->sb, *b=fb->sb; - - int cmp; - switch( sort_mode ) { - default: - case by_type: - { - const char* a_name = translator::translate(a->get_name()); - const char* b_name = translator::translate(b->get_name()); - cmp = STRICMP(a_name, b_name); - break; - } - case by_coord: - cmp = 0; - break; - case by_connected: - cmp = a->get_number_of_signals_controlled_from_this_box() - b->get_number_of_signals_controlled_from_this_box(); - break; - case by_capacity: - cmp = a->get_first_tile()->get_tile()->get_desc()->get_capacity() - b->get_first_tile()->get_tile()->get_desc()->get_capacity(); - break; - case by_radius: - cmp = a->get_first_tile()->get_tile()->get_desc()->get_radius() - b->get_first_tile()->get_tile()->get_desc()->get_radius(); - break; - case by_region: - cmp = welt->get_region(a->get_pos().get_2d()) - welt->get_region(b->get_pos().get_2d()); - break; - case by_built_in: - cmp = a->get_first_tile()->get_purchase_time() - b->get_first_tile()->get_purchase_time(); - break; + const signalboxlist_row_t* row_a = dynamic_cast(aa); + const signalboxlist_row_t* row_b = dynamic_cast(bb); + if (row_a == NULL || row_b == NULL) { + dbg->warning("signalboxlist_row_t::compare()", "row data error"); + return false; } - if (cmp == 0) { - cmp = koord_distance( a->get_pos(), koord( 0, 0 ) ) - koord_distance( b->get_pos(), koord( 0, 0 ) ); - if( cmp == 0 ) { - cmp = a->get_pos().x - b->get_pos().x; - } + + const table_cell_item_t* a = row_a->get_element(sort_mode); + const table_cell_item_t* b = row_b->get_element(sort_mode); + if (a == NULL || b == NULL) { + dbg->warning("depotlist_row_t::compare()", "Could not get table_cell_item_t successfully"); + return false; } - return reverse ? cmp > 0 : cmp < 0; + int cmp = gui_sort_table_row_t::compare(a, b); + return sortreverse ? cmp < 0 : cmp > 0; // Do not include 0 } - -static const char *sort_text[SORT_MODES] = { - "sb_type", - "koord", - "sb_connected", - "Max. signals", - "Radius", - "by_region", - "Built in" -}; - signalboxlist_frame_t::signalboxlist_frame_t(player_t *player) : gui_frame_t( translator::translate("sb_title"), player ), - scrolly(gui_scrolled_list_t::windowskin, signalboxlist_stats_t::compare) + scrolly(gui_scrolled_list_t::windowskin, signalboxlist_row_t::compare), + scroll_sortable(&cont_sortable, true, true) { this->player = player; last_signalbox_count = 0; + scrolly.add_listener(this); + scrolly.set_show_scroll_x(false); + scrolly.set_checkered(true); + scroll_sortable.set_maximize(true); + scrolly.set_scroll_amount_y(LINESPACE + D_H_SPACE + 2); // default cell height + + // init table sort buttons + table_header.add_listener(this); + for (uint8 col = 0; col < signalboxlist_row_t::MAX_COLS; col++) { + table_header.new_component(sb_header_text[col]); + } + cont_sortable.set_margin(NO_SPACING, NO_SPACING); + cont_sortable.set_spacing(NO_SPACING); + cont_sortable.set_table_layout(1, 2); + cont_sortable.set_alignment(ALIGN_TOP); // Without this, the layout will be broken if the height is small. + cont_sortable.add_component(&table_header); + cont_sortable.add_component(&scrolly); + set_table_layout(1,0); - add_table(2,2); + add_table(3,1); { - new_component("hl_txt_sort"); new_component("Filter:"); - add_table(3,1); - { - sortedby.clear_elements(); - for (int i = 0; i < SORT_MODES; i++) { - sortedby.new_component(translator::translate(sort_text[i]), SYSCOL_TEXT); - } - sortedby.set_selection(signalboxlist_stats_t::sort_mode); - sortedby.set_width_fixed(true); - sortedby.set_size(scr_size(D_WIDE_BUTTON_WIDTH, D_EDIT_HEIGHT)); - sortedby.add_listener(this); - add_component(&sortedby); - - // sort asc/desc switching button - sort_order.init(button_t::sortarrow_state, ""); - sort_order.set_tooltip(translator::translate("hl_btn_sort_order")); - sort_order.add_listener(this); - sort_order.pressed = signalboxlist_stats_t::reverse; - add_component(&sort_order); - - new_component(LINESPACE); - } - end_table(); filter_vacant_slot.init(button_t::square_state, "Vacant slot"); filter_vacant_slot.set_tooltip("helptxt_filter_sb_has_vacant_slot"); filter_vacant_slot.add_listener(this); filter_vacant_slot.pressed = filter_has_vacant_slot; add_component(&filter_vacant_slot); + + new_component(LINESPACE*10); } end_table(); - add_component(&scrolly); + add_component(&scroll_sortable); + set_min_windowsize(scr_size(LINESPACE * 24, LINESPACE * 12)); fill_list(); set_resizemode(diagonal_resize); - scrolly.set_maximize(true); - scrolly.set_checkered(true); - reset_min_windowsize(); } @@ -236,20 +204,22 @@ signalboxlist_frame_t::signalboxlist_frame_t(player_t *player) : */ bool signalboxlist_frame_t::action_triggered( gui_action_creator_t *comp,value_t v) { - if(comp == &sortedby) { - signalboxlist_stats_t::sort_mode = max(0, v.i); - scrolly.sort(0); - } - else if (comp == &sort_order) { - signalboxlist_stats_t::reverse = !signalboxlist_stats_t::reverse; - scrolly.sort(0); - sort_order.pressed = signalboxlist_stats_t::reverse; - } - else if (comp == &filter_vacant_slot) { + if (comp == &filter_vacant_slot) { filter_has_vacant_slot = !filter_has_vacant_slot; filter_vacant_slot.pressed = filter_has_vacant_slot; fill_list(); } + else if (comp == &table_header) { + signalboxlist_row_t::sort_mode = v.i; + table_header.set_selection(signalboxlist_row_t::sort_mode); + signalboxlist_row_t::sortreverse = table_header.is_reversed(); + scrolly.sort(0); + } + else if (comp == &scrolly) { + scrolly.get_selection(); + signalboxlist_row_t* row = (signalboxlist_row_t*)scrolly.get_element(v.i); + row->show_info(); + } return true; } @@ -263,13 +233,43 @@ void signalboxlist_frame_t::fill_list() } if(sigb->get_owner() == player && sigb->get_first_tile() == sigb ) { - scrolly.new_component( sigb ); + scrolly.new_component( sigb ); } } scrolly.sort(0); scrolly.set_size( scrolly.get_size()); + // recalc stats table width + scr_coord_val max_widths[signalboxlist_row_t::MAX_COLS] = {}; + // check column widths + table_header.set_selection(signalboxlist_row_t::sort_mode); + table_header.set_width(D_H_SPACE); // init width + for (uint c = 0; c < signalboxlist_row_t::MAX_COLS; c++) { + // get header widths + max_widths[c] = table_header.get_min_width(c); + } + for (int r = 0; r < scrolly.get_count(); r++) { + signalboxlist_row_t* row = (signalboxlist_row_t*)scrolly.get_element(r); + for (uint c = 0; c < signalboxlist_row_t::MAX_COLS; c++) { + max_widths[c] = max(max_widths[c], row->get_min_width(c)); + } + } + // set column widths + for (uint c = 0; c < signalboxlist_row_t::MAX_COLS; c++) { + table_header.set_col(c, max_widths[c]); + } + table_header.set_width(table_header.get_size().w + D_SCROLLBAR_WIDTH); + for (int r = 0; r < scrolly.get_count(); r++) { + signalboxlist_row_t* row = (signalboxlist_row_t*)scrolly.get_element(r); + row->set_size(scr_size(0, row->get_size().h)); + for (uint c = 0; c < signalboxlist_row_t::MAX_COLS; c++) { + row->set_col(c, max_widths[c]); + } + } + //cont_sortable.set_size(cont_sortable.get_min_size()); + last_signalbox_count = signalbox_t::all_signalboxes.get_count(); + resize(scr_size(0,0)); } @@ -281,3 +281,4 @@ void signalboxlist_frame_t::draw(scr_coord pos, scr_size size) gui_frame_t::draw(pos,size); } + diff --git a/gui/signalboxlist_frame.h b/gui/signalboxlist_frame.h index 468ea8dc91..1fc033c931 100644 --- a/gui/signalboxlist_frame.h +++ b/gui/signalboxlist_frame.h @@ -8,22 +8,67 @@ #include "gui_frame.h" +#include "../simsignalbox.h" #include "components/gui_scrolled_list.h" #include "components/gui_label.h" #include "components/gui_image.h" -#include "components/gui_combobox.h" +#include "components/sortable_table.h" +#include "components/sortable_table_header.h" class signalbox_t; +class signalbox_radius_cell_t : public value_cell_t +{ +public: + signalbox_radius_cell_t(uint32 radius); + + void set_value(sint64 value) OVERRIDE; +}; + + +class signalboxlist_row_t : public gui_sort_table_row_t +{ +public: + enum sort_mode_t { + SB_NAME, + SB_CONNECTED, + SB_CAPACITY, + SB_RANGE, + SB_COORD, + SB_REGION, + SB_CITY, + SB_MAINTENANCE, + SB_BUILT_DATE, + MAX_COLS + }; + static int sort_mode; + static bool sortreverse; + +private: + signalbox_t* sb; + // update flag + uint32 old_connected; + +public: + signalboxlist_row_t(signalbox_t* sb); + char const* get_text() const OVERRIDE { return sb->get_name(); } + void show_info() const { sb->show_info(); } + bool infowin_event(event_t const* ev) OVERRIDE; + void draw(scr_coord offset) OVERRIDE; + static bool compare(const gui_component_t* aa, const gui_component_t* bb); +}; + class signalboxlist_frame_t : public gui_frame_t, private action_listener_t { private: static bool filter_has_vacant_slot; + button_t filter_vacant_slot; - gui_combobox_t sortedby; - button_t sort_order, filter_vacant_slot; + gui_sort_table_header_t table_header; + gui_aligned_container_t cont_sortable; gui_scrolled_list_t scrolly; + gui_scrollpane_t scroll_sortable; uint32 last_signalbox_count; @@ -41,30 +86,4 @@ class signalboxlist_frame_t : public gui_frame_t, private action_listener_t void draw(scr_coord pos, scr_size size) OVERRIDE; }; -class signalboxlist_stats_t : public gui_aligned_container_t, public gui_scrolled_list_t::scrollitem_t -{ -private: - signalbox_t *sb; - gui_label_buf_t label, lb_connected, lb_radius, lb_region; - button_t gotopos; - - void update_label(); - -public: - static int sort_mode; - static bool reverse; - - signalboxlist_stats_t(signalbox_t *); - static uint16 name_width; - - void draw( scr_coord pos) OVERRIDE; - - char const* get_text() const OVERRIDE { return ""; /* label.buf().get_str(); */ } - bool infowin_event(const event_t *) OVERRIDE; - bool is_valid() const OVERRIDE; - void set_size(scr_size size) OVERRIDE; - - static bool compare(const gui_component_t *a, const gui_component_t *b ); -}; - #endif