change API for CairoWidget::focus_handler
This functor/closure is responsible for stealing focus from any existing text entry (or whatever else may have focus) when clicking on a CairoWidget or derived class. The old implementation just gave focus back to the editor canvas. The new version walks up the widget packing heirarchy to find a focusable parent (from the CairoWidget for which it is invoked). If no focusable parent is found, it cancels keyboard focus in the toplevel window containing the CairoWidget
This commit is contained in:
parent
a8f242f80a
commit
9a11e3a64d
@ -724,7 +724,7 @@ ArdourButton::set_led_left (bool yn)
|
||||
bool
|
||||
ArdourButton::on_button_press_event (GdkEventButton *ev)
|
||||
{
|
||||
focus_handler ();
|
||||
focus_handler (this);
|
||||
|
||||
if (ev->button == 1 && (_elements & Indicator) && _led_rect && _distinct_led_click) {
|
||||
if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width &&
|
||||
|
@ -55,8 +55,7 @@ void
|
||||
BigClockWindow::on_unmap ()
|
||||
{
|
||||
ArdourWindow::on_unmap ();
|
||||
|
||||
PublicEditor::instance().reset_focus ();
|
||||
PublicEditor::instance().reset_focus (&clock);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1178,7 +1178,7 @@ Editor::generic_event_handler (GdkEvent* ev)
|
||||
/* leaving window, so reset focus, thus ending any and
|
||||
all text entry operations.
|
||||
*/
|
||||
reset_focus();
|
||||
reset_focus (&contents());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1274,7 +1274,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
|
||||
void naturalize_region ();
|
||||
|
||||
void reset_focus ();
|
||||
void reset_focus (Gtk::Widget*);
|
||||
|
||||
void split_region ();
|
||||
|
||||
|
@ -1739,9 +1739,40 @@ Editor::parameter_changed (std::string p)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::reset_focus ()
|
||||
Editor::reset_focus (Gtk::Widget* w)
|
||||
{
|
||||
_track_canvas->grab_focus();
|
||||
/* this resets focus to the first focusable parent of the given widget,
|
||||
* or, if there is no focusable parent, cancels focus in the toplevel
|
||||
* window that the given widget is packed into (if there is one).
|
||||
*/
|
||||
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gtk::Widget* top = w->get_toplevel();
|
||||
|
||||
if (!top || !top->is_toplevel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
w = w->get_parent ();
|
||||
|
||||
while (w) {
|
||||
if (w->get_can_focus ()) {
|
||||
Window* win = dynamic_cast<Window*> (top);
|
||||
win->set_focus (*w);
|
||||
return;
|
||||
}
|
||||
w = w->get_parent ();
|
||||
}
|
||||
|
||||
/* no focusable parent found, cancel focus in top level window.
|
||||
C++ API cannot be used for this. Thanks, references.
|
||||
*/
|
||||
|
||||
gtk_window_set_focus (GTK_WINDOW(top->gobj()), 0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2456,7 +2456,7 @@ Editor::escape ()
|
||||
selection->clear ();
|
||||
}
|
||||
|
||||
reset_focus ();
|
||||
reset_focus (&contents());
|
||||
}
|
||||
|
||||
/** Update _join_object_range_state which indicate whether we are over the top
|
||||
|
@ -319,7 +319,7 @@ class PublicEditor : public Gtkmm2ext::Tabbable {
|
||||
Glib::RefPtr<Gtk::ActionGroup> editor_menu_actions;
|
||||
Glib::RefPtr<Gtk::ActionGroup> _region_actions;
|
||||
|
||||
virtual void reset_focus () = 0;
|
||||
virtual void reset_focus (Gtk::Widget*) = 0;
|
||||
|
||||
virtual bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas) = 0;
|
||||
virtual bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) = 0;
|
||||
|
@ -30,7 +30,7 @@ static const char* has_cairo_widget_background_info = "has_cairo_widget_backgrou
|
||||
bool CairoWidget::_flat_buttons = false;
|
||||
bool CairoWidget::_widget_prelight = true;
|
||||
|
||||
sigc::slot<void> CairoWidget::focus_handler;
|
||||
sigc::slot<void,Gtk::Widget*> CairoWidget::focus_handler;
|
||||
|
||||
void CairoWidget::set_source_rgb_a( cairo_t* cr, Gdk::Color col, float a) //ToDo: this one and the Canvas version should be in a shared file (?)
|
||||
{
|
||||
@ -60,7 +60,7 @@ CairoWidget::~CairoWidget ()
|
||||
bool
|
||||
CairoWidget::on_button_press_event (GdkEventButton*)
|
||||
{
|
||||
focus_handler();
|
||||
focus_handler (this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -393,7 +393,7 @@ CairoWidget::set_widget_prelight (bool yn)
|
||||
}
|
||||
|
||||
void
|
||||
CairoWidget::set_focus_handler (sigc::slot<void> s)
|
||||
CairoWidget::set_focus_handler (sigc::slot<void,Gtk::Widget*> s)
|
||||
{
|
||||
focus_handler = s;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
they wish to invoke any existing focus handler from their own
|
||||
button press handler, they can just use: focus_handler();
|
||||
*/
|
||||
static void set_focus_handler (sigc::slot<void>);
|
||||
static void set_focus_handler (sigc::slot<void,Gtk::Widget*>);
|
||||
|
||||
protected:
|
||||
/** Render the widget to the given Cairo context */
|
||||
@ -118,7 +118,7 @@ protected:
|
||||
static bool _widget_prelight;
|
||||
bool _grabbed;
|
||||
|
||||
static sigc::slot<void> focus_handler;
|
||||
static sigc::slot<void,Gtk::Widget*> focus_handler;
|
||||
|
||||
private:
|
||||
Cairo::RefPtr<Cairo::Surface> image_surface;
|
||||
|
Loading…
Reference in New Issue
Block a user