Merge lp:~themuso/unity/add-dash-filter-accessibility into lp:unity

Proposed by Luke Yelavich
Status: Merged
Approved by: Stephen M. Webb
Approved revision: no longer in the source branch.
Merged at revision: 3982
Proposed branch: lp:~themuso/unity/add-dash-filter-accessibility
Merge into: lp:unity
Diff against target: 995 lines (+737/-76)
14 files modified
dash/FilterBasicButton.cpp (+5/-0)
dash/FilterBasicButton.h (+2/-0)
dash/FilterExpanderLabel.cpp (+3/-34)
dash/FilterExpanderLabel.h (+3/-2)
plugins/unityshell/src/unity-expander-view-accessible.cpp (+207/-0)
plugins/unityshell/src/unity-expander-view-accessible.h (+60/-0)
plugins/unityshell/src/unity-filter-basic-button-accessible.cpp (+282/-0)
plugins/unityshell/src/unity-filter-basic-button-accessible.h (+53/-0)
plugins/unityshell/src/unitya11y.cpp (+10/-0)
unity-shared/CMakeLists.txt (+1/-0)
unity-shared/ExpanderView.cpp (+59/-0)
unity-shared/ExpanderView.h (+47/-0)
unity-shared/SearchBar.cpp (+3/-39)
unity-shared/SearchBar.h (+2/-1)
To merge this branch: bzr merge lp:~themuso/unity/add-dash-filter-accessibility
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Stephen M. Webb (community) Needs Fixing
Marco Trevisan (Treviño) Approve
Review via email: mp+258220@code.launchpad.net

Commit message

Implement filter results controls accessibility

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Thanks, core looks good... Some improvements, by the way.

See the inline comments, plus:

Instead of updating the expander_view_->expanded at every change is safer to do something like this:

 In SearchBar::SearchBar() (after creating expander_view_):
  expanded.changed.connect([this] (bool expanded) { expander_view_->expanded = expanded; });

 In FilterExpanderLabel::FilterExpanderLabel() (or BuildLayout):
  showing_filters.changed.connect([this] (bool showing_filters) { expander_view_->expanded = showing_filters; });

review: Needs Fixing
Revision history for this message
Luke Yelavich (themuso) wrote :

On Fri, May 08, 2015 at 10:54:20AM AEST, Marco Trevisan (Treviño) wrote:
> Review: Needs Fixing
>
> Thanks, core looks good... Some improvements, by the way.
>
> See the inline comments, plus:

Thanks, forgot to remove commented out stuff, revision incoming.

Luke

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looking good now... Thanks!

review: Approve
Revision history for this message
Stephen M. Webb (bregma) wrote :

Build fails on arm64 with the following messages. Not sure why it doesn't fail on the other architectures. I believe the fix is to reverse the order of includes in the
unity-shared/ExpanderView.cpp source file (Nux headers do not have proper order independence).

/build/buildd/unity-7.3.2+15.10.20150521/unity-shared/ExpanderView.cpp: In member function 'virtual void unity::ExpanderView::DrawContent(nux::GraphicsEngine&, bool)':
/build/buildd/unity-7.3.2+15.10.20150521/unity-shared/ExpanderView.cpp:43:57: error: no matching function for call to 'nux::Layout::ProcessDraw(nux::GraphicsEngine&, bool&)'
     GetLayout()->ProcessDraw(graphics_engine, force_draw);
                                                         ^
/build/buildd/unity-7.3.2+15.10.20150521/unity-shared/ExpanderView.cpp:43:57: note: candidate is:
In file included from /build/buildd/unity-7.3.2+15.10.20150521/unity-shared/ExpanderView.cpp:20:0:
/usr/include/Nux-4.0/Nux/Layout.h:196:18: note: virtual void nux::Layout::ProcessDraw(int&, bool)
     virtual void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw);
                  ^
