Add a focus event send to parents of a widget.

This event allows parent containers and windows to react if the mouse is
pressed down inside it's area. This also works if the selected widget
itself is disabled.
This commit is contained in:
Mark de Wever 2009-01-04 11:23:59 +00:00
parent c6fb8ef694
commit 5afc4c3351
5 changed files with 89 additions and 7 deletions

View File

@ -160,7 +160,17 @@ public:
/** See mouse_left_button_double_click. */
virtual void mouse_right_button_double_click(tevent_handler&) {}
/***** ***** ***** ***** mouse right button ***** ***** ***** *****/
/***** ***** ***** ***** focus ***** ***** ***** *****/
/**
* The widget recieves a focus event.
*
* Container classes are notified when a child item gets a mouse down
* event. This can be used to capture the keyboard.
*/
virtual void focus(tevent_handler&) {}
/***** ***** ***** ***** keyboard ***** ***** ***** *****/
/**
* A key is pressed.

View File

@ -154,6 +154,19 @@ void tevent_handler::handle_event(const SDL_Event& event)
mouse_y_ = event.button.y;
mouse_over = find_widget(tpoint(mouse_x_, mouse_y_), true);
/**
* @todo these two events aren't documented in the event overview
* at the end of the file.
*/
if(!mouse_captured_) {
twidget* widget =
find_widget(tpoint(mouse_x_, mouse_y_), false);
if(widget) {
focus_parent_container(widget);
focus_parent_window(widget);
}
}
switch(event.button.button) {
case SDL_BUTTON_LEFT :
DBG_G_E << "Event: Left button down.\n";
@ -520,6 +533,38 @@ void tevent_handler::mouse_click(twidget* widget, tmouse_button& button)
}
}
void tevent_handler::focus_parent_container(twidget* widget)
{
assert(widget);
twidget* parent = widget->parent();
while(parent) {
tcontainer_* container = dynamic_cast<tcontainer_*>(parent);
if(container) {
if(container != widget->get_window() && container->get_active()) {
container->focus(*this);
}
return;
}
parent = parent->parent();
}
}
void tevent_handler::focus_parent_window(twidget* widget)
{
assert(widget);
twindow* window = widget->get_window();
assert(window);
if(window->get_active()) {
window->focus(*this);
}
}
void tevent_handler::set_hover(const bool test_on_widget)
{
// Only one hover event.

View File

@ -310,6 +310,29 @@ private:
*/
void mouse_click(twidget* widget, tmouse_button& button);
/**
* Called when a mouse button is pressed.
*
* When a mouse button is pressed it's direct parent container is
* notified. If the parent container is the parent window this function
* doesn't notify the parent. The funcion focus_parent_window will send
* the event.
*
* @param widget The widget that generated the event.
*/
void focus_parent_container(twidget* widget);
/**
* Called when a mouse button is pressed.
*
* When a mouse button is pressed it's direct parent window is send the
* focus event.
*
* @param widget The widget that generated the event.
*/
void focus_parent_window(twidget* widget);
/**
* Raises a hover request.
*

View File

@ -332,6 +332,13 @@ void tscrollbar_container::key_press(tevent_handler& /*event*/,
}
}
void tscrollbar_container::focus(tevent_handler&)
{
twindow* window = get_window();
assert(window);
window->keyboard_capture(this);
}
twidget* tscrollbar_container::find_widget(
const tpoint& coordinate, const bool must_be_active)
{
@ -382,9 +389,6 @@ bool tscrollbar_container::does_block_easy_close() const
void tscrollbar_container::vertical_scrollbar_click(twidget* caller)
{
/** @todo Hack to capture the keyboard focus. */
get_window()->keyboard_capture(this);
const std::map<std::string, tscrollbar_::tscroll>::const_iterator
itor = scroll_lookup().find(caller->id());
@ -396,9 +400,6 @@ void tscrollbar_container::vertical_scrollbar_click(twidget* caller)
void tscrollbar_container::horizontal_scrollbar_click(twidget* caller)
{
/** @todo Hack to capture the keyboard focus. */
get_window()->keyboard_capture(this);
const std::map<std::string, tscrollbar_::tscroll>::const_iterator
itor = scroll_lookup().find(caller->id());

View File

@ -115,6 +115,9 @@ public:
void key_press(tevent_handler& event,
bool& handled, SDLKey key, SDLMod modifier, Uint16 unicode);
/** Inherted from tevent_executor. */
void focus(tevent_handler&);
/** Inherited from tcontainer_. */
bool get_active() const { return state_ != DISABLED; }