GUI2: added a public static type getter to all widgets implementing get_control_type

Fixes #2400. See comment in styled_widget.hpp for details.
This commit is contained in:
Charles Dang 2018-06-08 19:16:19 +11:00
parent 3d894faf11
commit 52f7fcf5cc
64 changed files with 221 additions and 38 deletions

View file

@ -57,10 +57,16 @@
*
* "Calls" REGISTER_WIDGET3(id_definition, id, nullptr)
*/
#define REGISTER_WIDGET(id) REGISTER_WIDGET3(id##_definition, id, nullptr) \
#define REGISTER_WIDGET(id) \
REGISTER_WIDGET3(id##_definition, id, nullptr) \
\
const std::string& id::get_control_type() const \
const std::string& id::type() \
{ \
static const std::string result(#id); \
return result; \
} \
\
const std::string& id::get_control_type() const \
{ \
return id::type(); \
}

View file

@ -50,7 +50,7 @@ const unsigned CONTROL_STACK_LAYER_PUBLISH = 2;
REGISTER_WIDGET(addon_list)
addon_list::addon_list(const implementation::builder_addon_list& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, addon_vector_()
, install_status_visibility_(visibility::visible)
, install_buttons_visibility_(visibility::invisible)

View file

@ -177,6 +177,11 @@ private:
/** Needed because otherwise the add-on with the first ID would be initially selected. */
void select_first_addon();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -41,7 +41,7 @@ namespace gui2
REGISTER_WIDGET(button)
button::button(const implementation::builder_button& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, clickable_item()
, state_(ENABLED)
, retval_(retval::NONE)

View file

@ -97,6 +97,11 @@ private:
*/
int retval_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -55,7 +55,7 @@ namespace gui2
REGISTER_WIDGET(chatbox)
chatbox::chatbox(const implementation::builder_chatbox& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, roomlistbox_(nullptr)
, chat_log_container_(nullptr)
, chat_input_(nullptr)

View file

@ -150,6 +150,11 @@ private:
std::map<std::string, chatroom_log>* log_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -32,7 +32,7 @@ namespace gui2
REGISTER_WIDGET(drawing)
drawing::drawing(const implementation::builder_drawing& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, best_size_(0, 0)
{
}

View file

@ -103,6 +103,11 @@ private:
/** When we're used as a fixed size item, this holds the best size. */
point best_size_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -34,7 +34,7 @@ namespace gui2
REGISTER_WIDGET(horizontal_scrollbar)
horizontal_scrollbar::horizontal_scrollbar(const implementation::builder_horizontal_scrollbar& builder)
: scrollbar_base(builder, get_control_type())
: scrollbar_base(builder, type())
{
}

View file

@ -70,6 +70,11 @@ private:
return current.x - original.x;
}
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -37,7 +37,7 @@ namespace gui2
REGISTER_WIDGET(image)
image::image(const implementation::builder_image& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
{
}

View file

@ -93,6 +93,11 @@ private:
ENABLED,
};
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -41,7 +41,7 @@ namespace gui2
REGISTER_WIDGET(label)
label::label(const implementation::builder_label& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, state_(ENABLED)
, can_wrap_(false)
, characters_per_line_(0)

View file

@ -134,6 +134,11 @@ private:
return can_shrink_;
}
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -271,6 +271,11 @@ private:
/** See @ref container_base::set_self_active. */
virtual void set_self_active(const bool active) override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -55,7 +55,7 @@ listbox::listbox(const implementation::builder_styled_widget& builder,
const bool has_minimum,
const bool has_maximum,
const bool select)
: scrollbar_container(builder, get_control_type())
: scrollbar_container(builder, type())
, generator_(generator_base::build(has_minimum, has_maximum, placement, select))
, is_horizontal_(placement == generator_base::horizontal_list)
, list_builder_(list_builder)

View file

@ -416,6 +416,11 @@ private:
/** Inherited from scrollbar_container. */
virtual void set_content_size(const point& origin, const point& size) override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -214,6 +214,11 @@ private:
*/
pane* pane_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -38,7 +38,7 @@ namespace gui2
REGISTER_WIDGET(menu_button)
menu_button::menu_button(const implementation::builder_menu_button& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, selectable_item()
, state_(ENABLED)
, retval_(retval::NONE)

View file

@ -140,6 +140,11 @@ private:
bool keep_open_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -49,7 +49,7 @@ namespace gui2
REGISTER_WIDGET(minimap)
minimap::minimap(const implementation::builder_minimap& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, map_data_()
, terrain_(nullptr)
, map_(nullptr)

View file

@ -92,6 +92,11 @@ private:
/** See @ref widget::impl_draw_background. */
virtual void impl_draw_background() override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -34,7 +34,7 @@ namespace gui2
REGISTER_WIDGET(multi_page)
multi_page::multi_page(const implementation::builder_multi_page& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, generator_(generator_base::build(true, true, generator_base::independent, false))
, page_builders_()
{

View file

@ -203,6 +203,11 @@ private:
/** See @ref widget::impl_draw_background. */
virtual void impl_draw_background() override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -40,7 +40,7 @@ namespace gui2
REGISTER_WIDGET(multimenu_button)
multimenu_button::multimenu_button(const implementation::builder_multimenu_button& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, state_(ENABLED)
, retval_(retval::NONE)
, max_shown_(1)

View file

@ -186,6 +186,11 @@ private:
void update_config_from_toggle_states();
void update_label();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -36,7 +36,7 @@ namespace gui2
REGISTER_WIDGET(panel)
panel::panel(const implementation::builder_styled_widget& builder, const std::string& control_type)
: container_base(builder, control_type.empty() ? get_control_type() : control_type)
: container_base(builder, control_type.empty() ? type() : control_type)
{
}

View file

@ -58,6 +58,11 @@ private:
/** See @ref widget::impl_draw_foreground. */
virtual void impl_draw_foreground() override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -101,12 +101,17 @@ void password_box::paste_selection(const bool mouse)
insert_char(text);
}
const std::string& password_box::get_control_type() const
const std::string& password_box::type() \
{
static const std::string type = "password_box";
return type;
}
const std::string& password_box::get_control_type() const
{
return type();
}
// }---------- BUILDER -----------{
namespace implementation

View file

@ -60,6 +60,11 @@ private:
std::string real_value_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** See @ref styled_widget::get_control_type. */
virtual const std::string& get_control_type() const override;
};

View file

@ -33,7 +33,7 @@ namespace gui2
REGISTER_WIDGET(progress_bar)
progress_bar::progress_bar(const implementation::builder_progress_bar& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, percentage_(static_cast<unsigned>(-1))
{
// Force canvas update

View file

@ -69,6 +69,11 @@ private:
/** The percentage done. */
unsigned percentage_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -36,7 +36,7 @@ namespace gui2
REGISTER_WIDGET(repeating_button)
repeating_button::repeating_button(const implementation::builder_repeating_button& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, clickable_item()
, state_(ENABLED)
, repeat_timer_(0)

View file

@ -102,6 +102,11 @@ private:
/** The timer for the repeating events. */
std::size_t repeat_timer_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -40,7 +40,7 @@ namespace gui2
REGISTER_WIDGET(scroll_label)
scroll_label::scroll_label(const implementation::builder_scroll_label& builder)
: scrollbar_container(builder, get_control_type())
: scrollbar_container(builder, type())
, state_(ENABLED)
, wrap_on_(builder.wrap_on)
, text_alignment_(builder.text_alignment)

View file

@ -103,6 +103,11 @@ private:
label* get_internal_label();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/***** ***** ***** inherited ****** *****/
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */

View file

@ -1060,12 +1060,17 @@ void scrollbar_container::scrollbar_moved()
set_scrollbar_button_status();
}
const std::string& scrollbar_container::get_control_type() const
const std::string& scrollbar_container::type()
{
static const std::string type = "scrollbar_container";
return type;
}
const std::string& scrollbar_container::get_control_type() const
{
return type();
}
void scrollbar_container::signal_handler_sdl_key_down(
const event::ui_event event, bool& handled, const SDL_Keycode key, SDL_Keymod modifier)
{

View file

@ -522,6 +522,11 @@ private:
/** Helper function which needs to be called after the scollbar moved. */
void scrollbar_moved();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** See @ref styled_widget::get_control_type. */
virtual const std::string& get_control_type() const override;

View file

@ -33,7 +33,7 @@ namespace gui2
REGISTER_WIDGET(scrollbar_panel)
scrollbar_panel::scrollbar_panel(const implementation::builder_scrollbar_panel& builder)
: scrollbar_container(builder, get_control_type())
: scrollbar_container(builder, type())
{
}

View file

@ -51,6 +51,9 @@ public:
/** See @ref styled_widget::get_state. */
virtual unsigned get_state() const override;
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -28,7 +28,7 @@ namespace gui2
REGISTER_WIDGET(size_lock)
size_lock::size_lock(const implementation::builder_size_lock& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, width_(builder.width_)
, height_(builder.height_)
, widget_(nullptr)

View file

@ -78,6 +78,11 @@ private:
*/
void finalize(builder_widget_const_ptr widget_builder);
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -47,7 +47,7 @@ namespace gui2
REGISTER_WIDGET(slider)
slider::slider(const implementation::builder_slider& builder)
: slider_base(builder, get_control_type())
: slider_base(builder, type())
, best_slider_length_(0)
, minimum_value_(0)
, step_size_(1)

View file

@ -195,6 +195,11 @@ private:
// void update_current_item_mouse_position();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -29,7 +29,7 @@ namespace gui2
REGISTER_WIDGET(spacer)
spacer::spacer(const implementation::builder_spacer& builder, const std::string& w, const std::string& h)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, width_(w)
, height_(h)
{

View file

@ -81,6 +81,11 @@ private:
/** See @ref widget::impl_draw_background. */
virtual void impl_draw_background() override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -57,7 +57,7 @@ struct stacked_widget_implementation
};
stacked_widget::stacked_widget(const implementation::builder_stacked_widget& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, generator_(generator_base::build(false, false, generator_base::independent, false))
, selected_layer_(-1)
, find_in_all_layers_(false)

View file

@ -161,6 +161,11 @@ private:
/** Internal implementation detail for selecting layers. */
void select_layer_impl(std::function<bool(unsigned int i)> display_condition);
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -400,13 +400,22 @@ private:
public:
/**
* Returns the control_type of the styled_widget.
* Returns the type of this styled_widget.
*
* The control_type parameter for gui_definition::get_control() To keep the
* code more generic this type is required so the controls need to return
* the proper string here. Might be used at other parts as well the get the
* type of
* styled_widget involved.
* This is used as the control_type parameter for @ref get_control.
*
* Do note that each widget also must have a public static type() function;
* it's use to implement this function. The reason for this system is twofold:
*
* 1) Due to an oddity in C++, one technically may not call a virtual function
* in a derived class's *initializer list*, which we do liberally. Calling
* it in the constructor *body* is fine, but doing so in the initializer list
* is technically undefined behavior and will give "invalid vptr" errors
* under UBSanitizer.
*
* 2) Having a static type getter allows the type string to be fetched without
* constructing an instance of the widget. A good example of this usecase is
* in @ref build_single_widget_and_cast_to.
*/
virtual const std::string& get_control_type() const = 0;

View file

@ -95,7 +95,7 @@ std::string text_history::get_value() const
}
text_box::text_box(const implementation::builder_styled_widget& builder)
: text_box_base(builder, get_control_type())
: text_box_base(builder, type())
, history_()
, max_input_length_(0)
, text_x_offset_(0)

View file

@ -272,6 +272,11 @@ private:
/** Inherited from text_box_base. */
void handle_key_clear_line(SDL_Keymod modifier, bool& handled) override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -36,7 +36,7 @@ namespace gui2
REGISTER_WIDGET(toggle_button)
toggle_button::toggle_button(const implementation::builder_toggle_button& builder)
: styled_widget(builder, get_control_type())
: styled_widget(builder, type())
, state_(ENABLED)
, state_num_(0)
, retval_(retval::NONE)

View file

@ -122,6 +122,11 @@ private:
*/
std::string icon_name_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -38,7 +38,7 @@ namespace gui2
REGISTER_WIDGET(toggle_panel)
toggle_panel::toggle_panel(const implementation::builder_toggle_panel& builder)
: panel(builder, get_control_type())
: panel(builder, type())
, state_(ENABLED)
, state_num_(0)
, retval_(retval::NONE)

View file

@ -153,6 +153,11 @@ private:
/** See @ref widget::impl_draw_foreground. */
virtual void impl_draw_foreground() override;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -38,7 +38,7 @@ namespace gui2
REGISTER_WIDGET(tree_view)
tree_view::tree_view(const implementation::builder_tree_view& builder)
: scrollbar_container(builder, get_control_type())
: scrollbar_container(builder, type())
, node_definitions_(builder.nodes)
, indentation_step_size_(0)
, need_layout_(false)

View file

@ -157,6 +157,11 @@ private:
/** Inherited from container_base. */
virtual void finalize_setup();
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -52,7 +52,7 @@ namespace gui2
REGISTER_WIDGET(unit_preview_pane)
unit_preview_pane::unit_preview_pane(const implementation::builder_unit_preview_pane& builder)
: container_base(builder, get_control_type())
: container_base(builder, type())
, current_type_()
, icon_type_(nullptr)
, icon_race_(nullptr)

View file

@ -97,6 +97,11 @@ private:
ENABLED
};
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;

View file

@ -29,7 +29,7 @@ namespace gui2
REGISTER_WIDGET(vertical_scrollbar)
vertical_scrollbar::vertical_scrollbar(const implementation::builder_vertical_scrollbar& builder)
: scrollbar_base(builder, get_control_type())
: scrollbar_base(builder, type())
{
}

View file

@ -67,6 +67,11 @@ private:
return current.y - original.y;
}
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;
};

View file

@ -252,7 +252,7 @@ window* manager::get_window(const unsigned id)
} // namespace
window::window(const builder_window::window_resolution* definition)
: panel(implementation::builder_window(::config {"definition", definition->definition}), get_control_type())
: panel(implementation::builder_window(::config {"definition", definition->definition}), type())
, cursor::setter(cursor::NORMAL)
, video_(CVideo::get_singleton())
, status_(NEW)

View file

@ -611,6 +611,11 @@ private:
*/
int mouse_button_state_;
public:
/** Static type getter that does not rely on the widget being constructed. */
static const std::string& type();
private:
/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
virtual const std::string& get_control_type() const override;