/usr/include/Nux-4.0/Nux/Layout.h:196:18: note: no known conversion for argument 1 from 'nux::GraphicsEngine' to 'int&'
unity-shared/CMakeFiles/unity-shared.dir/build.make:356: recipe for target 'unity-shared/CMakeFiles/unity-shared.dir/ExpanderView.cpp.o' failed

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dash/FilterBasicButton.cpp'
2--- dash/FilterBasicButton.cpp 2014-08-27 12:56:22 +0000
3+++ dash/FilterBasicButton.cpp 2015-05-25 05:13:52 +0000
4@@ -188,5 +188,10 @@
5 graphics_engine.PopClippingRectangle();
6 }
7
8+std::string const& FilterBasicButton::GetLabel() const
9+{
10+ return label_;
11+}
12+
13 } // namespace dash
14 } // namespace unity
15
16=== modified file 'dash/FilterBasicButton.h'
17--- dash/FilterBasicButton.h 2014-07-09 13:36:55 +0000
18+++ dash/FilterBasicButton.h 2015-05-25 05:13:52 +0000
19@@ -42,6 +42,8 @@
20
21 nux::Property<double> scale;
22
23+ std::string const& GetLabel() const;
24+
25 protected:
26 virtual long ComputeContentSize();
27 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
28
29=== modified file 'dash/FilterExpanderLabel.cpp'
30--- dash/FilterExpanderLabel.cpp 2014-07-09 11:18:45 +0000
31+++ dash/FilterExpanderLabel.cpp 2015-05-25 05:13:52 +0000
32@@ -40,40 +40,6 @@
33 // font
34 const char* const FONT_EXPANDER_LABEL = "Ubuntu 13"; // 17px = 13
35
36-class ExpanderView : public nux::View
37-{
38-public:
39- ExpanderView(NUX_FILE_LINE_DECL)
40- : nux::View(NUX_FILE_LINE_PARAM)
41- {
42- SetAcceptKeyNavFocusOnMouseDown(false);
43- SetAcceptKeyNavFocusOnMouseEnter(true);
44- }
45-
46-protected:
47- void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
48- {};
49-
50- void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
51- {
52- if (GetLayout())
53- GetLayout()->ProcessDraw(graphics_engine, force_draw);
54- }
55-
56- bool AcceptKeyNavFocus()
57- {
58- return true;
59- }
60-
61- nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
62- {
63- if (event_type != nux::EVENT_MOUSE_WHEEL && TestMousePointerInclusion(mouse_position, event_type))
64- return this;
65- else
66- return nullptr;
67- }
68-};
69-
70 }
71
72 NUX_IMPLEMENT_OBJECT_TYPE(FilterExpanderLabel);
73@@ -97,6 +63,7 @@
74 void FilterExpanderLabel::SetLabel(std::string const& label)
75 {
76 cairo_label_->SetText(label);
77+ expander_view_->label = label;
78 }
79
80 void FilterExpanderLabel::UpdateScale(double scale)
81@@ -139,6 +106,8 @@
82 expander_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
83
84 expander_view_ = new ExpanderView(NUX_TRACKER_LOCATION);
85+ expander_view_->expanded = expanded();
86+ expanded.changed.connect([this] (bool expanded) { expander_view_->expanded = expanded; });
87 expander_view_->SetLayout(expander_layout_);
88 top_bar_layout_->AddView(expander_view_, 1);
89
90
91=== modified file 'dash/FilterExpanderLabel.h'
92--- dash/FilterExpanderLabel.h 2014-07-09 10:55:58 +0000
93+++ dash/FilterExpanderLabel.h 2015-05-25 05:13:52 +0000
94@@ -35,6 +35,7 @@
95 #include "unity-shared/IconTexture.h"
96 #include "unity-shared/Introspectable.h"
97 #include "unity-shared/StaticCairoText.h"
98+#include "unity-shared/ExpanderView.h"
99
100 namespace nux
101 {
102@@ -62,7 +63,7 @@
103 virtual void SetFilter(Filter::Ptr const& filter) = 0;
104 virtual std::string GetFilterType() = 0;
105
106- nux::View* expander_view() const { return expander_view_; }
107+ ExpanderView* expander_view() const { return expander_view_; }
108
109 nux::Property<double> scale;
110 nux::Property<bool> expanded;
111@@ -87,7 +88,7 @@
112
113 nux::VLayout* layout_;
114 nux::LinearLayout* top_bar_layout_;
115- nux::View* expander_view_;
116+ ExpanderView* expander_view_;
117 nux::LinearLayout* expander_layout_;
118 nux::View* right_hand_contents_;
119 StaticCairoText* cairo_label_;
120
121=== added file 'plugins/unityshell/src/unity-expander-view-accessible.cpp'
122--- plugins/unityshell/src/unity-expander-view-accessible.cpp 1970-01-01 00:00:00 +0000
123+++ plugins/unityshell/src/unity-expander-view-accessible.cpp 2015-05-25 05:13:52 +0000
124@@ -0,0 +1,207 @@
125+/*
126+ * Copyright (C) 2015 Canonical Ltd
127+ *
128+ * This program is free software: you can redistribute it and/or modify
129+ * it under the terms of the GNU General Public License version 3 as
130+ * published by the Free Software Foundation.
131+ *
132+ * This program is distributed in the hope that it will be useful,
133+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
134+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
135+ * GNU General Public License for more details.
136+ *
137+ * You should have received a copy of the GNU General Public License
138+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
139+ *
140+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
141+ */
142+
143+/**
144+ * SECTION:unity-expander-view-accessible
145+ * @Title: UnityExpanderViewAccessible
146+ * @short_description: Implementation of the ATK interfaces for #ExpanderView
147+ * @see_also: ExpanderView
148+ *
149+ * #UnityExpanderViewAccessible implements the required ATK interfaces for
150+ * #ExpanderView, mainly exposing the text as his name, as this
151+ * #object is mainly used as a label
152+ *
153+ */
154+
155+#include <NuxCore/Logger.h>
156+#include <glib/gi18n.h>
157+
158+#include "unity-expander-view-accessible.h"
159+
160+#include "ExpanderView.h"
161+#include "StaticCairoText.h"
162+
163+DECLARE_LOGGER(logger, "unity.a11y.ExpanderView");
164+
165+using namespace unity;
166+
167+/* GObject */
168+static void unity_expander_view_accessible_class_init(UnityExpanderViewAccessibleClass* klass);
169+static void unity_expander_view_accessible_init(UnityExpanderViewAccessible* self);
170+static void unity_expander_view_accessible_dispose(GObject* object);
171+
172+/* AtkObject.h */
173+static void unity_expander_view_accessible_initialize(AtkObject* accessible,
174+ gpointer data);
175+static const gchar* unity_expander_view_accessible_get_name(AtkObject* obj);
176+static void on_focus_changed_cb(nux::Area* area,
177+ bool has_focus,
178+ nux::KeyNavDirection direction,
179+ AtkObject* accessible);
180+static void on_expanded_changed_cb(bool is_expanded,
181+ AtkObject* accessible);
182+static void on_name_changed_cb(std::string name,
183+ AtkObject* accessible);
184+
185+G_DEFINE_TYPE(UnityExpanderViewAccessible, unity_expander_view_accessible, NUX_TYPE_VIEW_ACCESSIBLE);
186+
187+
188+#define UNITY_EXPANDER_VIEW_ACCESSIBLE_GET_PRIVATE(obj) \
189+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE, \
190+ UnityExpanderViewAccessiblePrivate))
191+
192+struct _UnityExpanderViewAccessiblePrivate
193+{
194+ gchar* name;
195+};
196+
197+
198+static void
199+unity_expander_view_accessible_class_init(UnityExpanderViewAccessibleClass* klass)
200+{
201+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
202+ AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
203+
204+ gobject_class->dispose = unity_expander_view_accessible_dispose;
205+
206+ /* AtkObject */
207+ atk_class->initialize = unity_expander_view_accessible_initialize;
208+ atk_class->get_name = unity_expander_view_accessible_get_name;
209+
210+ g_type_class_add_private(gobject_class, sizeof(UnityExpanderViewAccessiblePrivate));
211+}
212+
213+static void
214+unity_expander_view_accessible_init(UnityExpanderViewAccessible* self)
215+{
216+ UnityExpanderViewAccessiblePrivate* priv =
217+ UNITY_EXPANDER_VIEW_ACCESSIBLE_GET_PRIVATE(self);
218+
219+ self->priv = priv;
220+ self->priv->name = NULL;
221+}
222+
223+static void
224+unity_expander_view_accessible_dispose(GObject* object)
225+{
226+ UnityExpanderViewAccessible* self = UNITY_EXPANDER_VIEW_ACCESSIBLE(object);
227+
228+ if (self->priv->name != NULL)
229+ {
230+ g_free(self->priv->name);
231+ self->priv->name = NULL;
232+ }
233+
234+ G_OBJECT_CLASS(unity_expander_view_accessible_parent_class)->dispose(object);
235+}
236+
237+AtkObject*
238+unity_expander_view_accessible_new(nux::Object* object)
239+{
240+ AtkObject* accessible = NULL;
241+
242+ g_return_val_if_fail(dynamic_cast<ExpanderView*>(object), NULL);
243+
244+ accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE, NULL));
245+
246+ atk_object_initialize(accessible, object);
247+
248+ return accessible;
249+}
250+
251+/* AtkObject.h */
252+static void
253+unity_expander_view_accessible_initialize(AtkObject* accessible,
254+ gpointer data)
255+{
256+ nux::Object* object = NULL;
257+ ExpanderView* view = NULL;
258+
259+ ATK_OBJECT_CLASS(unity_expander_view_accessible_parent_class)->initialize(accessible, data);
260+
261+ object = (nux::Object*)data;
262+ view = dynamic_cast<ExpanderView*>(object);
263+
264+ view->key_nav_focus_change.connect(sigc::bind(sigc::ptr_fun(on_focus_changed_cb), accessible));
265+
266+ view->expanded.changed.connect(sigc::bind(sigc::ptr_fun(on_expanded_changed_cb), accessible));
267+ view->label.changed.connect(sigc::bind(sigc::ptr_fun(on_name_changed_cb), accessible));
268+
269+ atk_object_set_role(accessible, ATK_ROLE_PANEL);
270+}
271+
272+static const gchar*
273+unity_expander_view_accessible_get_name(AtkObject* obj)
274+{
275+ g_return_val_if_fail(UNITY_IS_EXPANDER_VIEW_ACCESSIBLE(obj), NULL);
276+ UnityExpanderViewAccessible* self = UNITY_EXPANDER_VIEW_ACCESSIBLE(obj);
277+
278+ if (self->priv->name != NULL)
279+ {
280+ g_free(self->priv->name);
281+ self->priv->name = NULL;
282+ }
283+
284+ self->priv->name = g_strdup(ATK_OBJECT_CLASS(unity_expander_view_accessible_parent_class)->get_name(obj));
285+ if (self->priv->name == NULL)
286+ {
287+ ExpanderView* view = NULL;
288+
289+ view = dynamic_cast<ExpanderView*>(nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)));
290+
291+ if (view == NULL) /* state is defunct */
292+ return NULL;
293+
294+ if (view->expanded)
295+ self->priv->name = g_strdup_printf(_("%s: expanded"), view->label().c_str());
296+ else
297+ self->priv->name = g_strdup_printf(_("%s: collapsed"), view->label().c_str());
298+ }
299+
300+ return self->priv->name;
301+}
302+
303+static void
304+on_focus_changed_cb(nux::Area* area,
305+ bool has_focus,
306+ nux::KeyNavDirection direction,
307+ AtkObject* accessible)
308+{
309+ g_return_if_fail(UNITY_IS_EXPANDER_VIEW_ACCESSIBLE(accessible));
310+
311+ LOG_WARN(logger) << "has_focus = " << has_focus;
312+ g_signal_emit_by_name(accessible, "focus-event", has_focus);
313+}
314+
315+static void
316+on_expanded_changed_cb(bool is_expanded,
317+ AtkObject* accessible)
318+{
319+ g_return_if_fail(UNITY_IS_EXPANDER_VIEW_ACCESSIBLE(accessible));
320+
321+ g_object_notify(G_OBJECT(accessible), "accessible-name");
322+}
323+
324+static void
325+on_name_changed_cb(std::string name,
326+ AtkObject* accessible)
327+{
328+ g_return_if_fail(UNITY_IS_EXPANDER_VIEW_ACCESSIBLE(accessible));
329+
330+ g_object_notify(G_OBJECT(accessible), "accessible-name");
331+}
332
333=== added file 'plugins/unityshell/src/unity-expander-view-accessible.h'
334--- plugins/unityshell/src/unity-expander-view-accessible.h 1970-01-01 00:00:00 +0000
335+++ plugins/unityshell/src/unity-expander-view-accessible.h 2015-05-25 05:13:52 +0000
336@@ -0,0 +1,60 @@
337+/*
338+ * Copyright (C) 2015 Canonical Ltd
339+ *
340+ * This program is free software: you can redistribute it and/or modify
341+ * it under the terms of the GNU General Public License version 3 as
342+ * published by the Free Software Foundation.
343+ *
344+ * This program is distributed in the hope that it will be useful,
345+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
346+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
347+ * GNU General Public License for more details.
348+ *
349+ * You should have received a copy of the GNU General Public License
350+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
351+ *
352+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
353+ */
354+
355+#ifndef UNITY_EXPANDER_VIEW_ACCESSIBLE_H
356+#define UNITY_EXPANDER_VIEW_ACCESSIBLE_H
357+
358+#include <atk/atk.h>
359+
360+#include <Nux/Nux.h>
361+#include <Nux/Layout.h>
362+
363+#include "nux-view-accessible.h"
364+
365+G_BEGIN_DECLS
366+
367+#define UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE (unity_expander_view_accessible_get_type ())
368+#define UNITY_EXPANDER_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE, UnityExpanderViewAccessible))
369+#define UNITY_EXPANDER_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE, UnityExpanderViewAccessibleClass))
370+#define UNITY_IS_EXPANDER_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE))
371+#define UNITY_IS_EXPANDER_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE))
372+#define UNITY_EXPANDER_VIEW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_EXPANDER_VIEW_ACCESSIBLE, UnityExpanderViewAccessibleClass))
373+
374+typedef struct _UnityExpanderViewAccessible UnityExpanderViewAccessible;
375+typedef struct _UnityExpanderViewAccessibleClass UnityExpanderViewAccessibleClass;
376+typedef struct _UnityExpanderViewAccessiblePrivate UnityExpanderViewAccessiblePrivate;
377+
378+struct _UnityExpanderViewAccessible
379+{
380+ NuxViewAccessible parent;
381+
382+ /*< private >*/
383+ UnityExpanderViewAccessiblePrivate* priv;
384+};
385+
386+struct _UnityExpanderViewAccessibleClass
387+{
388+ NuxViewAccessibleClass parent_class;
389+};
390+
391+GType unity_expander_view_accessible_get_type(void);
392+AtkObject* unity_expander_view_accessible_new(nux::Object* object);
393+
394+G_END_DECLS
395+
396+#endif /* __UNITY_EXPANDER_VIEW_ACCESSIBLE_H__ */
397
398=== added file 'plugins/unityshell/src/unity-filter-basic-button-accessible.cpp'
399--- plugins/unityshell/src/unity-filter-basic-button-accessible.cpp 1970-01-01 00:00:00 +0000
400+++ plugins/unityshell/src/unity-filter-basic-button-accessible.cpp 2015-05-25 05:13:52 +0000
401@@ -0,0 +1,282 @@
402+/*
403+ * Copyright (C) 2015 Canonical Ltd
404+ *
405+ * This program is free software: you can redistribute it and/or modify
406+ * it under the terms of the GNU General Public License version 3 as
407+ * published by the Free Software Foundation.
408+ *
409+ * This program is distributed in the hope that it will be useful,
410+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
411+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
412+ * GNU General Public License for more details.
413+ *
414+ * You should have received a copy of the GNU General Public License
415+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
416+ *
417+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
418+ */
419+
420+/**
421+ * SECTION:unity-filter-basic-button_accessible
422+ * @Title: UnityFilterBasicButtonAccessible
423+ * @short_description: Implementation of the ATK interfaces for #unity::dash::FilterBasicButton
424+ *
425+ * #UnityFilterBasicButtonAccessible implements the required ATK interfaces of
426+ * unity::dash::FilterBasicButton, exposing the common elements on each basic individual
427+ * element (position, extents, etc)
428+ *
429+ */
430+
431+#include <NuxCore/Logger.h>
432+#include "unity-filter-basic-button-accessible.h"
433+#include "FilterBasicButton.h"
434+
435+#include "unitya11y.h"
436+
437+DECLARE_LOGGER(logger, "unity.a11y.UnityFilterBasicButtonAccessible");
438+
439+using namespace unity::dash;
440+
441+/* GObject */
442+static void unity_filter_basic_button_accessible_class_init(UnityFilterBasicButtonAccessibleClass* klass);
443+static void unity_filter_basic_button_accessible_init(UnityFilterBasicButtonAccessible* session_button_accessible);
444+static void unity_filter_basic_button_accessible_dispose(GObject* object);
445+static void unity_filter_basic_button_accessible_finalize(GObject* object);
446+
447+
448+/* AtkObject.h */
449+static void unity_filter_basic_button_accessible_initialize(AtkObject* accessible,
450+ gpointer data);
451+static AtkStateSet* unity_filter_basic_button_accessible_ref_state_set(AtkObject* obj);
452+static const gchar* unity_filter_basic_button_accessible_get_name(AtkObject* obj);
453+
454+
455+/* AtkAction */
456+static void atk_action_interface_init(AtkActionIface *iface);
457+static gboolean unity_filter_basic_button_accessible_do_action(AtkAction *action,
458+ gint i);
459+static gint unity_filter_basic_button_accessible_get_n_actions(AtkAction *action);
460+static const gchar* unity_filter_basic_button_accessible_get_action_name(AtkAction *action,
461+ gint i);
462+static void on_layout_changed_cb(nux::View* view,
463+ nux::Layout* layout,
464+ AtkObject* accessible,
465+ gboolean is_add);
466+static void on_focus_changed_cb(nux::Area* area,
467+ bool has_focus,
468+ nux::KeyNavDirection direction,
469+ AtkObject* accessible);
470+
471+G_DEFINE_TYPE_WITH_CODE(UnityFilterBasicButtonAccessible,
472+ unity_filter_basic_button_accessible,
473+ NUX_TYPE_VIEW_ACCESSIBLE,
474+ G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
475+ atk_action_interface_init))
476+
477+static void
478+unity_filter_basic_button_accessible_class_init(UnityFilterBasicButtonAccessibleClass* klass)
479+{
480+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
481+ AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
482+
483+ gobject_class->dispose = unity_filter_basic_button_accessible_dispose;
484+ gobject_class->finalize = unity_filter_basic_button_accessible_finalize;
485+
486+ /* AtkObject */
487+ atk_class->initialize = unity_filter_basic_button_accessible_initialize;
488+ atk_class->get_name = unity_filter_basic_button_accessible_get_name;
489+ atk_class->ref_state_set = unity_filter_basic_button_accessible_ref_state_set;
490+}
491+
492+static void
493+unity_filter_basic_button_accessible_init(UnityFilterBasicButtonAccessible* session_button_accessible)
494+{
495+}
496+
497+static void
498+unity_filter_basic_button_accessible_dispose(GObject* object)
499+{
500+ G_OBJECT_CLASS(unity_filter_basic_button_accessible_parent_class)->dispose(object);
501+}
502+
503+static void
504+unity_filter_basic_button_accessible_finalize(GObject* object)
505+{
506+ G_OBJECT_CLASS(unity_filter_basic_button_accessible_parent_class)->finalize(object);
507+}
508+
509+AtkObject*
510+unity_filter_basic_button_accessible_new(nux::Object* object)
511+{
512+ AtkObject* accessible = NULL;
513+
514+ g_return_val_if_fail(dynamic_cast<FilterBasicButton*>(object), NULL);
515+
516+ accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE, NULL));
517+
518+ atk_object_initialize(accessible, object);
519+
520+ return accessible;
521+}
522+
523+/* AtkObject.h */
524+static void
525+unity_filter_basic_button_accessible_initialize(AtkObject* accessible,
526+ gpointer data)
527+{
528+ nux::Object* nux_object = NULL;
529+ FilterBasicButton* button = NULL;
530+
531+ ATK_OBJECT_CLASS(unity_filter_basic_button_accessible_parent_class)->initialize(accessible, data);
532+
533+ accessible->role = ATK_ROLE_TOGGLE_BUTTON;
534+
535+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
536+
537+ if (nux_object == NULL) /* defunct */
538+ return;
539+
540+ button = dynamic_cast<FilterBasicButton*>(nux_object);
541+
542+ if (button == NULL) /* defunct */
543+ return;
544+
545+ button->LayoutAdded.connect(sigc::bind(sigc::ptr_fun(on_layout_changed_cb),
546+ accessible, TRUE));
547+
548+ button->key_nav_focus_change.connect(sigc::bind(sigc::ptr_fun(on_focus_changed_cb), accessible));
549+}
550+
551+static const gchar*
552+unity_filter_basic_button_accessible_get_name(AtkObject* obj)
553+{
554+ const gchar* name;
555+
556+ g_return_val_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(obj), NULL);
557+
558+ name = ATK_OBJECT_CLASS(unity_filter_basic_button_accessible_parent_class)->get_name(obj);
559+ if (name == NULL)
560+ {
561+ FilterBasicButton* button = NULL;
562+
563+ button = dynamic_cast<FilterBasicButton*>(nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj)));
564+
565+ if (button == NULL) /* State is defunct */
566+ name = NULL;
567+ else
568+ name = button->GetLabel().c_str();
569+ }
570+
571+ if (name == NULL)
572+ {
573+ LOG_WARN(logger) << "Name == NULL";
574+ }
575+
576+ return name;
577+}
578+
579+static AtkStateSet*
580+unity_filter_basic_button_accessible_ref_state_set(AtkObject* obj)
581+{
582+ AtkStateSet* state_set = NULL;
583+ nux::Object* nux_object = NULL;
584+ FilterBasicButton* button = NULL;
585+
586+ g_return_val_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(obj), NULL);
587+
588+ state_set = ATK_OBJECT_CLASS(unity_filter_basic_button_accessible_parent_class)->ref_state_set(obj);
589+
590+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
591+
592+ if (nux_object == NULL) /* defunct */
593+ return state_set;
594+
595+ button = dynamic_cast<FilterBasicButton*>(nux_object);
596+
597+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
598+ atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
599+ atk_state_set_add_state(state_set, ATK_STATE_SENSITIVE);
600+ atk_state_set_add_state(state_set, ATK_STATE_VISIBLE);
601+ atk_state_set_add_state(state_set, ATK_STATE_SHOWING);
602+
603+ if (button->GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)
604+ {
605+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSED);
606+ atk_state_set_add_state(state_set, ATK_STATE_SELECTED);
607+ atk_state_set_add_state(state_set, ATK_STATE_ACTIVE);
608+ }
609+
610+ if (button->Active())
611+ atk_state_set_add_state(state_set, ATK_STATE_CHECKED);
612+
613+ return state_set;
614+}
615+
616+/* AtkAction */
617+static void
618+atk_action_interface_init(AtkActionIface *iface)
619+{
620+ iface->do_action = unity_filter_basic_button_accessible_do_action;
621+ iface->get_n_actions = unity_filter_basic_button_accessible_get_n_actions;
622+ iface->get_name = unity_filter_basic_button_accessible_get_action_name;
623+}
624+
625+static gboolean
626+unity_filter_basic_button_accessible_do_action(AtkAction *action,
627+ gint i)
628+{
629+ FilterBasicButton* button = NULL;
630+ nux::Object* nux_object = NULL;
631+
632+ g_return_val_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(action), FALSE);
633+
634+ nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(action));
635+ if (nux_object == NULL)
636+ return FALSE;
637+
638+ button = dynamic_cast<FilterBasicButton*>(nux_object);
639+
640+ button->Activate();
641+
642+ return TRUE;
643+}
644+
645+static gint
646+unity_filter_basic_button_accessible_get_n_actions(AtkAction *action)
647+{
648+ g_return_val_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(action), 0);
649+
650+ return 1;
651+}
652+
653+static const gchar*
654+unity_filter_basic_button_accessible_get_action_name(AtkAction *action,
655+ gint i)
656+{
657+ g_return_val_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(action), NULL);
658+ g_return_val_if_fail(i == 0, NULL);
659+
660+ return "activate";
661+}
662+
663+static void
664+on_layout_changed_cb(nux::View* view,
665+ nux::Layout* layout,
666+ AtkObject* accessible,
667+ gboolean is_add)
668+{
669+ g_return_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(accessible));
670+
671+ g_object_notify(G_OBJECT(accessible), "accessible-name");
672+}
673+
674+static void
675+on_focus_changed_cb(nux::Area* area,
676+ bool has_focus,
677+ nux::KeyNavDirection direction,
678+ AtkObject* accessible)
679+{
680+ g_return_if_fail(UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(accessible));
681+
682+ g_signal_emit_by_name(accessible, "focus-event", has_focus);
683+}
684
685=== added file 'plugins/unityshell/src/unity-filter-basic-button-accessible.h'
686--- plugins/unityshell/src/unity-filter-basic-button-accessible.h 1970-01-01 00:00:00 +0000
687+++ plugins/unityshell/src/unity-filter-basic-button-accessible.h 2015-05-25 05:13:52 +0000
688@@ -0,0 +1,53 @@
689+/*
690+ * Copyright (C) 2015 Canonical Ltd
691+ *
692+ * This program is free software: you can redistribute it and/or modify
693+ * it under the terms of the GNU General Public License version 3 as
694+ * published by the Free Software Foundation.
695+ *
696+ * This program is distributed in the hope that it will be useful,
697+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
698+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
699+ * GNU General Public License for more details.
700+ *
701+ * You should have received a copy of the GNU General Public License
702+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
703+ *
704+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
705+ */
706+
707+#ifndef UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE_H
708+#define UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE_H
709+
710+#include <atk/atk.h>
711+
712+#include "nux-view-accessible.h"
713+
714+G_BEGIN_DECLS
715+
716+#define UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE (unity_filter_basic_button_accessible_get_type ())
717+#define UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE, UnityFilterBasicButtonAccessible))
718+#define UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE, UnityFilterBasicButtonAccessibleClass))
719+#define UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE))
720+#define UNITY_IS_FILTER_BASIC_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE))
721+#define UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_FILTER_BASIC_BUTTON_ACCESSIBLE, UnityFilterBasicButtonAccessibleClass))
722+
723+typedef struct _UnityFilterBasicButtonAccessible UnityFilterBasicButtonAccessible;
724+typedef struct _UnityFilterBasicButtonAccessibleClass UnityFilterBasicButtonAccessibleClass;
725+
726+struct _UnityFilterBasicButtonAccessible
727+{
728+ NuxViewAccessible parent;
729+};
730+
731+struct _UnityFilterBasicButtonAccessibleClass
732+{
733+ NuxViewAccessibleClass parent_class;
734+};
735+
736+GType unity_filter_basic_button_accessible_get_type(void);
737+AtkObject* unity_filter_basic_button_accessible_new(nux::Object* object);
738+
739+G_END_DECLS
740+
741+#endif /* __UNITY_FILTER_BASIC_BUTTON_ACCESSIBLE_H__ */
742
743=== modified file 'plugins/unityshell/src/unitya11y.cpp'
744--- plugins/unityshell/src/unitya11y.cpp 2014-03-06 16:13:58 +0000
745+++ plugins/unityshell/src/unitya11y.cpp 2015-05-25 05:13:52 +0000
746@@ -39,11 +39,13 @@
747 #include "PanelView.h"
748 #include "DashView.h"
749 #include "PlacesGroup.h"
750+#include "ExpanderView.h"
751 #include "QuicklistView.h"
752 #include "QuicklistMenuItem.h"
753 #include "SwitcherView.h"
754 #include "TextInput.h"
755 #include "SessionButton.h"
756+#include "FilterBasicButton.h"
757 #include "unity-launcher-accessible.h"
758 #include "unity-launcher-icon-accessible.h"
759 #include "unity-panel-view-accessible.h"
760@@ -52,11 +54,13 @@
761 #include "unity-sctext-accessible.h"
762 #include "unity-rvgrid-accessible.h"
763 #include "unity-places-group-accessible.h"
764+#include "unity-expander-view-accessible.h"
765 #include "unity-quicklist-accessible.h"
766 #include "unity-quicklist-menu-item-accessible.h"
767 #include "unity-switcher-accessible.h"
768 #include "unity-text-input-accessible.h"
769 #include "unity-session-button-accessible.h"
770+#include "unity-filter-basic-button-accessible.h"
771
772 using namespace unity;
773 using namespace unity::dash;
774@@ -174,6 +178,12 @@
775 if (object->Type().IsDerivedFromType(PlacesGroup::StaticObjectType))
776 return unity_places_group_accessible_new(object);
777
778+ if (object->Type().IsDerivedFromType(ExpanderView::StaticObjectType))
779+ return unity_expander_view_accessible_new(object);
780+
781+ if (object->Type().IsDerivedFromType(FilterBasicButton::StaticObjectType))
782+ return unity_filter_basic_button_accessible_new(object);
783+
784 if (object->Type().IsDerivedFromType(QuicklistView::StaticObjectType))
785 return unity_quicklist_accessible_new(object);
786
787
788=== modified file 'unity-shared/CMakeLists.txt'
789--- unity-shared/CMakeLists.txt 2014-07-11 22:24:13 +0000
790+++ unity-shared/CMakeLists.txt 2015-05-25 05:13:52 +0000
791@@ -28,6 +28,7 @@
792 DeltaRestrainment.cpp
793 DesktopApplicationManager.cpp
794 EMConverter.cpp
795+ ExpanderView.cpp
796 GnomeFileManager.cpp
797 FontSettings.cpp
798 GraphicsUtils.cpp
799
800=== added file 'unity-shared/ExpanderView.cpp'
801--- unity-shared/ExpanderView.cpp 1970-01-01 00:00:00 +0000
802+++ unity-shared/ExpanderView.cpp 2015-05-25 05:13:52 +0000
803@@ -0,0 +1,59 @@
804+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
805+/*
806+ * Copyright (C) 2015 Canonical Ltd
807+ *
808+ * This program is free software: you can redistribute it and/or modify
809+ * it under the terms of the GNU General Public License version 3 as
810+ * published by the Free Software Foundation.
811+ *
812+ * This program is distributed in the hope that it will be useful,
813+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
814+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
815+ * GNU General Public License for more details.
816+ *
817+ * You should have received a copy of the GNU General Public License
818+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
819+ *
820+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
821+ */
822+
823+#include "ExpanderView.h"
824+
825+#include <Nux/Layout.h>
826+
827+namespace unity
828+{
829+
830+NUX_IMPLEMENT_OBJECT_TYPE(ExpanderView);
831+
832+ExpanderView::ExpanderView(NUX_FILE_LINE_DECL)
833+ : nux::View(NUX_FILE_LINE_PARAM)
834+{
835+ SetAcceptKeyNavFocusOnMouseDown(false);
836+ SetAcceptKeyNavFocusOnMouseEnter(true);
837+}
838+
839+void ExpanderView::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
840+{
841+}
842+
843+void ExpanderView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
844+{
845+ if (GetLayout())
846+ GetLayout()->ProcessDraw(graphics_engine, force_draw);
847+}
848+
849+bool ExpanderView::AcceptKeyNavFocus()
850+{
851+ return true;
852+}
853+
854+nux::Area* ExpanderView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
855+{
856+ if (TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type))
857+ return this;
858+
859+ return nullptr;
860+}
861+
862+} // namespace unity
863
864=== added file 'unity-shared/ExpanderView.h'
865--- unity-shared/ExpanderView.h 1970-01-01 00:00:00 +0000
866+++ unity-shared/ExpanderView.h 2015-05-25 05:13:52 +0000
867@@ -0,0 +1,47 @@
868+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
869+/*
870+ * Copyright (C) 2015 Canonical Ltd
871+ *
872+ * This program is free software: you can redistribute it and/or modify
873+ * it under the terms of the GNU General Public License version 3 as
874+ * published by the Free Software Foundation.
875+ *
876+ * This program is distributed in the hope that it will be useful,
877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
879+ * GNU General Public License for more details.
880+ *
881+ * You should have received a copy of the GNU General Public License
882+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
883+ *
884+ * Authored by: Luke Yelavich <luke.yelavich@canonical.com>
885+ */
886+
887+#ifndef EXPANDERVIEW_H
888+#define EXPANDERVIEW_H
889+
890+#include <Nux/Nux.h>
891+
892+namespace unity
893+{
894+
895+class ExpanderView : public nux::View
896+{
897+ NUX_DECLARE_OBJECT_TYPE(ExpanderView, nux::View);
898+public:
899+ ExpanderView(NUX_FILE_LINE_PROTO);
900+
901+ nux::Property<bool> expanded;
902+ nux::Property<std::string> label;
903+protected:
904+ void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw);
905+ void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw);
906+
907+ bool AcceptKeyNavFocus();
908+
909+ nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);
910+};
911+
912+}
913+
914+#endif
915
916=== modified file 'unity-shared/SearchBar.cpp'
917--- unity-shared/SearchBar.cpp 2014-09-04 22:11:33 +0000
918+++ unity-shared/SearchBar.cpp 2015-05-25 05:13:52 +0000
919@@ -88,45 +88,6 @@
920 }
921
922 DECLARE_LOGGER(logger, "unity.dash.searchbar");
923-namespace
924-{
925-class ExpanderView : public nux::View
926-{
927-public:
928- ExpanderView(NUX_FILE_LINE_DECL)
929- : nux::View(NUX_FILE_LINE_PARAM)
930- {
931- SetAcceptKeyNavFocusOnMouseDown(false);
932- SetAcceptKeyNavFocusOnMouseEnter(true);
933- }
934-
935-protected:
936- void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
937- {}
938-
939- void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
940- {
941- if (GetLayout())
942- GetLayout()->ProcessDraw(graphics_engine, force_draw);
943- }
944-
945- bool AcceptKeyNavFocus()
946- {
947- return true;
948- }
949-
950- nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
951- {
952- bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
953-
954- if (mouse_inside == false)
955- return nullptr;
956-
957- return this;
958- }
959-};
960-
961-}
962
963 namespace unity
964 {
965@@ -231,6 +192,9 @@
966 filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER);
967
968 expander_view_ = new ExpanderView(NUX_TRACKER_LOCATION);
969+ expander_view_->label = filter_str;
970+ expander_view_->expanded = showing_filters();
971+ showing_filters.changed.connect([this] (bool showing_filters) { expander_view_->expanded = showing_filters; });
972 expander_view_->SetVisible(false);
973 expander_view_->SetLayout(filter_layout_);
974 layout_->AddView(expander_view_, 0, nux::MINOR_POSITION_END, nux::MINOR_SIZE_FULL);
975
976=== modified file 'unity-shared/SearchBar.h'
977--- unity-shared/SearchBar.h 2014-08-06 19:46:43 +0000
978+++ unity-shared/SearchBar.h 2015-05-25 05:13:52 +0000
979@@ -26,6 +26,7 @@
980 #include <UnityCore/GLibSource.h>
981
982 #include "unity-shared/Introspectable.h"
983+#include "unity-shared/ExpanderView.h"
984
985 namespace nux
986 {
987@@ -110,7 +111,7 @@
988 StaticCairoText* hint_;
989 nux::LinearLayout* expander_layout_;
990 IMTextEntry* pango_entry_;
991- nux::View* expander_view_;
992+ ExpanderView* expander_view_;
993 nux::HLayout* filter_layout_;
994 StaticCairoText* show_filters_;
995 nux::VLayout* arrow_layout_;