Add the easy close code to the window.

Easy close means a single click will close a window (if this is enabled
in the configs). Also convert the dialogs in the test scenario to use
this feature.
This commit is contained in:
Mark de Wever 2008-10-31 18:45:14 +00:00
parent 9b8c0550fd
commit c89168bf0e
7 changed files with 107 additions and 1 deletions

View file

@ -144,6 +144,8 @@
y = "(screen_height - " + {IMAGE_WIDTH} + ")"
width = "(screen_width - 142)"
height = {IMAGE_WIDTH}
easy_close = "true"
[grid]
@ -238,6 +240,8 @@
y = "(screen_height - " + {IMAGE_WIDTH} + ")"
width = "(screen_width - 142)"
height = {IMAGE_WIDTH}
easy_close = "true"
[grid]

View file

@ -194,17 +194,29 @@ void tevent_handler::handle_event(const SDL_Event& event)
switch(event.button.button) {
/*
* All button clicks should trigger easy_close() unfortunately
* the scrollwheel also produceses click events, thus the
* function is moved to all cases.
*
* Note the engine makes sure easy close is disabled when a
* widget needs to process the click so calling it
* unconditionally is safe.
*/
case SDL_BUTTON_LEFT :
DBG_G_E << "Event: Left button up.\n";
mouse_button_up(event, mouse_over, left_);
easy_close();
break;
case SDL_BUTTON_MIDDLE :
DBG_G_E << "Event: Middle button up.\n";
mouse_button_up(event, mouse_over, middle_);
easy_close();
break;
case SDL_BUTTON_RIGHT :
DBG_G_E << "Event: Right button up.\n";
mouse_button_up(event, mouse_over, right_);
easy_close();
break;
default:
// cast to avoid being printed as char.

View file

@ -349,6 +349,9 @@ private:
/** Function to do the real removal of the help popup. */
virtual void do_remove_help_popup() = 0;
/** Handler for the easy close functionallity. */
virtual void easy_close() = 0;
};
} // namespace gui2

View file

@ -99,7 +99,9 @@ twindow::twindow(CVideo& video,
x_(x),
y_(y),
w_(w),
h_(h)
h_(h),
easy_close_(false),
easy_close_blocker_()
{
// We load the config in here as exception.
// Our caller did update the screen size so no need for us to do that again.
@ -357,6 +359,20 @@ SDL_Rect twindow::get_client_rect() const
return result;
}
void twindow::add_easy_close_blocker(const std::string& id)
{
// avoid duplicates.
remove_easy_close_blocker(id);
easy_close_blocker_.push_back(id);
}
void twindow::remove_easy_close_blocker(const std::string& id)
{
easy_close_blocker_.erase(
std::remove(easy_close_blocker_.begin(), easy_close_blocker_.end(), id),
easy_close_blocker_.end());
}
void twindow::layout()
{
@ -528,6 +544,13 @@ void twindow::do_show_help_popup(const tpoint& location, const t_string& help_po
help_popup_.set_visible();
}
void twindow::easy_close()
{
if(easy_close_ && easy_close_blocker_.empty()) {
set_retval(OK);
}
}
void twindow::draw(surface& /*surf*/, const bool /*force*/,
const bool /*invalidate_background*/)
{

View file

@ -219,6 +219,25 @@ public:
/** Inherited from tpanel. */
SDL_Rect get_client_rect() const;
/**
* Register a widget that prevents easy closing.
*
* Duplicate registration are ignored. See easy_close_ for more info.
*
* @param id The id of the widget to register.
*/
void add_easy_close_blocker(const std::string& id);
/**
* Unregister a widget the prevents easy closing.
*
* Removing a non registered id is allowed but will do nothing. See
* easy_close_ for more info.
*
* @param id The id of the widget to register.
*/
void remove_easy_close_blocker(const std::string& id);
/***** ***** ***** setters / getters for members ***** ****** *****/
/**
@ -232,6 +251,8 @@ public:
void set_owner(tdialog* owner) { owner_ = owner; }
void set_easy_close(const bool easy_close) { easy_close_ = easy_close; }
private:
/** Needed so we can change what's drawn on the screen. */
@ -311,6 +332,20 @@ private:
/** The formula to calulate the height of the dialog. */
tformula<unsigned>h_;
/**
* Do we want to have easy close behaviour?
*
* Easy closing means that whenever a mouse click is done the dialog will be
* closed. The widgets in the window may override this behaviour by
* registering themselves as blockers. These items will be stored in
* easy_close_blocker_. So in order to do an easy close the boolean needs to
* be true and the vector empty.
*/
bool easy_close_;
/** The list with items which prevent the easy close behaviour. */
std::vector<std::string> easy_close_blocker_;
/** Layouts the window. */
void layout();
@ -326,6 +361,9 @@ private:
/** Inherited from tevent_handler. */
void do_remove_help_popup() { help_popup_.set_visible(false); }
/** Inherited from tevent_handler. */
void easy_close();
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{ static const std::string type = "window"; return type; }

View file

@ -218,6 +218,8 @@ twindow build(CVideo& video, const std::string& type)
log_scope2(gui, "Window builder: building grid for window");
window.set_easy_close(definition->easy_close);
const unsigned rows = definition->grid->rows;
const unsigned cols = definition->grid->cols;
@ -292,6 +294,7 @@ twindow_builder::tresolution::tresolution(const config& cfg) :
height(cfg["height"]),
vertical_placement(get_v_align(cfg["vertical_placement"])),
horizontal_placement(get_h_align(cfg["horizontal_placement"])),
easy_close(utils::string_bool(cfg["easy_close"])),
definition(cfg["definition"]),
grid(0)
{
@ -324,6 +327,27 @@ twindow_builder::tresolution::tresolution(const config& cfg) :
* horizontal_placement (h_align = "")
* The horizontal placement of the window.
*
* easy_close (bool = false) Does the window need easy close behaviour?
* Easy close behaviour means that any mouse
* click will close the dialog. Note certain
* widgets will automatically disable this
* behaviour since they need to process the
* clicks as well, for example buttons do need
* a click and a missclick on button shouldn't
* close the dialog. NOTE with some widgets
* this behaviour depends on their contents
* (like scrolling labels) so the behaviour
* might get changed depending on the data in
* the dialog. NOTE the default behaviour
* might be changed since it will be disabled
* when can't be used due to widgets which use
* the mouse, including buttons, so it might
* be wise to set the behaviour explicitly
* when not wanted and no mouse using widgets
* are available. This means enter, escape or
* an external source needs to be used to
* close the dialog (which is valid).
*
* definition (string = "default")
* Definition of the window which we want to
* show.

View file

@ -110,6 +110,8 @@ public:
unsigned vertical_placement;
unsigned horizontal_placement;
bool easy_close;
std::string definition;