GUI2: A modeless_dialog is now a window
Which it should have been all along, as evidenced by the diff stats here of +84, -246.
This commit is contained in:
parent
6e357ea8b3
commit
247e5ff055
9 changed files with 87 additions and 254 deletions
|
@ -41,31 +41,7 @@ std::unique_ptr<window> build(const builder_window::window_resolution& definitio
|
|||
// best size (if needed) after all widgets have been placed.
|
||||
auto win = std::make_unique<window>(definition);
|
||||
assert(win);
|
||||
|
||||
for(const auto& lg : definition.linked_groups) {
|
||||
if(win->has_linked_size_group(lg.id)) {
|
||||
t_string msg = VGETTEXT("Linked '$id' group has multiple definitions.", {{"id", lg.id}});
|
||||
|
||||
FAIL(msg);
|
||||
}
|
||||
|
||||
win->init_linked_size_group(lg.id, lg.fixed_width, lg.fixed_height);
|
||||
}
|
||||
|
||||
win->set_click_dismiss(definition.click_dismiss);
|
||||
|
||||
const auto conf = win->cast_config_to<window_definition>();
|
||||
assert(conf);
|
||||
|
||||
if(conf->grid) {
|
||||
win->init_grid(*conf->grid);
|
||||
win->finalize(*definition.grid);
|
||||
} else {
|
||||
win->init_grid(*definition.grid);
|
||||
}
|
||||
|
||||
win->add_to_keyboard_chain(win.get());
|
||||
|
||||
win->finish_build(definition);
|
||||
return win;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "gui/dialogs/debug_clock.hpp"
|
||||
|
||||
#include "draw_manager.hpp"
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/dialogs/modal_dialog.hpp"
|
||||
#include "gui/widgets/integer_selector.hpp"
|
||||
|
@ -35,57 +34,43 @@ namespace gui2::dialogs
|
|||
|
||||
REGISTER_DIALOG(debug_clock)
|
||||
|
||||
void debug_clock::pre_show(window& window)
|
||||
debug_clock::debug_clock()
|
||||
: modeless_dialog(window_id())
|
||||
, signal_()
|
||||
, time_()
|
||||
{
|
||||
hour_percentage_ = find_widget<progress_bar>(
|
||||
&window, "hour_percentage", false, false);
|
||||
this, "hour_percentage", false, false);
|
||||
minute_percentage_ = find_widget<progress_bar>(
|
||||
&window, "minute_percentage", false, false);
|
||||
this, "minute_percentage", false, false);
|
||||
second_percentage_ = find_widget<progress_bar>(
|
||||
&window, "second_percentage", false, false);
|
||||
this, "second_percentage", false, false);
|
||||
|
||||
hour_ = find_widget<integer_selector>(&window, "hour", false, false);
|
||||
hour_ = find_widget<integer_selector>(this, "hour", false, false);
|
||||
if(styled_widget *hour = dynamic_cast<styled_widget*>(hour_)) { //Note that the standard specifies that a dynamic cast of a null pointer is null
|
||||
hour->set_active(false);
|
||||
}
|
||||
minute_ = find_widget<integer_selector>(&window, "minute", false, false);
|
||||
minute_ = find_widget<integer_selector>(this, "minute", false, false);
|
||||
if(styled_widget *minute = dynamic_cast<styled_widget*>(minute_)) {
|
||||
minute->set_active(false);
|
||||
}
|
||||
second_ = find_widget<integer_selector>(&window, "second", false, false);
|
||||
second_ = find_widget<integer_selector>(this, "second", false, false);
|
||||
if(styled_widget *second = dynamic_cast<styled_widget*>(second_)) {
|
||||
second->set_active(false);
|
||||
}
|
||||
|
||||
pane_ = find_widget<pane>(&window, "pane", false, false);
|
||||
pane_ = find_widget<pane>(this, "pane", false, false);
|
||||
|
||||
clock_ = find_widget<styled_widget>(&window, "clock", false, false);
|
||||
|
||||
draw_manager::register_drawable(this);
|
||||
clock_ = find_widget<styled_widget>(this, "clock", false, false);
|
||||
|
||||
time_.set_current_time();
|
||||
update_time(true);
|
||||
}
|
||||
|
||||
void debug_clock::post_show()
|
||||
{
|
||||
draw_manager::deregister_drawable(this);
|
||||
}
|
||||
|
||||
void debug_clock::layout()
|
||||
void debug_clock::update()
|
||||
{
|
||||
update_time(false);
|
||||
}
|
||||
|
||||
rect debug_clock::screen_location()
|
||||
{
|
||||
return get_window()->get_rectangle();
|
||||
}
|
||||
|
||||
bool debug_clock::expose(const rect& /*region*/)
|
||||
{
|
||||
// Drawing is handled by the window that this should be, but is not.
|
||||
return false;
|
||||
window::update();
|
||||
}
|
||||
|
||||
void debug_clock::update_time(const bool force)
|
||||
|
|
|
@ -47,23 +47,10 @@ namespace dialogs
|
|||
* second | integer_selector |no |This shows the seconds since the beginning of the current minute. The control should have a minimum_value of 0 and a maximum_value of 59.
|
||||
* clock | control |no |A control which will have set three variables in its canvas:<ul><li>hour - the same value as the hour integer_selector.</li><li>minute - the same value as the minute integer_selector.</li><li>second - the same value as the second integer_selector.</li></ul>The control can then show the time in its own preferred format(s).
|
||||
*/
|
||||
class debug_clock : public modeless_dialog, public top_level_drawable
|
||||
class debug_clock : public modeless_dialog
|
||||
{
|
||||
public:
|
||||
debug_clock()
|
||||
: modeless_dialog()
|
||||
, hour_percentage_(nullptr)
|
||||
, minute_percentage_(nullptr)
|
||||
, second_percentage_(nullptr)
|
||||
, hour_(nullptr)
|
||||
, minute_(nullptr)
|
||||
, second_(nullptr)
|
||||
, pane_(nullptr)
|
||||
, clock_(nullptr)
|
||||
, signal_()
|
||||
, time_()
|
||||
{
|
||||
}
|
||||
debug_clock();
|
||||
|
||||
private:
|
||||
/** Progress bar for displaying the hours as a percentage. */
|
||||
|
@ -139,12 +126,9 @@ private:
|
|||
*/
|
||||
time time_;
|
||||
|
||||
/** The type of window this is. */
|
||||
virtual const std::string& window_id() const override;
|
||||
|
||||
virtual void pre_show(window& window) override;
|
||||
|
||||
virtual void post_show();
|
||||
|
||||
/**
|
||||
* The callback for the drawing routine.
|
||||
*
|
||||
|
@ -156,11 +140,8 @@ private:
|
|||
*/
|
||||
void update_time(const bool force);
|
||||
|
||||
// TODO: draw_manager - modeless dialog should be a window, fix
|
||||
/* top_level_drawable interface */
|
||||
virtual void layout() override;
|
||||
virtual bool expose(const rect& region) override;
|
||||
virtual rect screen_location() override;
|
||||
virtual void update() override;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -17,19 +17,21 @@
|
|||
|
||||
#include "gui/dialogs/modeless_dialog.hpp"
|
||||
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "gui/core/gui_definition.hpp" // get_window_builder
|
||||
#include "video.hpp"
|
||||
|
||||
namespace gui2::dialogs
|
||||
{
|
||||
|
||||
modeless_dialog::modeless_dialog() : window_(nullptr)
|
||||
modeless_dialog::modeless_dialog(const std::string& window_id)
|
||||
: window(get_window_builder(window_id))
|
||||
{
|
||||
window::finish_build(get_window_builder(window_id));
|
||||
widget::set_id(window_id);
|
||||
}
|
||||
|
||||
modeless_dialog::~modeless_dialog()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void modeless_dialog::show(const bool allow_interaction, const unsigned /*auto_close_time*/)
|
||||
|
@ -38,47 +40,13 @@ void modeless_dialog::show(const bool allow_interaction, const unsigned /*auto_c
|
|||
return;
|
||||
}
|
||||
|
||||
hide();
|
||||
|
||||
window_ = build_window();
|
||||
|
||||
post_build(*window_);
|
||||
|
||||
pre_show(*window_);
|
||||
|
||||
if(allow_interaction) {
|
||||
open_window_stack.push_back(window_.get());
|
||||
window_->show_non_modal();
|
||||
open_window_stack.push_back(this);
|
||||
window::show_non_modal();
|
||||
remove_from_window_stack(this);
|
||||
} else {
|
||||
window_->show_tooltip(/*auto_close_time*/);
|
||||
window::show_tooltip(/*auto_close_time*/);
|
||||
}
|
||||
}
|
||||
|
||||
void modeless_dialog::hide()
|
||||
{
|
||||
if(window_) {
|
||||
// Don't bother if show_mode_ == tooltip, because in that case we didn't add it anyway.
|
||||
if(window_->mode() == window::show_mode::modeless) {
|
||||
remove_from_window_stack(window_.get());
|
||||
}
|
||||
|
||||
window_->undraw();
|
||||
window_.reset(nullptr); }
|
||||
}
|
||||
|
||||
std::unique_ptr<window> modeless_dialog::build_window() const
|
||||
{
|
||||
return build(window_id());
|
||||
}
|
||||
|
||||
void modeless_dialog::post_build(window& /*window*/)
|
||||
{
|
||||
/* DO NOTHING */
|
||||
}
|
||||
|
||||
void modeless_dialog::pre_show(window& /*window*/)
|
||||
{
|
||||
/* DO NOTHING */
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -15,14 +15,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "gui/widgets/window.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gui2
|
||||
{
|
||||
|
||||
class window;
|
||||
|
||||
namespace dialogs
|
||||
{
|
||||
|
||||
|
@ -32,7 +30,7 @@ namespace dialogs
|
|||
* At the moment these windows also don't capture the mouse and keyboard so can
|
||||
* only be used for things like tooltips. This behavior might change later.
|
||||
*/
|
||||
class modeless_dialog
|
||||
class modeless_dialog : public window
|
||||
{
|
||||
/**
|
||||
* Special helper function to get the id of the window.
|
||||
|
@ -51,7 +49,7 @@ class modeless_dialog
|
|||
friend window* unit_test_window(const modeless_dialog& dialog);
|
||||
|
||||
public:
|
||||
modeless_dialog();
|
||||
explicit modeless_dialog(const std::string& window_id);
|
||||
|
||||
virtual ~modeless_dialog();
|
||||
|
||||
|
@ -70,52 +68,13 @@ public:
|
|||
void show(const bool allow_interaction = false,
|
||||
const unsigned auto_close_time = 0);
|
||||
|
||||
|
||||
/**
|
||||
* Hides the window.
|
||||
*
|
||||
* The hiding also destroys the window. It is save to call the function
|
||||
* when the window is not shown.
|
||||
*/
|
||||
void hide();
|
||||
|
||||
/** Returns a pointer to the dialog's window. Will be null if it hasn't been built yet. */
|
||||
window* get_window() const
|
||||
{
|
||||
return window_.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
/** The window, used in show. */
|
||||
std::unique_ptr<window> window_;
|
||||
|
||||
private:
|
||||
/** The id of the window to build. */
|
||||
virtual const std::string& window_id() const = 0;
|
||||
|
||||
/**
|
||||
* Builds the window.
|
||||
* The ID of the window to build. Usually defined by REGISTER_DIALOG.
|
||||
*
|
||||
* Every dialog shows it's own kind of window, this function should return
|
||||
* the window to show.
|
||||
*
|
||||
* @returns The window to show.
|
||||
* Falls back to widget::id(), which is set during construction.
|
||||
*/
|
||||
std::unique_ptr<window> build_window() const;
|
||||
|
||||
/**
|
||||
* Actions to be taken directly after the window is build.
|
||||
*
|
||||
* @param window The window just created.
|
||||
*/
|
||||
virtual void post_build(window& window);
|
||||
|
||||
/**
|
||||
* Actions to be taken before showing the window.
|
||||
*
|
||||
* @param window The window to be shown.
|
||||
*/
|
||||
virtual void pre_show(window& window);
|
||||
virtual const std::string& window_id() const { return widget::id(); }
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -57,85 +57,26 @@ REGISTER_WINDOW(tooltip_large)
|
|||
class tooltip : public modeless_dialog
|
||||
{
|
||||
public:
|
||||
tooltip() : modeless_dialog(), window_id_(), message_(), mouse_()
|
||||
tooltip(const std::string& window_id, const t_string& message,
|
||||
const point& mouse, const SDL_Rect& source_rect)
|
||||
: modeless_dialog(window_id)
|
||||
{
|
||||
// To make Coverity happy
|
||||
source_rect_.x = 0;
|
||||
source_rect_.y = 0;
|
||||
source_rect_.w = 0;
|
||||
source_rect_.h = 0;
|
||||
find_widget<styled_widget>(this, "label", false).set_label(message);
|
||||
|
||||
set_variable("mouse_x", wfl::variant(mouse.x));
|
||||
set_variable("mouse_y", wfl::variant(mouse.y));
|
||||
|
||||
set_variable("source_x", wfl::variant(source_rect.x));
|
||||
set_variable("source_y", wfl::variant(source_rect.y));
|
||||
set_variable("source_w", wfl::variant(source_rect.w));
|
||||
set_variable("source_h", wfl::variant(source_rect.h));
|
||||
}
|
||||
|
||||
void set_window_id(const std::string& window_id)
|
||||
{
|
||||
window_id_ = window_id;
|
||||
}
|
||||
|
||||
void set_message(const t_string& message)
|
||||
{
|
||||
message_ = message;
|
||||
}
|
||||
|
||||
void set_mouse(const point& mouse)
|
||||
{
|
||||
mouse_ = mouse;
|
||||
}
|
||||
|
||||
void set_source_rect(const SDL_Rect& rect)
|
||||
{
|
||||
source_rect_ = rect;
|
||||
}
|
||||
|
||||
private:
|
||||
/** The id of the window to use to show the tip. */
|
||||
std::string window_id_;
|
||||
|
||||
/** The message to show. */
|
||||
t_string message_;
|
||||
|
||||
/** The position of the mouse. */
|
||||
point mouse_;
|
||||
|
||||
/** The size of the requestor. */
|
||||
SDL_Rect source_rect_;
|
||||
|
||||
/** Inherited from modeless_dialog. */
|
||||
virtual const std::string& window_id() const override;
|
||||
|
||||
/** Inherited from modeless_dialog. */
|
||||
virtual void pre_show(window& window) override;
|
||||
};
|
||||
|
||||
void tooltip::pre_show(window& window)
|
||||
{
|
||||
find_widget<styled_widget>(&window, "label", false).set_label(message_);
|
||||
|
||||
window.set_variable("mouse_x", wfl::variant(mouse_.x));
|
||||
window.set_variable("mouse_y", wfl::variant(mouse_.y));
|
||||
|
||||
window.set_variable("source_x", wfl::variant(source_rect_.x));
|
||||
window.set_variable("source_y", wfl::variant(source_rect_.y));
|
||||
window.set_variable("source_w", wfl::variant(source_rect_.w));
|
||||
window.set_variable("source_h", wfl::variant(source_rect_.h));
|
||||
}
|
||||
|
||||
const std::string& tooltip::window_id() const
|
||||
{
|
||||
return window_id_;
|
||||
}
|
||||
|
||||
namespace tip
|
||||
{
|
||||
|
||||
static tooltip& tip()
|
||||
{
|
||||
/*
|
||||
* Allocating a static tip object causes a segmentation fault when Wesnoth
|
||||
* terminates. So instead create an object on the heap and never free it.
|
||||
*/
|
||||
static tooltip* t = new tooltip();
|
||||
return *t;
|
||||
}
|
||||
static std::unique_ptr<tooltip> tip;
|
||||
|
||||
void show(const std::string& window_id,
|
||||
const t_string& message,
|
||||
|
@ -146,23 +87,19 @@ void show(const std::string& window_id,
|
|||
* For now allow invalid tip names, might turn them to invalid wml messages
|
||||
* later on.
|
||||
*/
|
||||
tooltip& t = tip();
|
||||
t.set_window_id(window_id);
|
||||
t.set_message(message);
|
||||
t.set_mouse(mouse);
|
||||
t.set_source_rect(source_rect);
|
||||
tip.reset(new tooltip(window_id, message, mouse, source_rect));
|
||||
try
|
||||
{
|
||||
t.show();
|
||||
tip->show();
|
||||
}
|
||||
catch(const window_builder_invalid_id&)
|
||||
{
|
||||
ERR_CFG << "Tip with the requested id '" << window_id
|
||||
<< "' doesn't exist, fall back to the default.";
|
||||
t.set_window_id("tooltip_large");
|
||||
tip.reset(new tooltip("tooltip_large", message, mouse, source_rect));
|
||||
try
|
||||
{
|
||||
t.show();
|
||||
tip->show();
|
||||
}
|
||||
catch(const window_builder_invalid_id&)
|
||||
{
|
||||
|
@ -173,7 +110,7 @@ void show(const std::string& window_id,
|
|||
|
||||
void remove()
|
||||
{
|
||||
tip().hide();
|
||||
tip.reset();
|
||||
}
|
||||
|
||||
} // namespace tip
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "events.hpp"
|
||||
#include "floating_label.hpp"
|
||||
#include "formula/callable.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "log.hpp"
|
||||
#include "gui/auxiliary/typed_formula.hpp"
|
||||
|
@ -392,6 +393,8 @@ window::~window()
|
|||
|
||||
manager::instance().remove(*this);
|
||||
|
||||
undraw();
|
||||
|
||||
#ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
|
||||
|
||||
delete debug_layout_;
|
||||
|
@ -417,6 +420,33 @@ retval window::get_retval_by_id(const std::string& id)
|
|||
}
|
||||
}
|
||||
|
||||
void window::finish_build(const builder_window::window_resolution& definition)
|
||||
{
|
||||
for(const auto& lg : definition.linked_groups) {
|
||||
if(has_linked_size_group(lg.id)) {
|
||||
t_string msg = VGETTEXT("Linked '$id' group has multiple definitions.", {{"id", lg.id}});
|
||||
|
||||
FAIL(msg);
|
||||
}
|
||||
|
||||
init_linked_size_group(lg.id, lg.fixed_width, lg.fixed_height);
|
||||
}
|
||||
|
||||
set_click_dismiss(definition.click_dismiss);
|
||||
|
||||
const auto conf = cast_config_to<window_definition>();
|
||||
assert(conf);
|
||||
|
||||
if(conf->grid) {
|
||||
init_grid(*conf->grid);
|
||||
finalize(*definition.grid);
|
||||
} else {
|
||||
init_grid(*definition.grid);
|
||||
}
|
||||
|
||||
add_to_keyboard_chain(this);
|
||||
}
|
||||
|
||||
void window::show_tooltip(/*const unsigned auto_close_timeout*/)
|
||||
{
|
||||
log_scope2(log_gui_draw, "Window: show as tooltip.");
|
||||
|
|
|
@ -74,7 +74,7 @@ class window : public panel, public top_level_drawable
|
|||
public:
|
||||
explicit window(const builder_window::window_resolution& definition);
|
||||
|
||||
~window();
|
||||
virtual ~window();
|
||||
|
||||
/**
|
||||
* Returns the instance of a window.
|
||||
|
@ -88,6 +88,8 @@ public:
|
|||
/** Gets the retval for the default buttons. */
|
||||
static retval get_retval_by_id(const std::string& id);
|
||||
|
||||
void finish_build(const builder_window::window_resolution&);
|
||||
|
||||
/**
|
||||
* Shows the window, running an event loop until it should close.
|
||||
*
|
||||
|
|
|
@ -152,11 +152,6 @@ std::string unit_test_mark_popup_as_tested(const modeless_dialog& dialog)
|
|||
return dialog.window_id();
|
||||
}
|
||||
|
||||
window* unit_test_window(const modeless_dialog& dialog)
|
||||
{
|
||||
return dialog.window_.get();
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
} // namespace gui2
|
||||
|
||||
|
@ -235,7 +230,7 @@ namespace {
|
|||
std::string exception;
|
||||
try {
|
||||
dlg->show(interact);
|
||||
gui2::window* window = unit_test_window((*dlg.get()));
|
||||
gui2::window* window = dlg.get();
|
||||
BOOST_REQUIRE_NE(window, static_cast<void*>(nullptr));
|
||||
window->draw();
|
||||
} catch(const gui2::layout_exception_width_modified&) {
|
||||
|
|
Loading…
Add table
Reference in a new issue