Add the keyboard event chaining.
The mp selection dialog is the only dialog which can benefit from it so the only dialog which chains the keyboard events. (The window itself is always chained eventhough there's no hotkey support yet.) When the listbox has the focus and ends at the top item the next up arrow is send to the textbox which selects from the history there. Not sure whether this is great behaviour, but it can be changed by letting the listbox always handle the up arrow.
This commit is contained in:
parent
1e79743e6f
commit
8268e382de
4 changed files with 54 additions and 4 deletions
|
@ -65,6 +65,9 @@ void tmp_method_selection::pre_show(CVideo& /*video*/, twindow& window)
|
|||
tlistbox* list = dynamic_cast<tlistbox*>(window.find_widget("method_list", false));
|
||||
VALIDATE(list, missing_widget("method_list"));
|
||||
|
||||
window.add_to_keyboard_chain(list);
|
||||
window.add_to_keyboard_chain(user_widget);
|
||||
|
||||
window.recalculate_size();
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ tevent_handler::tevent_handler() :
|
|||
help_popup_(0),
|
||||
mouse_focus_(0),
|
||||
mouse_captured_(false),
|
||||
keyboard_focus_(0)
|
||||
keyboard_focus_(0),
|
||||
keyboard_focus_chain_()
|
||||
{
|
||||
if(SDL_WasInit(SDL_INIT_TIMER) == 0) {
|
||||
if(SDL_InitSubSystem(SDL_INIT_TIMER) == -1) {
|
||||
|
@ -240,6 +241,25 @@ tpoint tevent_handler::get_mouse() const
|
|||
return get_window().client_position(tpoint(mouse_x_, mouse_y_));
|
||||
}
|
||||
|
||||
void tevent_handler::add_to_keyboard_chain(twidget* widget)
|
||||
{
|
||||
assert(
|
||||
std::find(keyboard_focus_chain_.begin(), keyboard_focus_chain_.end(), widget)
|
||||
== keyboard_focus_chain_.end());
|
||||
|
||||
keyboard_focus_chain_.push_back(widget);
|
||||
}
|
||||
|
||||
void tevent_handler::remove_from_keyboard_chain(twidget* widget)
|
||||
{
|
||||
std::vector<twidget*>::iterator itor = std::find(
|
||||
keyboard_focus_chain_.begin(), keyboard_focus_chain_.end(), widget);
|
||||
|
||||
if(itor != keyboard_focus_chain_.end()) {
|
||||
keyboard_focus_chain_.erase(itor);
|
||||
}
|
||||
}
|
||||
|
||||
void tevent_handler::show_tooltip(const t_string& tooltip, const unsigned timeout)
|
||||
{
|
||||
DBG_G_E << "Event: show tooltip.\n";
|
||||
|
@ -510,11 +530,18 @@ void tevent_handler::key_down(const SDL_Event& event)
|
|||
|
||||
bool handled = false;
|
||||
if(keyboard_focus_) {
|
||||
keyboard_focus_->key_press(*this, handled, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
|
||||
keyboard_focus_->key_press(*this, handled,
|
||||
event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
|
||||
}
|
||||
|
||||
if(!handled) {
|
||||
get_window().key_press(*this, handled, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
|
||||
std::vector<twidget*>::reverse_iterator ritor = keyboard_focus_chain_.rbegin();
|
||||
for(; !handled && ritor != keyboard_focus_chain_.rend(); ++ritor) {
|
||||
if(*ritor == keyboard_focus_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(**ritor).key_press(*this, handled,
|
||||
event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,12 @@ public:
|
|||
void mouse_capture(const bool capture = true);
|
||||
void keyboard_capture(twidget* widget) { keyboard_focus_ = widget; }
|
||||
|
||||
/** Adds the widget to the chain, widgets may only be added once. */
|
||||
void add_to_keyboard_chain(twidget* widget);
|
||||
|
||||
/** Remove the widget (if in the vector) from the chain. */
|
||||
void remove_from_keyboard_chain(twidget* widget);
|
||||
|
||||
tpoint get_mouse() const;
|
||||
|
||||
//! We impement the handling of the tip, but call the do functions
|
||||
|
@ -135,8 +141,21 @@ private:
|
|||
twidget* mouse_focus_;
|
||||
bool mouse_captured_;
|
||||
|
||||
/** The widget that holds the keyboard focus. */
|
||||
twidget* keyboard_focus_;
|
||||
|
||||
/**
|
||||
* Fall back keyboard focus items.
|
||||
*
|
||||
* When the focussed widget didn't handle the keyboard event (or no handler
|
||||
* for the keyboard focus) it is send all widgets in this vector. The order
|
||||
* is from rbegin() to rend(). If the keyboard_focus_ is in the vector it
|
||||
* won't get the event twice. The first item added to the vector should be
|
||||
* the window, so it will be the last handler and can dispatch the hotkeys
|
||||
* registered.
|
||||
*/
|
||||
std::vector<twidget*> keyboard_focus_chain_;
|
||||
|
||||
void mouse_enter(const SDL_Event& event, twidget* mouse_over);
|
||||
void mouse_move(const SDL_Event& event, twidget* mouse_over);
|
||||
void mouse_hover(const SDL_Event& event, twidget* mouse_over);
|
||||
|
|
|
@ -307,6 +307,7 @@ twindow build(CVideo& video, const std::string& type)
|
|||
}
|
||||
|
||||
window.recalculate_size();
|
||||
window.add_to_keyboard_chain(&window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue