Merge lp:~gordallott/unity/hud into lp:unity

Proposed by Gord Allott on 2012-01-25
Status: Merged
Approved by: Gord Allott on 2012-02-06
Approved revision: 1809
Merged at revision: 1900
Proposed branch: lp:~gordallott/unity/hud
Merge into: lp:unity
Prerequisite: lp:~gordallott/unity/rename-ubus-place-view-messages
Diff against target: 4304 lines (+3163/-177)
45 files modified
CMakeLists.txt (+1/-1)
UnityCore/CMakeLists.txt (+2/-0)
UnityCore/GLibDBusProxy.cpp (+0/-4)
UnityCore/Hud.cpp (+255/-0)
UnityCore/Hud.h (+127/-0)
manual-tests/Hud.txt (+57/-0)
plugins/unityshell/src/DashController.cpp (+12/-0)
plugins/unityshell/src/DashStyle.cpp (+136/-4)
plugins/unityshell/src/DashStyle.h (+9/-2)
plugins/unityshell/src/DashView.h (+1/-1)
plugins/unityshell/src/FilterAllButton.cpp (+1/-0)
plugins/unityshell/src/HudButton.cpp (+208/-0)
plugins/unityshell/src/HudButton.h (+81/-0)
plugins/unityshell/src/HudController.cpp (+385/-0)
plugins/unityshell/src/HudController.h (+113/-0)
plugins/unityshell/src/HudIcon.cpp (+95/-0)
plugins/unityshell/src/HudIcon.h (+73/-0)
plugins/unityshell/src/HudIconTextureSource.cpp (+110/-0)
plugins/unityshell/src/HudIconTextureSource.h (+51/-0)
plugins/unityshell/src/HudView.cpp (+398/-0)
plugins/unityshell/src/HudView.h (+118/-0)
plugins/unityshell/src/IMTextEntry.cpp (+1/-4)
plugins/unityshell/src/IMTextEntry.h (+0/-3)
plugins/unityshell/src/IconTexture.cpp (+12/-3)
plugins/unityshell/src/IconTexture.h (+5/-2)
plugins/unityshell/src/OverlayRenderer.cpp (+5/-5)
plugins/unityshell/src/OverlayRenderer.h (+1/-1)
plugins/unityshell/src/SearchBar.cpp (+124/-55)
plugins/unityshell/src/SearchBar.h (+11/-8)
plugins/unityshell/src/SearchBarSpinner.cpp (+1/-4)
plugins/unityshell/src/SearchBarSpinner.h (+2/-5)
plugins/unityshell/src/UBusMessages.h (+2/-0)
plugins/unityshell/src/unity-search-bar-accessible.cpp (+3/-3)
plugins/unityshell/src/unitya11y.cpp (+1/-1)
plugins/unityshell/src/unityshell.cpp (+67/-21)
plugins/unityshell/src/unityshell.h (+8/-1)
plugins/unityshell/unityshell.xml.in (+46/-41)
po/POTFILES.in (+1/-1)
standalone-clients/CMakeLists.txt (+41/-4)
standalone-clients/StandaloneHud.cpp (+171/-0)
tests/CMakeLists.txt (+4/-1)
tests/test_hud.cpp (+104/-0)
tests/test_service_hud.c (+268/-0)
tests/test_service_hud.h (+46/-0)
tests/test_service_main.c (+6/-2)
To merge this branch: bzr merge lp:~gordallott/unity/hud
Reviewer Review Type Date Requested Status
Gord Allott (community) Approve on 2012-02-06
John Lea (community) design review 2012-02-03 Approve on 2012-02-03
Andrea Azzarone (community) Needs Fixing on 2012-01-27
Mirco Müller (community) Needs Fixing on 2012-01-27
Thomi Richards (community) 2012-01-25 Needs Fixing on 2012-01-25
Marco Biscaro (community) Needs Fixing on 2012-01-25
Review via email: mp+90085@code.launchpad.net

This proposal supersedes a proposal from 2012-01-25.

To post a comment you must log in.
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal

50 - self->owner_->connected.emit();

Why is this needed?

review: Needs Information
lp:~gordallott/unity/hud updated on 2012-01-25
1791. By Gord Allott on 2012-01-25

merges in a branch to fix the seperation between DashSearchBar and HudSearchBar

Marco Biscaro (marcobiscaro2112) wrote :

- lens_ = service_lens_new();
- model_ = service_model_new();
+ //lens_ = service_lens_new();
+ //model_ = service_model_new();
+ hud_ = service_hud_new();

If this lines are no longer necessary, they can be removed instead of commented.

- g_object_unref(lens_);
- g_object_unref(model_);
+ //g_object_unref(lens_);
+ //g_object_unref(model_);
+ g_object_unref(hud_);

The same thing here.

review: Needs Fixing
Thomi Richards (thomir) wrote :

Hi,

There are a few introspection / autopilot issues with this branch:

Your HUDController derives from Introspectable, but you never use it. You need to:
 1) Add it to the introspection tree.At Diff line 2729 (where you create the HUDController instance) you need to call "AddChild(hud_controller_.get());". If the HUDController is ever deleted, you need to call "RemoveChild(hud_controller_.get());" BEFFORE the deletion takes place.

 2) Add properties to the HUD controller that will be useful in autopilot tests.

You need to repeat this process with all child objects of the HUDController that derive from Introspectable.

Finally, the string returned from "GetName" should be "HUDController" - you don't need to qualify it with "unity.hud".

In HUDIcon.h you #include "Introspectable.h", but never use it.

In HUDView.h, you've declared a "const gchar* GetName()" method, which is from Introspectable, but there's two problems:
 1) You don't derive from Introsopectable (as noted above, you should).
 2) That's not the correct method signiture - the return type is "std::string", and the method is const.

In the same class, make sure you add the search bar to the introspection tree - that way we can get the current search string.

Finally, it'd be really nice to have some autopilot tests written when this is merged. I don't mind helping you with this.

Cheers,

review: Needs Fixing
lp:~gordallott/unity/hud updated on 2012-01-26
1792. By Gord Allott on 2012-01-26

removes the callback on alt release

1793. By Gord Allott on 2012-01-26

updated to latest unity trunk

1794. By Gord Allott on 2012-01-26

fixed conflicts

1795. By Gord Allott on 2012-01-26

fixes the interactions with the dash

1796. By Gord Allott on 2012-01-26

enables tests that were disabled

Gord Allott (gordallott) wrote :

> Hi,
>
> There are a few introspection / autopilot issues with this branch:
>
> Your HUDController derives from Introspectable, but you never use it. You need
> to:
> 1) Add it to the introspection tree.At Diff line 2729 (where you create the
> HUDController instance) you need to call "AddChild(hud_controller_.get());".
> If the HUDController is ever deleted, you need to call
> "RemoveChild(hud_controller_.get());" BEFFORE the deletion takes place.
>
> 2) Add properties to the HUD controller that will be useful in autopilot
> tests.
>
>
> You need to repeat this process with all child objects of the HUDController
> that derive from Introspectable.
>
> Finally, the string returned from "GetName" should be "HUDController" - you
> don't need to qualify it with "unity.hud".
>
> In HUDIcon.h you #include "Introspectable.h", but never use it.
>
> In HUDView.h, you've declared a "const gchar* GetName()" method, which is from
> Introspectable, but there's two problems:
> 1) You don't derive from Introsopectable (as noted above, you should).
> 2) That's not the correct method signiture - the return type is
> "std::string", and the method is const.
>
> In the same class, make sure you add the search bar to the introspection tree
> - that way we can get the current search string.
>

Very much so, Introspection was on my todo list for earlier in the week before last minute changes bumped it off, will fix that up

> Finally, it'd be really nice to have some autopilot tests written when this is
> merged. I don't mind helping you with this.
>

Already have a guy from Systems helping out there, for now manual but he's going through and converting them :)

> Cheers,

Gord Allott (gordallott) wrote :

> - lens_ = service_lens_new();
> - model_ = service_model_new();
> + //lens_ = service_lens_new();
> + //model_ = service_model_new();
> + hud_ = service_hud_new();
>
> If this lines are no longer necessary, they can be removed instead of
> commented.
>
> - g_object_unref(lens_);
> - g_object_unref(model_);
> + //g_object_unref(lens_);
> + //g_object_unref(model_);
> + g_object_unref(hud_);
>
> The same thing here.

Actually was just left over debugging code ;)

lp:~gordallott/unity/hud updated on 2012-01-27
1797. By Gord Allott on 2012-01-27

merged with trunk

1798. By Gord Allott on 2012-01-27

changed potfiles

Michal Hruby (mhr3) wrote :

49 self->connected_ = true;
50 - self->owner_->connected.emit();

So can we at least not fool IsConnected() users (ie remove the "self->connected_ = true;" as well pls)

150 + GVariant* query_key = g_variant_get_child_value(query, 2);

Please check that the variant has at least 2 children (or at least that query_key != NULL)

153 + GVariant* queries = g_variant_get_child_value(query, 1);
173, 176, 189, 192

Same

Mirco Müller (macslow) wrote :

Getting this error during compilation atm:

CMakeFiles/test-gtest-dbus.dir/test_hud.cpp.o: In function `TestBody':
/tmp/fasel/unity/tests/test_hud.cpp:30: undefined reference to `unity::hud::Hud::Hud(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/tmp/fasel/unity/tests/test_hud.cpp:93: undefined reference to `unity::hud::Hud::RequestQuery(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/tmp/fasel/unity/tests/test_hud.cpp:100: undefined reference to `unity::hud::Hud::CloseQuery()'
collect2: ld returned 1 exit status
make[2]: *** [tests/test-gtest-dbus] Error 1
make[1]: *** [tests/CMakeFiles/test-gtest-dbus.dir/all] Error 2
make: *** [all] Error 2

review: Needs Fixing
Mirco Müller (macslow) wrote :

Above mentioned issue solved... typical cmake picking up the wrong libunity-core.so *sigh³*

Mirco Müller (macslow) wrote :

Is the HUD really meant to use the exact same button-visuals from the dash? Does Design demand that?

Should the HUD-searchbar not be of the same width as the Dash-searchbar (in non-fullscreen state at least)?

Please get into the habbit of using const int/float in an unnamed namespace instead of "magic" numbers for padding/margins/sizes... you don't use that consistently across this branch... check:

...
+ layout_->AddLayout(new nux::SpaceLayout(8,8,8,8), 0);
...
+ icon_layout->SetVerticalExternalMargin(12);
...
+ search_bar_ = new unity::SearchBar(940, true);
...
+ button_views_->SetHorizontalExternalMargin(12);
+ button_views_->SetMaximumWidth(940);
...
+ hud_controller_->launcher_width = optionGetIconSize() + 18;

review: Needs Fixing
Andrea Azzarone (azzar1) wrote :

997 + nux::Geometry content_geo = view_->GetGeometry();
998 + nux::Geometry geo = GetIdealWindowGeometry();

If is it possible, please do something like this:

997 + nux::Geometry const& content_geo = view_->GetGeometry();
998 + nux::Geometry geo(GetIdealWindowGeometry());

or at least:
997 + nux::Geometry content_geo(view_->GetGeometry());
998 + nux::Geometry geo(GetIdealWindowGeometry());

Andrea Azzarone (azzar1) :
review: Needs Fixing
lp:~gordallott/unity/hud updated on 2012-02-03
1799. By Gord Allott on 2012-01-30

adds introspection to hud

1800. By Gord Allott on 2012-01-31

fix about a million conflicts with trunk, updated to trunk (5.2)

1801. By Gord Allott on 2012-01-31

merge with trunk again, fix even more conflicts

1802. By Gord Allott on 2012-02-02

stop tricking applications into thinking GDbus is connected when it is not

1803. By Gord Allott on 2012-02-02

merged in alignment branch

1804. By Gord Allott on 2012-02-02

merge in branch to remove magic numbers

1805. By Gord Allott on 2012-02-02

more checks in UnityCore/Hud

1806. By Gord Allott on 2012-02-02

add missing files

1807. By Gord Allott on 2012-02-02

working launcher icons

1808. By Gord Allott on 2012-02-03

more visual refinements

John Lea (johnlea) wrote :

A great improvement, still a bunch of outstanding changes required but a good step in the right direction. Branch approved, look forward to seeing the next iteration with further finesse.

review: Approve (design review)
lp:~gordallott/unity/hud updated on 2012-02-06
1809. By Gord Allott on 2012-02-06

updated to trunk to fix conflicts

Gord Allott (gordallott) wrote :

approving as latest revision just fixed up conflicts

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2012-02-03 15:02:15 +0000
3+++ CMakeLists.txt 2012-02-06 11:00:29 +0000
4@@ -113,7 +113,7 @@
5 SET (BOOT_LOGGER_FLAG "-DENABLE_LOGGER")
6 endif (BOOT_LOGGER)
7
8-SET (MAINTAINER_CFLAGS "-Werror -Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds")
9+SET (MAINTAINER_CFLAGS "-Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Warray-bounds")
10 option (DISABLE_MAINTAINER_CFLAGS "Disable maintainer CFlags" OFF)
11 if (DISABLE_MAINTAINER_CFLAGS)
12 SET (MAINTAINER_CFLAGS "")
13
14=== modified file 'UnityCore/CMakeLists.txt'
15--- UnityCore/CMakeLists.txt 2012-01-18 13:32:26 +0000
16+++ UnityCore/CMakeLists.txt 2012-02-06 11:00:29 +0000
17@@ -21,6 +21,7 @@
18 GLibSignal-inl.h
19 GLibWrapper.h
20 GLibWrapper-inl.h
21+ Hud.h
22 HomeLens.h
23 IndicatorEntry.h
24 Indicator.h
25@@ -54,6 +55,7 @@
26 GLibDBusProxy.cpp
27 GLibSignal.cpp
28 GLibWrapper.cpp
29+ Hud.cpp
30 HomeLens.cpp
31 Indicator.cpp
32 IndicatorEntry.cpp
33
34=== modified file 'UnityCore/GLibDBusProxy.cpp'
35--- UnityCore/GLibDBusProxy.cpp 2012-01-19 11:01:58 +0000
36+++ UnityCore/GLibDBusProxy.cpp 2012-02-06 11:00:29 +0000
37@@ -141,11 +141,7 @@
38 gpointer impl)
39 {
40 DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl);
41-
42 LOG_DEBUG(logger) << self->name_ << " appeared";
43-
44- self->connected_ = true;
45- self->owner_->connected.emit();
46 }
47
48 void DBusProxy::Impl::OnNameVanished(GDBusConnection* connection,
49
50=== added file 'UnityCore/Hud.cpp'
51--- UnityCore/Hud.cpp 1970-01-01 00:00:00 +0000
52+++ UnityCore/Hud.cpp 2012-02-06 11:00:29 +0000
53@@ -0,0 +1,255 @@
54+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
55+/*
56+ * Copyright (C) 2011 Canonical Ltd
57+ *
58+ * This program is free software: you can redistribute it and/or modify
59+ * it under the terms of the GNU General Public License version 3 as
60+ * published by the Free Software Foundation.
61+ *
62+ * This program is distributed in the hope that it will be useful,
63+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
64+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65+ * GNU General Public License for more details.
66+ *
67+ * You should have received a copy of the GNU General Public License
68+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
69+ *
70+ * Authored by: Gordon Allott <gord.allott@canonical.com>
71+ */
72+//
73+#include "Hud.h"
74+
75+#include <gio/gio.h>
76+#include <glib.h>
77+#include <NuxCore/Logger.h>
78+#include "GLibWrapper.h"
79+#include "GLibDBusProxy.h"
80+
81+#include "config.h"
82+
83+#include <sigc++/bind.h>
84+
85+namespace unity
86+{
87+namespace hud
88+{
89+
90+namespace
91+{
92+nux::logging::Logger logger("unity.hud.hud");
93+const int request_number_of_results = 6;
94+}
95+
96+// Impl classes
97+class HudImpl
98+{
99+public:
100+ HudImpl(std::string const& dbus_name,
101+ std::string const& dbus_path,
102+ Hud *parent)
103+ : query_key_(NULL)
104+ , proxy_(dbus_name, dbus_path, "com.canonical.hud")
105+ , parent_(parent)
106+ {
107+ LOG_DEBUG(logger) << "Hud init with name: " << dbus_name << "and path: " << dbus_path;
108+ proxy_.connected.connect([&]() {
109+ LOG_DEBUG(logger) << "Hud Connected";
110+ parent_->connected = true;
111+ });
112+
113+ proxy_.Connect("UpdatedQuery", sigc::mem_fun(this, &HudImpl::UpdateQueryCallback));
114+ }
115+
116+ void QueryCallback(GVariant* data);
117+ void UpdateQueryCallback(GVariant* data);
118+ void BuildQueries(GVariant* query_array);
119+ void ExecuteByKey(GVariant* key, unsigned int timestamp);
120+ void ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp);
121+ void CloseQuery();
122+
123+ GVariant* query_key_;
124+ Hud::Queries queries_;
125+ glib::DBusProxy proxy_;
126+ Hud* parent_;
127+};
128+
129+void HudImpl::ExecuteByKey(GVariant* key, unsigned int timestamp)
130+{
131+ LOG_DEBUG(logger) << "Executing by Key";
132+
133+ GVariantBuilder tuple;
134+ g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
135+ g_variant_builder_add_value(&tuple, g_variant_new_variant(key));
136+ g_variant_builder_add_value(&tuple, g_variant_new_uint32(timestamp));
137+
138+ proxy_.Call("ExecuteQuery", g_variant_builder_end(&tuple));
139+}
140+
141+void HudImpl::ExecuteQueryByStringCallback(GVariant* query, unsigned int timestamp)
142+{
143+ if (g_variant_n_children(query) < 3)
144+ {
145+ LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3";
146+ return;
147+ }
148+
149+ queries_.clear();
150+
151+ GVariant* query_key = g_variant_get_child_value(query, 2);
152+ query_key_ = query_key;
153+
154+ GVariant* queries = g_variant_get_child_value(query, 1);
155+ BuildQueries(queries);
156+ g_variant_unref(queries);
157+
158+ if (queries_.empty() == false)
159+ {
160+ // we now execute based off the first result
161+ ExecuteByKey(queries_.front()->key, timestamp);
162+ CloseQuery();
163+ }
164+}
165+
166+void HudImpl::QueryCallback(GVariant* query)
167+{
168+ if (g_variant_n_children(query) < 3)
169+ {
170+ LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3";
171+ return;
172+ }
173+ queries_.clear();
174+
175+ // extract the information from the GVariants
176+ GVariant* target = g_variant_get_child_value(query, 0);
177+ g_variant_unref(target);
178+
179+ GVariant* query_key = g_variant_get_child_value(query, 2);
180+ query_key_ = query_key;
181+
182+ GVariant* queries = g_variant_get_child_value(query, 1);
183+ BuildQueries(queries);
184+ g_variant_unref(queries);
185+
186+ parent_->queries_updated.emit(queries_);
187+}
188+
189+void HudImpl::UpdateQueryCallback(GVariant* query)
190+{
191+ if (g_variant_n_children(query) < 3)
192+ {
193+ LOG_ERROR(logger) << "Received (" << g_variant_n_children(query) << ") children in a query, expected 3";
194+ return;
195+ }
196+ // as we are expecting an update, we want to check
197+ // and make sure that we are the actual receivers of
198+ // the signal
199+
200+ GVariant* query_key = g_variant_get_child_value(query, 2);
201+ if (g_variant_equal(query_key_, query_key))
202+ {
203+ GVariant* queries = g_variant_get_child_value(query, 1);
204+ BuildQueries(queries);
205+ g_variant_unref(queries);
206+ }
207+}
208+
209+void HudImpl::BuildQueries(GVariant* query_array)
210+{
211+ GVariantIter iter;
212+ g_variant_iter_init(&iter, query_array);
213+ glib::String formatted_text;
214+ glib::String icon;
215+ glib::String item_icon;
216+ glib::String completion_text;
217+ glib::String shortcut;
218+ GVariant* key = NULL;
219+
220+ while (g_variant_iter_loop(&iter, "(sssssv)",
221+ &formatted_text, &icon, &item_icon, &completion_text, &shortcut, &key))
222+ {
223+ queries_.push_back(Query::Ptr(new Query(formatted_text,
224+ icon,
225+ item_icon,
226+ completion_text,
227+ shortcut,
228+ key)));
229+ }
230+}
231+
232+void HudImpl::CloseQuery()
233+{
234+ if (query_key_ == NULL)
235+ {
236+ LOG_WARN(logger) << "Attempted to close the hud connection without starting it";
237+ }
238+ else
239+ {
240+ GVariant* paramaters = g_variant_new("(v)", query_key_);
241+ proxy_.Call("CloseQuery", paramaters);
242+ g_variant_unref(query_key_);
243+ query_key_ = NULL;
244+ queries_.clear();
245+ }
246+}
247+
248+
249+Hud::Hud(std::string const& dbus_name,
250+ std::string const& dbus_path)
251+ : connected(false)
252+ , pimpl_(new HudImpl(dbus_name, dbus_path, this))
253+{
254+ pimpl_->parent_ = this;
255+}
256+
257+Hud::~Hud()
258+{
259+ delete pimpl_;
260+}
261+
262+void Hud::RequestQuery(std::string const& search_string)
263+{
264+ LOG_DEBUG(logger) << "Getting Query: " << search_string;
265+ if (pimpl_->query_key_ != NULL)
266+ {
267+ CloseQuery();
268+ }
269+
270+ GVariant* paramaters = g_variant_new("(si)",
271+ search_string.c_str(),
272+ request_number_of_results);
273+ pimpl_->proxy_.Call("StartQuery", paramaters, sigc::mem_fun(this->pimpl_, &HudImpl::QueryCallback));
274+}
275+
276+
277+void Hud::ExecuteQuery(Query::Ptr query, unsigned int timestamp)
278+{
279+ LOG_DEBUG(logger) << "Executing query: " << query->formatted_text;
280+ pimpl_->ExecuteByKey(query->key, timestamp);
281+}
282+
283+void Hud::ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp)
284+{
285+ //Does a search then executes the result based on that search
286+ LOG_DEBUG(logger) << "Executing by string" << execute_string;
287+ if (pimpl_->query_key_ != NULL)
288+ {
289+ CloseQuery();
290+ }
291+
292+ GVariant* paramaters = g_variant_new("(si)",
293+ execute_string.c_str(),
294+ 1);
295+
296+ auto functor = sigc::mem_fun(this->pimpl_, &HudImpl::ExecuteQueryByStringCallback);
297+
298+ pimpl_->proxy_.Call("StartQuery", paramaters, sigc::bind(functor, timestamp));
299+}
300+
301+void Hud::CloseQuery()
302+{
303+ //Send close hint to the hud
304+ pimpl_->CloseQuery();
305+}
306+
307+}
308+}
309
310=== added file 'UnityCore/Hud.h'
311--- UnityCore/Hud.h 1970-01-01 00:00:00 +0000
312+++ UnityCore/Hud.h 2012-02-06 11:00:29 +0000
313@@ -0,0 +1,127 @@
314+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
315+/*
316+ * Copyright (C) 2011 Canonical Ltd
317+ *
318+ * This program is free software: you can redistribute it and/or modify
319+ * it under the terms of the GNU General Public License version 3 as
320+ * published by the Free Software Foundation.
321+ *
322+ * This program is distributed in the hope that it will be useful,
323+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
324+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
325+ * GNU General Public License for more details.
326+ *
327+ * You should have received a copy of the GNU General Public License
328+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
329+ *
330+ * Authored by: Gordon Allott <gord.allott@canonical.com>
331+ */
332+
333+#ifndef UNITY_HUD_H
334+#define UNITY_HUD_H
335+
336+#include <deque>
337+#include <string>
338+#include <memory>
339+#include <NuxCore/Property.h>
340+#include <glib/gvariant.h>
341+
342+namespace unity
343+{
344+namespace hud
345+{
346+
347+
348+class Query
349+{
350+public:
351+ typedef std::shared_ptr<Query> Ptr;
352+
353+ Query(std::string const& formatted_text_, std::string const& icon_name_,
354+ std::string const& item_icon_, std::string const& completion_text_,
355+ std::string const& shortcut_, GVariant* key_)
356+ : formatted_text(formatted_text_)
357+ , icon_name(icon_name_)
358+ , item_icon(item_icon_)
359+ , completion_text(completion_text_)
360+ , shortcut(shortcut_)
361+ , key(key_)
362+ {
363+ g_variant_ref(key);
364+ }
365+
366+ ~Query()
367+ {
368+ g_variant_unref(key);
369+ }
370+
371+ Query(const Query &rhs);
372+ Query& operator=(Query);
373+
374+ std::string formatted_text; // Pango formatted text
375+ std::string icon_name; // icon name using standard lookups
376+ std::string item_icon; // Future API
377+ std::string completion_text; // Non formatted text f or completion
378+ std::string shortcut; // Shortcut key
379+ GVariant *key;
380+};
381+
382+
383+class HudImpl;
384+class Hud
385+{
386+public:
387+ typedef std::shared_ptr<Hud> Ptr;
388+ typedef std::deque<Query::Ptr> Queries;
389+
390+ /*
391+ * Constructor for the hud
392+ * \param dbus_name string that specifies the name of the hud service
393+ * \param dbus_path string that specifies the path of the hud service
394+ */
395+ Hud(std::string const& dbus_name,
396+ std::string const& dbus_path);
397+
398+ ~Hud();
399+
400+ Hud(const Hud &rhs);
401+ Hud& operator=(Hud);
402+
403+ nux::Property<std::string> target;
404+ nux::Property<bool> connected;
405+
406+ /*
407+ * Queries the service for new suggestions, will fire off the
408+ * suggestion_search_finished signal when the suggestions are returned
409+ */
410+ void RequestQuery(std::string const& search_string);
411+
412+ /*
413+ * Executes a Query
414+ */
415+ void ExecuteQuery(Query::Ptr query, unsigned int timestamp);
416+
417+ /*
418+ * Executes a query that returns from a search,
419+ * Implicitly calls CloseQuery();
420+ */
421+ void ExecuteQueryBySearch(std::string execute_string, unsigned int timestamp);
422+
423+ /*
424+ * Closes the query connection, call when the hud closes
425+ */
426+ void CloseQuery();
427+
428+ /*
429+ * Returns a deque of Query types when the service provides them
430+ */
431+ sigc::signal<void, Queries> queries_updated;
432+
433+private:
434+ HudImpl *pimpl_;
435+};
436+
437+}
438+}
439+
440+#endif /* UNITY_HUD_H */
441
442=== added file 'manual-tests/Hud.txt'
443--- manual-tests/Hud.txt 1970-01-01 00:00:00 +0000
444+++ manual-tests/Hud.txt 2012-02-06 11:00:29 +0000
445@@ -0,0 +1,57 @@
446+For reference, the term Tap means to press the indicated key and release it, within a timeframe of 50ms
447+
448+Hud Invocate
449+-----------
450+This test makes sure that the hud presents itself, the launcher hides
451+and the panel changes
452+
453+#. Tap Alt
454+
455+Outcome
456+ The hud interface presents itself with no other interface such as the dash present.
457+ The Launcher hides, the panel becomes transparent with a colour tint matching the hud
458+
459+Hud Search
460+-----------
461+This test makes sure that the hud will search and activate items.
462+
463+#. Ensure the devices indicator is present
464+#. Tap Alt
465+#. Type "system" to search for the "System settings..." item in the devices indicator
466+#. Press return to activate the search query.
467+
468+Outcome
469+ The system settings interface presents itself, the hud disappears.
470+ If the hud does not disappear, this test failed. If the system settings interface
471+ did not present itself, this test did *not* fail.
472+
473+
474+Hud Key-Navigation
475+-----------
476+This test ensures the hud key navigation is intact
477+
478+#. Ensure the messaging indicator is present
479+#. Tap Alt
480+#. Type "Message" to search for items from the messaging indicator
481+#. Press down twice
482+#. Press return
483+
484+Outcome
485+ The item selected will activate and the hud with disappear.
486+ If the hud does not disappear, this test failed.
487+ If the buttons under the search box do not highlight, this test failed.
488+
489+
490+Hud Dismiss
491+----------
492+This test ensures that the hud is dismissable
493+
494+#. Tap Alt
495+#. Type "test"
496+#. Press escape
497+#. Click anywhere on the screen that is not the hud interface
498+
499+Outcome
500+ After pressing escape in step three, the text "test" should be removed from the hud search
501+ After step four, the hud should dismiss itself and not be present.
502+
503
504=== modified file 'plugins/unityshell/src/DashController.cpp'
505--- plugins/unityshell/src/DashController.cpp 2012-02-04 01:55:49 +0000
506+++ plugins/unityshell/src/DashController.cpp 2012-02-06 11:00:29 +0000
507@@ -118,6 +118,18 @@
508 sigc::mem_fun(this, &Controller::OnActivateRequest));
509 ubus_manager_.RegisterInterest(UBUS_DASH_ABOUT_TO_SHOW,
510 [&] (GVariant*) { EnsureDash(); });
511+ ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&] (GVariant *data) {
512+ unity::glib::String overlay_identity;
513+ gboolean can_maximise = FALSE;
514+ gint32 overlay_monitor = 0;
515+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);
516+
517+ // hide if something else is coming up
518+ if (g_strcmp0(overlay_identity, "dash"))
519+ {
520+ HideDash(true);
521+ }
522+ });
523 }
524
525 void Controller::EnsureDash()
526
527=== modified file 'plugins/unityshell/src/DashStyle.cpp'
528--- plugins/unityshell/src/DashStyle.cpp 2012-01-19 11:57:37 +0000
529+++ plugins/unityshell/src/DashStyle.cpp 2012-02-06 11:00:29 +0000
530@@ -119,6 +119,7 @@
531 void Text(cairo_t* cr,
532 nux::Color const& color,
533 std::string const& label,
534+ int font_size = -1,
535 double horizMargin = 10.0,
536 Alignment alignment = Alignment::CENTER);
537
538@@ -1325,6 +1326,7 @@
539 void Style::Impl::Text(cairo_t* cr,
540 nux::Color const& color,
541 std::string const& label,
542+ int text_size,
543 double horizMargin,
544 Alignment alignment)
545 {
546@@ -1358,6 +1360,11 @@
547 else
548 desc = pango_font_description_from_string(fontName);
549
550+ if (text_size > 0)
551+ {
552+ pango_font_description_set_absolute_size(desc, text_size * PANGO_SCALE);
553+ }
554+
555 PangoWeight weight;
556 switch (regular_text_weight_)
557 {
558@@ -1428,6 +1435,7 @@
559 pango_layout_get_extents(layout, &ink, &log);
560 x = horizMargin; // let pango alignment handle the x position
561 y = ((double) h - pango_units_to_double(log.height)) / 2.0;
562+
563 cairo_move_to(cr, x, y);
564 pango_cairo_show_layout(cr, layout);
565
566@@ -1530,7 +1538,9 @@
567 cairo_set_operator(cr, old);
568 }
569
570-bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, std::string const& label, Alignment alignment)
571+bool Style::Button(cairo_t* cr, nux::ButtonVisualState state,
572+ std::string const& label, int font_size,
573+ Alignment alignment, bool zeromargin)
574 {
575 // sanity checks
576 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
577@@ -1539,8 +1549,10 @@
578 if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE)
579 return false;
580
581- unsigned int garnish = GetButtonGarnishSize();
582-
583+ unsigned int garnish = 0;
584+ if (zeromargin == false)
585+ garnish = GetButtonGarnishSize();
586+
587 //ButtonOutlinePath(cr, true);
588 double w = cairo_image_surface_get_width(cairo_get_target(cr));
589 double h = cairo_image_surface_get_height(cairo_get_target(cr));
590@@ -1571,7 +1583,6 @@
591 cairo_fill_preserve(cr);
592 }
593 cairo_set_source_rgba(cr, pimpl->button_label_border_color_[state]);
594- //cairo_set_line_width(cr, pimpl->button_label_border_size_[state]);
595 cairo_stroke(cr);
596
597 pimpl->DrawOverlay(cr,
598@@ -1582,12 +1593,133 @@
599 pimpl->Text(cr,
600 pimpl->button_label_text_color_[state],
601 label,
602+ font_size,
603 10.0,
604 alignment);
605
606 return true;
607 }
608
609+bool Style::SquareButton(cairo_t* cr, nux::ButtonVisualState state,
610+ std::string const& label, bool curve_bottom,
611+ int font_size, Alignment alignment,
612+ bool zeromargin)
613+{
614+ // sanity checks
615+ if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
616+ return false;
617+
618+ if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE)
619+ return false;
620+
621+ unsigned int garnish = 0;
622+ if (zeromargin == false)
623+ garnish = GetButtonGarnishSize();
624+
625+ double w = cairo_image_surface_get_width(cairo_get_target(cr));
626+ double h = cairo_image_surface_get_height(cairo_get_target(cr));
627+
628+ double x = garnish;
629+ double y = garnish;
630+
631+ double width = w - (2.0 * garnish) - 1.0;
632+ double height = h - (2.0 * garnish) - 1.0;
633+
634+ bool odd = true;
635+ double radius = 7.0;
636+
637+ // draw the grid background
638+ {
639+ cairo_set_line_width(cr, 1);
640+ cairo_move_to(cr, _align(x + width, odd), _align(y, odd));
641+ if (curve_bottom)
642+ {
643+ LOG_DEBUG(logger) << "curve: " << _align(x + width, odd) << " - " << _align(y + height - radius, odd);
644+ // line to bottom-right corner
645+ cairo_line_to(cr, _align(x + width, odd), _align(y + height - radius, odd));
646+
647+ // line to bottom-right, left of the corner
648+ cairo_arc(cr,
649+ _align(x + width - radius, odd),
650+ _align(y + height - radius, odd),
651+ radius,
652+ 0.0f * G_PI / 180.0f,
653+ 90.0f * G_PI / 180.0f);
654+
655+ // line to bottom-left, right of the corner
656+ cairo_line_to(cr, _align(x + radius, odd), _align(y + height, odd));
657+
658+ // line to bottom-left, above the corner
659+ cairo_arc(cr,
660+ _align(x + radius, odd),
661+ _align(y + height - radius, odd),
662+ radius,
663+ 90.0f * G_PI / 180.0f,
664+ 180.0f * G_PI / 180.0f);
665+
666+ // line to top
667+ cairo_line_to(cr, _align(x, odd), _align(y, odd));
668+ }
669+ else
670+ {
671+ cairo_line_to(cr, _align(x + width, odd), _align(y + height, odd));
672+ cairo_line_to(cr, _align(x, odd), _align(x + height, odd));
673+ cairo_line_to(cr, _align(x, odd), _align(y, odd));
674+ }
675+
676+ cairo_set_source_rgba(cr, pimpl->button_label_border_color_[nux::ButtonVisualState::VISUAL_STATE_NORMAL]);
677+ cairo_stroke(cr);
678+ }
679+
680+ cairo_set_line_width(cr, pimpl->button_label_border_size_[state]);
681+ odd = cairo_get_line_width(cr) == 2.0 ? false : true;
682+
683+
684+ if (pimpl->button_label_border_size_[state] == 2.0)
685+ {
686+ x += 1;
687+ y += 1;
688+ width -= 1.0;
689+ height -= 1.0;
690+ }
691+
692+ if (state == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
693+ {
694+ RoundedRect(cr,
695+ 1.0,
696+ _align(x, odd), _align(y, odd),
697+ 5.0,
698+ _align(width, odd), _align(height, odd));
699+
700+ if (pimpl->button_label_fill_color_[state].alpha != 0.0)
701+ {
702+ cairo_set_source_rgba(cr, pimpl->button_label_fill_color_[state]);
703+ cairo_fill_preserve(cr);
704+ }
705+ cairo_set_source_rgba(cr, pimpl->button_label_border_color_[state]);
706+ cairo_stroke(cr);
707+ }
708+
709+ pimpl->DrawOverlay(cr,
710+ pimpl->button_label_overlay_opacity_[state],
711+ pimpl->button_label_overlay_mode_[state],
712+ pimpl->button_label_blur_size_[state] * 0.75);
713+
714+ // FIXME - magic value of 42 here for the offset in the HUD,
715+ // replace with a nicer style system that lets hud override
716+ // default values when it needs to
717+ pimpl->Text(cr,
718+ pimpl->button_label_text_color_[state],
719+ label,
720+ font_size,
721+ 42.0 + 10.0,
722+ alignment);
723+
724+ cairo_surface_write_to_png(cairo_get_target(cr), "/tmp/wut.png");
725+
726+ return true;
727+}
728+
729 bool Style::StarEmpty(cairo_t* cr, nux::ButtonVisualState state)
730 {
731 // sanity checks
732
733=== modified file 'plugins/unityshell/src/DashStyle.h'
734--- plugins/unityshell/src/DashStyle.h 2012-01-19 11:51:57 +0000
735+++ plugins/unityshell/src/DashStyle.h 2012-02-06 11:00:29 +0000
736@@ -87,8 +87,15 @@
737 static Style& Instance();
738
739 virtual bool Button(cairo_t* cr, nux::ButtonVisualState state,
740- std::string const& label,
741- Alignment alignment = Alignment::CENTER);
742+ std::string const& label, int font_size=-1,
743+ Alignment alignment = Alignment::CENTER,
744+ bool zeromargin=false);
745+
746+ virtual bool SquareButton(cairo_t* cr, nux::ButtonVisualState state,
747+ std::string const& label, bool curve_bottom,
748+ int font_size=-1,
749+ Alignment alignment = Alignment::CENTER,
750+ bool zeromargin=false);
751
752 virtual bool StarEmpty(cairo_t* cr, nux::ButtonVisualState state);
753
754
755=== modified file 'plugins/unityshell/src/DashView.h'
756--- plugins/unityshell/src/DashView.h 2012-01-27 06:58:20 +0000
757+++ plugins/unityshell/src/DashView.h 2012-02-06 11:00:29 +0000
758@@ -30,7 +30,7 @@
759 #include <UnityCore/HomeLens.h>
760
761 #include "BackgroundEffectHelper.h"
762-#include "DashSearchBar.h"
763+#include "SearchBar.h"
764 #include "Introspectable.h"
765 #include "LensBar.h"
766 #include "LensView.h"
767
768=== modified file 'plugins/unityshell/src/FilterAllButton.cpp'
769--- plugins/unityshell/src/FilterAllButton.cpp 2012-01-10 14:09:12 +0000
770+++ plugins/unityshell/src/FilterAllButton.cpp 2012-02-06 11:00:29 +0000
771@@ -59,6 +59,7 @@
772 {
773 if (filter_ and Active())
774 filter_->Clear();
775+ QueueDraw();
776 }
777
778 void FilterAllButton::OnFilteringChanged(bool filtering)
779
780=== added file 'plugins/unityshell/src/HudButton.cpp'
781--- plugins/unityshell/src/HudButton.cpp 1970-01-01 00:00:00 +0000
782+++ plugins/unityshell/src/HudButton.cpp 2012-02-06 11:00:29 +0000
783@@ -0,0 +1,208 @@
784+/*
785+ * Copyright 2011 Canonical Ltd.
786+ *
787+ * This program is free software: you can redistribute it and/or modify it
788+ * under the terms of the GNU Lesser General Public License version 3, as
789+ * published by the Free Software Foundation.
790+ *
791+ * This program is distributed in the hope that it will be useful, but
792+ * WITHOUT ANY WARRANTY; without even the implied warranties of
793+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
794+ * PURPOSE. See the applicable version of the GNU Lesser General Public
795+ * License for more details.
796+ *
797+ * You should have received a copy of both the GNU Lesser General Public
798+ * License version 3 along with this program. If not, see
799+ * <http://www.gnu.org/licenses/>
800+ *
801+ * Authored by: Gordon Allott <gord.allott@canonical.com>
802+ *
803+ */
804+#include "config.h"
805+
806+#include <pango/pango.h>
807+#include <pango/pangocairo.h>
808+#include <gdk/gdk.h>
809+#include <gtk/gtk.h>
810+
811+#include <Nux/Nux.h>
812+#include <NuxCore/Logger.h>
813+#include <NuxImage/CairoGraphics.h>
814+#include <NuxGraphics/NuxGraphics.h>
815+#include <UnityCore/GLibWrapper.h>
816+#include "DashStyle.h"
817+
818+#include "HudButton.h"
819+
820+namespace
821+{
822+nux::logging::Logger logger("unity.hud.HudButton");
823+}
824+
825+namespace unity
826+{
827+namespace hud
828+{
829+
830+
831+HudButton::HudButton (nux::TextureArea *image, NUX_FILE_LINE_DECL)
832+ : nux::Button (image, NUX_FILE_LINE_PARAM)
833+ , is_rounded(false)
834+ , is_focused_(false)
835+{
836+ InitTheme();
837+ key_nav_focus_change.connect([this](nux::Area *area, bool recieving, nux::KeyNavDirection direction){ QueueDraw(); });
838+}
839+
840+HudButton::HudButton (const std::string label_, NUX_FILE_LINE_DECL)
841+ : nux::Button (NUX_FILE_LINE_PARAM)
842+ , is_rounded(false)
843+ , is_focused_(false)
844+{
845+ InitTheme();
846+}
847+
848+HudButton::HudButton (const std::string label_, nux::TextureArea *image, NUX_FILE_LINE_DECL)
849+ : nux::Button (image, NUX_FILE_LINE_PARAM)
850+ , is_rounded(false)
851+ , is_focused_(false)
852+{
853+ InitTheme();
854+}
855+
856+HudButton::HudButton (NUX_FILE_LINE_DECL)
857+ : nux::Button (NUX_FILE_LINE_PARAM)
858+ , is_rounded(false)
859+ , is_focused_(false)
860+{
861+ InitTheme();
862+}
863+
864+HudButton::~HudButton() {
865+}
866+
867+void HudButton::InitTheme()
868+{
869+ is_rounded.changed.connect([&] (bool rounded)
870+ {
871+ nux::Geometry geo = GetGeometry();
872+ prelight_->Invalidate(geo);
873+ active_->Invalidate(geo);
874+ normal_->Invalidate(geo);
875+ });
876+
877+ SetMinimumHeight(42);
878+ if (!active_)
879+ {
880+ nux::Geometry const& geo = GetGeometry();
881+
882+ prelight_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)));
883+ active_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRESSED)));
884+ normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL)));
885+ }
886+}
887+
888+void HudButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state)
889+{
890+ dash::Style::Instance().SquareButton(cr, faked_state, label_,
891+ is_rounded, 17,
892+ dash::Alignment::LEFT, true);
893+}
894+
895+bool HudButton::AcceptKeyNavFocus()
896+{
897+ return true;
898+}
899+
900+
901+long HudButton::ComputeContentSize ()
902+{
903+ long ret = nux::Button::ComputeContentSize();
904+ nux::Geometry const& geo = GetGeometry();
905+
906+ if (cached_geometry_ != geo)
907+ {
908+ prelight_->Invalidate(geo);
909+ active_->Invalidate(geo);
910+ normal_->Invalidate(geo);
911+
912+ cached_geometry_ = geo;
913+ }
914+
915+ return ret;
916+}
917+
918+void HudButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
919+{
920+ nux::Geometry const& geo = GetGeometry();
921+ gPainter.PaintBackground(GfxContext, geo);
922+ // set up our texture mode
923+ nux::TexCoordXForm texxform;
924+ texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
925+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
926+
927+ // clear what is behind us
928+ unsigned int alpha = 0, src = 0, dest = 0;
929+ GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
930+ GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
931+ GfxContext.GetRenderStates().SetBlend(true);
932+
933+ nux::Color col = nux::color::Black;
934+ col.alpha = 0;
935+ GfxContext.QRP_Color(geo.x,
936+ geo.y,
937+ geo.width,
938+ geo.height,
939+ col);
940+
941+ nux::BaseTexture* texture = normal_->GetTexture();
942+ if (HasKeyFocus())
943+ texture = active_->GetTexture();
944+ else if (HasKeyFocus())
945+ texture = prelight_->GetTexture();
946+ else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
947+ texture = active_->GetTexture();
948+
949+ GfxContext.QRP_1Tex(geo.x,
950+ geo.y,
951+ texture->GetWidth() + 1, // FIXME !! - jay, nux has gone crazy, unless i specify +1 here, it won't render the entire texture
952+ texture->GetHeight(),
953+ texture->GetDeviceTexture(),
954+ texxform,
955+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
956+
957+ GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
958+}
959+
960+void HudButton::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) {
961+}
962+
963+void HudButton::PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw) {
964+ nux::Button::PostDraw(GfxContext, force_draw);
965+}
966+
967+void HudButton::SetQuery(Query::Ptr query)
968+{
969+ query_ = query;
970+ label_ = query->formatted_text;
971+ label = query->formatted_text;
972+}
973+
974+Query::Ptr HudButton::GetQuery()
975+{
976+ return query_;
977+}
978+
979+// Introspectable
980+std::string HudButton::GetName() const
981+{
982+ return "HudButton";
983+}
984+
985+void HudButton::AddProperties(GVariantBuilder* builder)
986+{
987+ g_variant_builder_add(builder, "{sv}", "label", g_variant_new_string(label_.c_str()));
988+}
989+
990+}
991+}
992
993=== added file 'plugins/unityshell/src/HudButton.h'
994--- plugins/unityshell/src/HudButton.h 1970-01-01 00:00:00 +0000
995+++ plugins/unityshell/src/HudButton.h 2012-02-06 11:00:29 +0000
996@@ -0,0 +1,81 @@
997+/*
998+ * Copyright 2011 Canonical Ltd.
999+ *
1000+ * This program is free software: you can redistribute it and/or modify it
1001+ * under the terms of the GNU Lesser General Public License version 3, as
1002+ * published by the Free Software Foundation.
1003+ *
1004+ * This program is distributed in the hope that it will be useful, but
1005+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1006+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1007+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1008+ * License for more details.
1009+ *
1010+ * You should have received a copy of both the GNU Lesser General Public
1011+ * License version 3 along with this program. If not, see
1012+ * <http://www.gnu.org/licenses/>
1013+ *
1014+ * Authored by: Gordon Allott <gord.allott@canonical.com>
1015+ *
1016+ */
1017+
1018+
1019+
1020+#ifndef FILTERBASICBUTTON_H
1021+#define FILTERBASICBUTTON_H
1022+
1023+#include <Nux/Nux.h>
1024+#include <Nux/CairoWrapper.h>
1025+#include <Nux/Button.h>
1026+#include <Nux/TextureArea.h>
1027+#include <UnityCore/Hud.h>
1028+#include "Introspectable.h"
1029+
1030+namespace unity {
1031+namespace hud {
1032+class HudButton : public nux::Button, public unity::debug::Introspectable
1033+{
1034+ typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
1035+public:
1036+ typedef nux::ObjectPtr<HudButton> Ptr;
1037+ HudButton (nux::TextureArea *image, NUX_FILE_LINE_PROTO);
1038+ HudButton (const std::string label, NUX_FILE_LINE_PROTO);
1039+ HudButton (const std::string label, nux::TextureArea *image, NUX_FILE_LINE_PROTO);
1040+ HudButton (NUX_FILE_LINE_PROTO);
1041+ virtual ~HudButton();
1042+
1043+ void SetQuery(Query::Ptr query);
1044+ std::shared_ptr<Query> GetQuery();
1045+
1046+ nux::Property<std::string> label;
1047+ nux::Property<std::string> hint;
1048+ nux::Property<bool> is_rounded;
1049+protected:
1050+
1051+ virtual bool AcceptKeyNavFocus();
1052+ virtual long ComputeContentSize();
1053+ virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1054+ virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
1055+ virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
1056+
1057+ std::string GetName() const;
1058+ void AddProperties(GVariantBuilder* builder);
1059+
1060+ void InitTheme ();
1061+ void RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state);
1062+ typedef std::unique_ptr<nux::CairoWrapper> NuxCairoPtr;
1063+
1064+ NuxCairoPtr prelight_;
1065+ NuxCairoPtr active_;
1066+ NuxCairoPtr normal_;
1067+
1068+private:
1069+ std::string label_;
1070+
1071+ Query::Ptr query_;
1072+ nux::Geometry cached_geometry_;
1073+ bool is_focused_;
1074+};
1075+}
1076+}
1077+#endif // FILTERBASICBUTTON_H
1078
1079=== added file 'plugins/unityshell/src/HudController.cpp'
1080--- plugins/unityshell/src/HudController.cpp 1970-01-01 00:00:00 +0000
1081+++ plugins/unityshell/src/HudController.cpp 2012-02-06 11:00:29 +0000
1082@@ -0,0 +1,385 @@
1083+/*
1084+ * Copyright (C) 2010 Canonical Ltd
1085+ *
1086+ * This program is free software: you can redistribute it and/or modify
1087+ * it under the terms of the GNU General Public License version 3 as
1088+ * published by the Free Software Foundation.
1089+ *
1090+ * This program is distributed in the hope that it will be useful,
1091+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1092+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1093+ * GNU General Public License for more details.
1094+ *
1095+ * You should have received a copy of the GNU General Public License
1096+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1097+ *
1098+ * Authored by: Gord Allott <gord.allott@canonical.com>
1099+ */
1100+
1101+#include "HudController.h"
1102+
1103+#include <NuxCore/Logger.h>
1104+#include <Nux/HLayout.h>
1105+#include "PluginAdapter.h"
1106+#include "UBusMessages.h"
1107+#include "UScreen.h"
1108+namespace unity
1109+{
1110+namespace hud
1111+{
1112+
1113+namespace
1114+{
1115+nux::logging::Logger logger("unity.hud.controller");
1116+}
1117+
1118+Controller::Controller()
1119+ : launcher_width(66)
1120+ , panel_height(24)
1121+ , hud_service_("com.canonical.hud", "/com/canonical/hud")
1122+ , window_(0)
1123+ , visible_(false)
1124+ , need_show_(false)
1125+ , timeline_id_(0)
1126+ , last_opacity_(0.0f)
1127+ , start_time_(0)
1128+{
1129+ LOG_DEBUG(logger) << "hud startup";
1130+ SetupRelayoutCallbacks();
1131+
1132+ ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
1133+
1134+ //!!FIXME!! - just hijacks the dash close request so we get some more requests than normal,
1135+ ubus.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
1136+
1137+ ubus.RegisterInterest(UBUS_OVERLAY_SHOWN, [&] (GVariant *data) {
1138+ unity::glib::String overlay_identity;
1139+ gboolean can_maximise = FALSE;
1140+ gint32 overlay_monitor = 0;
1141+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);
1142+
1143+ if (g_strcmp0(overlay_identity, "hud"))
1144+ {
1145+ HideHud(true);
1146+ }
1147+ });
1148+
1149+ PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
1150+
1151+ hud_service_.queries_updated.connect(sigc::mem_fun(this, &Controller::OnQueriesFinished));
1152+ EnsureHud();
1153+}
1154+
1155+Controller::~Controller()
1156+{
1157+ if (window_)
1158+ window_->UnReference();
1159+ window_ = 0;
1160+
1161+ g_source_remove(timeline_id_);
1162+ g_source_remove(ensure_id_);
1163+}
1164+
1165+void Controller::SetupWindow()
1166+{
1167+ window_ = new nux::BaseWindow("Hud");
1168+ window_->SinkReference();
1169+ window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
1170+ window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);
1171+ window_->ShowWindow(false);
1172+ window_->SetOpacity(0.0f);
1173+ window_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));
1174+}
1175+
1176+void Controller::SetupHudView()
1177+{
1178+ LOG_DEBUG(logger) << "SetupHudView called";
1179+ view_ = new View();
1180+
1181+ layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
1182+ layout_->AddView(view_, 1);
1183+ window_->SetLayout(layout_);
1184+
1185+ view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));
1186+
1187+ LOG_DEBUG(logger) << "connecting to signals";
1188+ view_->search_changed.connect(sigc::mem_fun(this, &Controller::OnSearchChanged));
1189+ view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated));
1190+ view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated));
1191+ view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected));
1192+}
1193+
1194+void Controller::SetupRelayoutCallbacks()
1195+{
1196+ GdkScreen* screen = gdk_screen_get_default();
1197+
1198+ sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
1199+ "monitors-changed", sigc::mem_fun(this, &Controller::Relayout)));
1200+ sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
1201+ "size-changed", sigc::mem_fun(this, &Controller::Relayout)));
1202+}
1203+
1204+void Controller::EnsureHud()
1205+{
1206+ if (window_)
1207+ return;
1208+
1209+ LOG_DEBUG(logger) << "Initializing Hud";
1210+
1211+ SetupWindow();
1212+ SetupHudView();
1213+ Relayout();
1214+ ensure_id_ = 0;
1215+}
1216+
1217+nux::BaseWindow* Controller::window() const
1218+{
1219+ return window_;
1220+}
1221+
1222+// We update the @geo that's sent in with our desired width and height
1223+void Controller::OnWindowConfigure(int window_width, int window_height,
1224+ nux::Geometry& geo, void* data)
1225+{
1226+ Controller* self = static_cast<Controller*>(data);
1227+ geo = self->GetIdealWindowGeometry();
1228+}
1229+
1230+nux::Geometry Controller::GetIdealWindowGeometry()
1231+{
1232+ UScreen *uscreen = UScreen::GetDefault();
1233+ int primary_monitor = uscreen->GetPrimaryMonitor();
1234+ auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor);
1235+
1236+ // We want to cover as much of the screen as possible to grab any mouse events outside
1237+ // of our window
1238+ return nux::Geometry (monitor_geo.x,
1239+ monitor_geo.y + panel_height,
1240+ monitor_geo.width,
1241+ monitor_geo.height - panel_height);
1242+}
1243+
1244+void Controller::Relayout(GdkScreen*screen)
1245+{
1246+ EnsureHud();
1247+ nux::Geometry content_geo = view_->GetGeometry();
1248+ nux::Geometry geo = GetIdealWindowGeometry();
1249+
1250+ window_->SetGeometry(geo);
1251+ layout_->SetMinMaxSize(content_geo.width, content_geo.height);
1252+ view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());
1253+ view_->Relayout();
1254+}
1255+
1256+void Controller::OnMouseDownOutsideWindow(int x, int y,
1257+ unsigned long bflags, unsigned long kflags)
1258+{
1259+ LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called";
1260+ HideHud();
1261+}
1262+
1263+void Controller::OnScreenUngrabbed()
1264+{
1265+ LOG_DEBUG(logger) << "OnScreenUngrabbed called";
1266+ if (need_show_)
1267+ {
1268+ EnsureHud();
1269+ ShowHud();
1270+ }
1271+}
1272+
1273+void Controller::OnExternalShowHud(GVariant* variant)
1274+{
1275+ EnsureHud();
1276+ visible_ ? HideHud() : ShowHud();
1277+}
1278+
1279+void Controller::OnExternalHideHud(GVariant* variant)
1280+{
1281+ LOG_DEBUG(logger) << "External Hiding the hud";
1282+ EnsureHud();
1283+ HideHud();
1284+}
1285+
1286+void Controller::ShowHideHud()
1287+{
1288+ EnsureHud();
1289+ visible_ ? HideHud(true) : ShowHud();
1290+}
1291+
1292+bool Controller::IsVisible()
1293+{
1294+ return visible_;
1295+}
1296+
1297+void Controller::ShowHud()
1298+{
1299+ LOG_DEBUG(logger) << "Showing the hud";
1300+ EnsureHud();
1301+ view_->AboutToShow();
1302+
1303+ window_->ShowWindow(true);
1304+ window_->PushToFront();
1305+ window_->EnableInputWindow(true, "Hud", true, false);
1306+ window_->SetInputFocus();
1307+ nux::GetWindowCompositor().SetKeyFocusArea(view_->default_focus());
1308+ window_->CaptureMouseDownAnyWhereElse(true);
1309+ view_->CaptureMouseDownAnyWhereElse(true);
1310+ window_->QueueDraw();
1311+
1312+ view_->ResetToDefault();
1313+
1314+ view_->SetIcon("");
1315+ hud_service_.RequestQuery("");
1316+ need_show_ = false;
1317+ visible_ = true;
1318+
1319+ StartShowHideTimeline();
1320+ view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());
1321+
1322+ // hide the launcher
1323+ GVariant* message_data = g_variant_new("(b)", TRUE);
1324+ ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data);
1325+
1326+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, 0);
1327+ ubus.SendMessage(UBUS_OVERLAY_SHOWN, info);
1328+}
1329+void Controller::HideHud(bool restore)
1330+{
1331+ LOG_DEBUG (logger) << "hiding the hud";
1332+ if (visible_ == false)
1333+ return;
1334+
1335+ EnsureHud();
1336+ view_->AboutToHide();
1337+ window_->CaptureMouseDownAnyWhereElse(false);
1338+ window_->EnableInputWindow(false, "Hud", true, false);
1339+ visible_ = false;
1340+
1341+ StartShowHideTimeline();
1342+
1343+ restore = true;
1344+ if (restore)
1345+ PluginAdapter::Default ()->restoreInputFocus ();
1346+
1347+ hud_service_.CloseQuery();
1348+
1349+ //unhide the launcher
1350+ GVariant* message_data = g_variant_new("(b)", FALSE);
1351+ ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data);
1352+
1353+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, 0);
1354+ ubus.SendMessage(UBUS_OVERLAY_HIDDEN, info);
1355+}
1356+
1357+void Controller::StartShowHideTimeline()
1358+{
1359+ EnsureHud();
1360+
1361+ if (timeline_id_)
1362+ g_source_remove(timeline_id_);
1363+
1364+ timeline_id_ = g_timeout_add(15, (GSourceFunc)Controller::OnViewShowHideFrame, this);
1365+ last_opacity_ = window_->GetOpacity();
1366+ start_time_ = g_get_monotonic_time();
1367+
1368+}
1369+
1370+gboolean Controller::OnViewShowHideFrame(Controller* self)
1371+{
1372+#define _LENGTH_ 90000
1373+ float diff = g_get_monotonic_time() - self->start_time_;
1374+ float progress = diff / (float)_LENGTH_;
1375+ float last_opacity = self->last_opacity_;
1376+
1377+ if (self->visible_)
1378+ {
1379+ self->window_->SetOpacity(last_opacity + ((1.0f - last_opacity) * progress));
1380+ }
1381+ else
1382+ {
1383+ self->window_->SetOpacity(last_opacity - (last_opacity * progress));
1384+ }
1385+
1386+ if (diff > _LENGTH_)
1387+ {
1388+ self->timeline_id_ = 0;
1389+
1390+ // Make sure the state is right
1391+ self->window_->SetOpacity(self->visible_ ? 1.0f : 0.0f);
1392+ if (!self->visible_)
1393+ {
1394+ self->window_->ShowWindow(false);
1395+ }
1396+
1397+ return FALSE;
1398+ }
1399+
1400+ return TRUE;
1401+}
1402+
1403+void Controller::OnActivateRequest(GVariant* variant)
1404+{
1405+ EnsureHud();
1406+ ShowHud();
1407+}
1408+
1409+void Controller::OnSearchChanged(std::string search_string)
1410+{
1411+ LOG_DEBUG(logger) << "Search Changed";
1412+ hud_service_.RequestQuery(search_string);
1413+}
1414+
1415+void Controller::OnSearchActivated(std::string search_string)
1416+{
1417+ unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
1418+ hud_service_.ExecuteQueryBySearch(search_string, timestamp);
1419+ HideHud();
1420+}
1421+
1422+void Controller::OnQueryActivated(Query::Ptr query)
1423+{
1424+ LOG_DEBUG(logger) << "Activating query, " << query->formatted_text;
1425+ unsigned int timestamp = nux::GetWindowThread()->GetGraphicsDisplay().GetCurrentEvent().x11_timestamp;
1426+ hud_service_.ExecuteQuery(query, timestamp);
1427+ HideHud();
1428+}
1429+
1430+void Controller::OnQuerySelected(Query::Ptr query)
1431+{
1432+ LOG_DEBUG(logger) << "Selected query, " << query->formatted_text;
1433+ view_->SetIcon(query->icon_name);
1434+}
1435+
1436+
1437+void Controller::OnQueriesFinished(Hud::Queries queries)
1438+{
1439+ view_->SetQueries(queries);
1440+ std::string icon_name = "";
1441+ for (auto query = queries.begin(); query != queries.end(); query++)
1442+ {
1443+ if (!(*query)->icon_name.empty())
1444+ {
1445+ icon_name = (*query)->icon_name;
1446+ break;
1447+ }
1448+ }
1449+
1450+ LOG_DEBUG(logger) << "setting icon to - " << icon_name;
1451+ view_->SetIcon(icon_name);
1452+}
1453+
1454+// Introspectable
1455+std::string Controller::GetName() const
1456+{
1457+ return "HudController";
1458+}
1459+
1460+void Controller::AddProperties(GVariantBuilder* builder)
1461+{
1462+ g_variant_builder_add(builder, "{sv}", "visible", g_variant_new_boolean (visible_));
1463+}
1464+
1465+
1466+}
1467+}
1468
1469=== added file 'plugins/unityshell/src/HudController.h'
1470--- plugins/unityshell/src/HudController.h 1970-01-01 00:00:00 +0000
1471+++ plugins/unityshell/src/HudController.h 2012-02-06 11:00:29 +0000
1472@@ -0,0 +1,113 @@
1473+/*
1474+ * Copyright (C) 2010 Canonical Ltd
1475+ *
1476+ * This program is free software: you can redistribute it and/or modify
1477+ * it under the terms of the GNU General Public License version 3 as
1478+ * published by the Free Software Foundation.
1479+ *
1480+ * This program is distributed in the hope that it will be useful,
1481+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1482+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1483+ * GNU General Public License for more details.
1484+ *
1485+ * You should have received a copy of the GNU General Public License
1486+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1487+ *
1488+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1489+ */
1490+
1491+#ifndef UNITY_HUD_CONTROLLER_H_
1492+#define UNITY_HUD_CONTROLLER_H_
1493+
1494+#include <memory>
1495+
1496+#include <gdk/gdk.h>
1497+#include <UnityCore/GLibSignal.h>
1498+#include <UnityCore/Hud.h>
1499+
1500+#include <NuxCore/Property.h>
1501+#include <NuxGraphics/GraphicsEngine.h>
1502+#include <Nux/Nux.h>
1503+#include <Nux/BaseWindow.h>
1504+
1505+#include "HudView.h"
1506+#include "UBusWrapper.h"
1507+
1508+namespace unity
1509+{
1510+namespace hud
1511+{
1512+
1513+class Controller : public unity::debug::Introspectable
1514+{
1515+public:
1516+ typedef std::shared_ptr<Controller> Ptr;
1517+
1518+ Controller();
1519+ ~Controller();
1520+
1521+ nux::BaseWindow* window() const;
1522+
1523+ nux::Property<int> launcher_width;
1524+ nux::Property<int> panel_height;
1525+
1526+ void ShowHideHud();
1527+ void ShowHud();
1528+ void HideHud(bool restore_focus = true);
1529+ bool IsVisible();
1530+protected:
1531+ std::string GetName() const;
1532+ void AddProperties(GVariantBuilder* builder);
1533+
1534+private:
1535+ void EnsureHud();
1536+ void SetupWindow();
1537+ void SetupHudView();
1538+ void SetupRelayoutCallbacks();
1539+ void RegisterUBusInterests();
1540+
1541+ nux::Geometry GetIdealWindowGeometry();
1542+ void Relayout(GdkScreen*screen=NULL);
1543+
1544+ void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
1545+ void OnScreenUngrabbed();
1546+ void OnExternalShowHud(GVariant* variant);
1547+ void OnExternalHideHud(GVariant* variant);
1548+ void OnActivateRequest(GVariant* variant);
1549+
1550+ void OnSearchChanged(std::string search_string);
1551+ void OnSearchActivated(std::string search_string);
1552+ void OnQueryActivated(Query::Ptr query);
1553+ void OnQuerySelected(Query::Ptr query);
1554+
1555+
1556+private:
1557+ void StartShowHideTimeline();
1558+ static gboolean OnViewShowHideFrame(Controller* self);
1559+
1560+ static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data);
1561+
1562+ void OnQueriesFinished(Hud::Queries queries);
1563+
1564+private:
1565+ UBusManager ubus;
1566+ Hud hud_service_;
1567+ glib::SignalManager sig_manager_;
1568+ nux::BaseWindow* window_;
1569+ bool visible_;
1570+ bool need_show_;
1571+
1572+ guint timeline_id_;
1573+ float last_opacity_;
1574+ gint64 start_time_;
1575+
1576+ View* view_;
1577+ guint ensure_id_;
1578+
1579+ nux::Layout* layout_;
1580+};
1581+
1582+
1583+}
1584+}
1585+#endif
1586
1587=== added file 'plugins/unityshell/src/HudIcon.cpp'
1588--- plugins/unityshell/src/HudIcon.cpp 1970-01-01 00:00:00 +0000
1589+++ plugins/unityshell/src/HudIcon.cpp 2012-02-06 11:00:29 +0000
1590@@ -0,0 +1,95 @@
1591+/*
1592+ * Copyright (C) 2010 Canonical Ltd
1593+ *
1594+ * This program is free software: you can redistribute it and/or modify
1595+ * it under the terms of the GNU General Public License version 3 as
1596+ * published by the Free Software Foundation.
1597+ *
1598+ * This program is distributed in the hope that it will be useful,
1599+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1600+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1601+ * GNU General Public License for more details.
1602+ *
1603+ * You should have received a copy of the GNU General Public License
1604+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1605+ *
1606+ * Authored by: Gord Allott <gord.allott@canonical.com>
1607+ */
1608+
1609+
1610+#include "HudIcon.h"
1611+#include "NuxCore/Logger.h"
1612+namespace
1613+{
1614+ nux::logging::Logger logger("unity.hud.icon");
1615+}
1616+
1617+namespace unity
1618+{
1619+namespace hud
1620+{
1621+
1622+Icon::Icon(nux::BaseTexture* texture, guint width, guint height)
1623+ : unity::IconTexture(texture, width, height)
1624+{
1625+ Init();
1626+ icon_renderer_.SetTargetSize(54, 46, 0);
1627+}
1628+
1629+Icon::Icon(const char* icon_name, unsigned int size, bool defer_icon_loading)
1630+ : unity::IconTexture(icon_name, size, defer_icon_loading)
1631+{
1632+ Init();
1633+}
1634+
1635+Icon::~Icon()
1636+{
1637+}
1638+
1639+void Icon::Init()
1640+{
1641+ SetMinimumWidth(66);
1642+ SetMinimumHeight(66);
1643+ background_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_back_54.png", -1, true);
1644+ gloss_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_shine_54.png", -1, true);
1645+ edge_ = nux::CreateTexture2DFromFile(PKGDATADIR"/launcher_icon_edge_54.png", -1, true);
1646+
1647+ texture_updated.connect([&] (nux::BaseTexture* texture)
1648+ {
1649+ icon_texture_source_ = new HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture>(texture));
1650+ icon_texture_source_->ColorForIcon(_pixbuf_cached);
1651+ QueueDraw();
1652+ LOG_DEBUG(logger) << "got our texture";
1653+ });
1654+}
1655+
1656+void Icon::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1657+{
1658+ if (texture() == nullptr)
1659+ return;
1660+
1661+ unity::ui::RenderArg arg;
1662+ arg.icon = icon_texture_source_.GetPointer();
1663+ arg.colorify = nux::color::White;
1664+ arg.running_arrow = true;
1665+ arg.running_on_viewport = true;
1666+ arg.render_center = nux::Point3(32, 32, 0);
1667+ arg.logical_center = nux::Point3(52, 50, 0);
1668+ arg.window_indicators = true;
1669+ arg.backlight_intensity = 1.0f;
1670+ arg.alpha = 1.0f;
1671+
1672+ std::list<unity::ui::RenderArg> args;
1673+ args.push_front(arg);
1674+
1675+
1676+ auto toplevel = GetToplevel();
1677+ icon_renderer_.SetTargetSize(54, 46, 0);
1678+ icon_renderer_.PreprocessIcons(args, toplevel->GetGeometry());
1679+ icon_renderer_.RenderIcon(GfxContext, arg, toplevel->GetGeometry(), toplevel->GetGeometry());
1680+}
1681+
1682+
1683+}
1684+}
1685+
1686
1687=== added file 'plugins/unityshell/src/HudIcon.h'
1688--- plugins/unityshell/src/HudIcon.h 1970-01-01 00:00:00 +0000
1689+++ plugins/unityshell/src/HudIcon.h 2012-02-06 11:00:29 +0000
1690@@ -0,0 +1,73 @@
1691+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1692+/*
1693+ * Copyright (C) 2010 Canonical Ltd
1694+ *
1695+ * This program is free software: you can redistribute it and/or modify
1696+ * it under the terms of the GNU General Public License version 3 as
1697+ * published by the Free Software Foundation.
1698+ *
1699+ * This program is distributed in the hope that it will be useful,
1700+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1701+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1702+ * GNU General Public License for more details.
1703+ *
1704+ * You should have received a copy of the GNU General Public License
1705+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1706+ *
1707+ * Authored by: Gord Allott <gord.allott@canonical.com>
1708+ *
1709+ */
1710+
1711+#ifndef HUDICON_H
1712+#define HUDICON_H
1713+
1714+#include <set>
1715+#include <string>
1716+
1717+#include "config.h"
1718+
1719+#include <Nux/Nux.h>
1720+#include <Nux/BaseWindow.h>
1721+#include <NuxCore/Math/MathInc.h>
1722+
1723+#include <sigc++/trackable.h>
1724+#include <sigc++/signal.h>
1725+#include <sigc++/functors/ptr_fun.h>
1726+#include <sigc++/functors/mem_fun.h>
1727+
1728+#include <gtk/gtk.h>
1729+
1730+#include "IconTexture.h"
1731+#include "HudIconTextureSource.h"
1732+#include "IconRenderer.h"
1733+#include "Introspectable.h"
1734+
1735+namespace unity
1736+{
1737+namespace hud
1738+{
1739+
1740+class Icon : public unity::IconTexture
1741+{
1742+public:
1743+ typedef nux::ObjectPtr<IconTexture> Ptr;
1744+ Icon(nux::BaseTexture* texture, guint width, guint height);
1745+ Icon(const char* icon_name, unsigned int size, bool defer_icon_loading = false);
1746+ ~Icon();
1747+
1748+protected:
1749+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1750+ void Init();
1751+
1752+ nux::ObjectPtr<nux::BaseTexture> background_;
1753+ nux::ObjectPtr<nux::BaseTexture> gloss_;
1754+ nux::ObjectPtr<nux::BaseTexture> edge_;
1755+ nux::ObjectPtr<HudIconTextureSource> icon_texture_source_;
1756+ unity::ui::IconRenderer icon_renderer_;
1757+};
1758+
1759+}
1760+
1761+}
1762+
1763+#endif /* HUDICON_H */
1764
1765=== added file 'plugins/unityshell/src/HudIconTextureSource.cpp'
1766--- plugins/unityshell/src/HudIconTextureSource.cpp 1970-01-01 00:00:00 +0000
1767+++ plugins/unityshell/src/HudIconTextureSource.cpp 2012-02-06 11:00:29 +0000
1768@@ -0,0 +1,110 @@
1769+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1770+/*
1771+ * Copyright (C) 2011 Canonical Ltd
1772+ *
1773+ * This program is free software: you can redistribute it and/or modify
1774+ * it under the terms of the GNU General Public License version 3 as
1775+ * published by the Free Software Foundation.
1776+ *
1777+ * This program is distributed in the hope that it will be useful,
1778+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1779+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1780+ * GNU General Public License for more details.
1781+ *
1782+ * You should have received a copy of the GNU General Public License
1783+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1784+ *
1785+ * Authored by: Gordon Allott <gord.allott@canonical.com>
1786+ */
1787+
1788+
1789+#include "HudIconTextureSource.h"
1790+#include "config.h"
1791+
1792+#include <glib.h>
1793+
1794+#include <Nux/Nux.h>
1795+#include <NuxCore/Logger.h>
1796+
1797+
1798+namespace unity
1799+{
1800+namespace hud
1801+{
1802+
1803+HudIconTextureSource::HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture> texture)
1804+ : unity::ui::IconTextureSource()
1805+ , icon_texture_(texture)
1806+{
1807+}
1808+
1809+HudIconTextureSource::~HudIconTextureSource()
1810+{
1811+}
1812+
1813+void HudIconTextureSource::ColorForIcon(GdkPixbuf* pixbuf)
1814+{
1815+ unsigned int width = gdk_pixbuf_get_width(pixbuf);
1816+ unsigned int height = gdk_pixbuf_get_height(pixbuf);
1817+ unsigned int row_bytes = gdk_pixbuf_get_rowstride(pixbuf);
1818+
1819+ long int rtotal = 0, gtotal = 0, btotal = 0;
1820+ float total = 0.0f;
1821+
1822+ guchar* img = gdk_pixbuf_get_pixels(pixbuf);
1823+
1824+ for (unsigned int i = 0; i < width; i++)
1825+ {
1826+ for (unsigned int j = 0; j < height; j++)
1827+ {
1828+ guchar* pixels = img + (j * row_bytes + i * 4);
1829+ guchar r = *(pixels + 0);
1830+ guchar g = *(pixels + 1);
1831+ guchar b = *(pixels + 2);
1832+ guchar a = *(pixels + 3);
1833+
1834+ float saturation = (MAX(r, MAX(g, b)) - MIN(r, MIN(g, b))) / 255.0f;
1835+ float relevance = .1 + .9 * (a / 255.0f) * saturation;
1836+
1837+ rtotal += (guchar)(r * relevance);
1838+ gtotal += (guchar)(g * relevance);
1839+ btotal += (guchar)(b * relevance);
1840+
1841+ total += relevance * 255;
1842+ }
1843+ }
1844+
1845+ nux::color::RedGreenBlue rgb(rtotal / total,
1846+ gtotal / total,
1847+ btotal / total);
1848+ nux::color::HueSaturationValue hsv(rgb);
1849+
1850+ if (hsv.saturation > 0.15f)
1851+ hsv.saturation = 0.65f;
1852+
1853+ hsv.value = 0.90f;
1854+ bg_color = nux::Color(nux::color::RedGreenBlue(hsv));
1855+}
1856+
1857+nux::Color HudIconTextureSource::BackgroundColor()
1858+{
1859+ return bg_color;
1860+}
1861+
1862+nux::BaseTexture* HudIconTextureSource::TextureForSize(int size)
1863+{
1864+ return icon_texture_.GetPointer();
1865+}
1866+
1867+nux::Color HudIconTextureSource::GlowColor()
1868+{
1869+ return nux::Color(0.0f, 0.0f, 0.0f, 0.0f);
1870+}
1871+
1872+nux::BaseTexture* HudIconTextureSource::Emblem()
1873+{
1874+ return nullptr;
1875+}
1876+
1877+}
1878+}
1879\ No newline at end of file
1880
1881=== added file 'plugins/unityshell/src/HudIconTextureSource.h'
1882--- plugins/unityshell/src/HudIconTextureSource.h 1970-01-01 00:00:00 +0000
1883+++ plugins/unityshell/src/HudIconTextureSource.h 2012-02-06 11:00:29 +0000
1884@@ -0,0 +1,51 @@
1885+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1886+/*
1887+ * Copyright (C) 2011 Canonical Ltd
1888+ *
1889+ * This program is free software: you can redistribute it and/or modify
1890+ * it under the terms of the GNU General Public License version 3 as
1891+ * published by the Free Software Foundation.
1892+ *
1893+ * This program is distributed in the hope that it will be useful,
1894+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1895+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1896+ * GNU General Public License for more details.
1897+ *
1898+ * You should have received a copy of the GNU General Public License
1899+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1900+ *
1901+ * Authored by: Gordon Allott <gord.allott@canonical.com>
1902+ */
1903+
1904+
1905+#ifndef HUDICONTEXTURESOURCE_H
1906+#define HUDICONTEXTURESOURCE_H
1907+
1908+#include "IconTextureSource.h"
1909+
1910+namespace unity
1911+{
1912+namespace hud
1913+{
1914+
1915+class HudIconTextureSource : public unity::ui::IconTextureSource
1916+{
1917+public:
1918+ HudIconTextureSource(nux::ObjectPtr<nux::BaseTexture> texture);
1919+ ~HudIconTextureSource();
1920+
1921+ virtual nux::Color BackgroundColor();
1922+ virtual nux::BaseTexture* TextureForSize(int size);
1923+ virtual nux::Color GlowColor();
1924+ virtual nux::BaseTexture* Emblem();
1925+ void ColorForIcon(GdkPixbuf* pixbuf);
1926+
1927+private:
1928+ nux::Color bg_color;
1929+ nux::ObjectPtr<nux::BaseTexture> icon_texture_;
1930+};
1931+
1932+}
1933+}
1934+
1935+#endif // HUDICONTEXTURESOURCE_H
1936
1937=== added file 'plugins/unityshell/src/HudView.cpp'
1938--- plugins/unityshell/src/HudView.cpp 1970-01-01 00:00:00 +0000
1939+++ plugins/unityshell/src/HudView.cpp 2012-02-06 11:00:29 +0000
1940@@ -0,0 +1,398 @@
1941+/*
1942+ * Copyright (C) 2010 Canonical Ltd
1943+ *
1944+ * This program is free software: you can redistribute it and/or modify
1945+ * it under the terms of the GNU General Public License version 3 as
1946+ * published by the Free Software Foundation.
1947+ *
1948+ * This program is distributed in the hope that it will be useful,
1949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1951+ * GNU General Public License for more details.
1952+ *
1953+ * You should have received a copy of the GNU General Public License
1954+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1955+ *
1956+ * Authored by: Gord Allott <gord.allott@canonical.com>
1957+ */
1958+
1959+#include "HudView.h"
1960+
1961+#include <math.h>
1962+
1963+#include <gio/gdesktopappinfo.h>
1964+#include <glib/gi18n-lib.h>
1965+#include <gtk/gtk.h>
1966+#include <Nux/Button.h>
1967+#include <iostream>
1968+#include <sstream>
1969+
1970+#include <NuxCore/Logger.h>
1971+#include <UnityCore/GLibWrapper.h>
1972+#include <UnityCore/RadioOptionFilter.h>
1973+#include <Nux/HLayout.h>
1974+#include <Nux/LayeredLayout.h>
1975+
1976+#include <NuxCore/Logger.h>
1977+#include "HudButton.h"
1978+#include "UBusMessages.h"
1979+#include "DashStyle.h"
1980+
1981+namespace unity
1982+{
1983+namespace hud
1984+{
1985+
1986+namespace
1987+{
1988+nux::logging::Logger logger("unity.hud.view");
1989+int icon_size = 42;
1990+const std::string default_text = _("Type your command");
1991+}
1992+
1993+NUX_IMPLEMENT_OBJECT_TYPE(View);
1994+
1995+View::View()
1996+ : nux::View(NUX_TRACKER_LOCATION)
1997+ , button_views_(NULL)
1998+{
1999+ renderer_.SetOwner(this);
2000+ renderer_.need_redraw.connect([this] () {
2001+ QueueDraw();
2002+ });
2003+
2004+ nux::ROPConfig rop;
2005+ rop.Blend = true;
2006+ rop.SrcBlend = GL_ONE;
2007+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
2008+
2009+ SetupViews();
2010+ search_bar_->key_down.connect (sigc::mem_fun (this, &View::OnKeyDown));
2011+
2012+ search_bar_->activated.connect ([&]() {
2013+ search_activated.emit(search_bar_->search_string);
2014+ });
2015+
2016+ mouse_down.connect(sigc::mem_fun(this, &View::OnMouseButtonDown));
2017+
2018+ Relayout();
2019+
2020+}
2021+
2022+View::~View()
2023+{
2024+ RemoveChild(search_bar_.GetPointer());
2025+ for (auto button = buttons_.begin(); button != buttons_.end(); button++)
2026+ {
2027+ RemoveChild((*button).GetPointer());
2028+ }
2029+}
2030+
2031+void View::ResetToDefault()
2032+{
2033+ search_bar_->search_string = "";
2034+ search_bar_->search_hint = default_text;
2035+}
2036+
2037+void View::Relayout()
2038+{
2039+ nux::Geometry geo = GetGeometry();
2040+ content_geo_ = GetBestFitGeometry(geo);
2041+ LOG_DEBUG(logger) << "content_geo: " << content_geo_.width << "x" << content_geo_.height;
2042+
2043+ layout_->SetMinMaxSize(content_geo_.width, content_geo_.height);
2044+
2045+ QueueDraw();
2046+}
2047+
2048+long View::PostLayoutManagement(long LayoutResult)
2049+{
2050+ Relayout();
2051+ return LayoutResult;
2052+}
2053+
2054+
2055+nux::View* View::default_focus() const
2056+{
2057+ return search_bar_->text_entry();
2058+}
2059+
2060+void View::SetQueries(Hud::Queries queries)
2061+{
2062+ // remove the previous children
2063+ for (auto button = buttons_.begin(); button != buttons_.end(); button++)
2064+ {
2065+ RemoveChild((*button).GetPointer());
2066+ }
2067+
2068+ queries_ = queries_;
2069+ buttons_.clear();
2070+ button_views_->Clear();
2071+ int found_items = 0;
2072+ for (auto query = queries.begin(); query != queries.end(); query++)
2073+ {
2074+ if (found_items > 5)
2075+ break;
2076+
2077+ HudButton::Ptr button = HudButton::Ptr(new HudButton());
2078+ buttons_.push_front(button);
2079+ button->SetQuery(*query);
2080+ button_views_->AddView(button.GetPointer(), 0, nux::MINOR_POSITION_LEFT);
2081+
2082+ button->click.connect([&](nux::View* view) {
2083+ query_activated.emit(dynamic_cast<HudButton*>(view)->GetQuery());
2084+ });
2085+
2086+ button->key_nav_focus_activate.connect([&](nux::Area *area) {
2087+ query_activated.emit(dynamic_cast<HudButton*>(area)->GetQuery());
2088+ });
2089+
2090+ button->key_nav_focus_change.connect([&](nux::Area *area, bool recieving, KeyNavDirection direction){
2091+ if (recieving)
2092+ query_selected.emit(dynamic_cast<HudButton*>(area)->GetQuery());
2093+ });
2094+
2095+ button->is_rounded = (query == --(queries.end())) ? true : false;
2096+ button->SetMinimumWidth(941);
2097+ found_items++;
2098+ }
2099+
2100+ QueueRelayout();
2101+ QueueDraw();
2102+}
2103+
2104+void View::SetIcon(std::string icon_name)
2105+{
2106+ LOG_DEBUG(logger) << "Setting icon to " << icon_name;
2107+ icon_->SetByIconName(icon_name.c_str(), icon_size);
2108+ QueueDraw();
2109+}
2110+
2111+// Gives us the width and height of the contents that will give us the best "fit",
2112+// which means that the icons/views will not have uneccessary padding, everything will
2113+// look tight
2114+nux::Geometry View::GetBestFitGeometry(nux::Geometry const& for_geo)
2115+{
2116+ //FIXME - remove magic values, replace with scalable text depending on DPI
2117+ // requires smarter font settings really...
2118+ int width, height = 0;
2119+ width = 1024;
2120+ height = 276;
2121+
2122+ LOG_DEBUG (logger) << "best fit is, " << width << ", " << height;
2123+
2124+ return nux::Geometry(0, 0, width, height);
2125+}
2126+
2127+void View::AboutToShow()
2128+{
2129+ renderer_.AboutToShow();
2130+}
2131+
2132+void View::AboutToHide()
2133+{
2134+ renderer_.AboutToHide();
2135+}
2136+
2137+void View::SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo)
2138+{
2139+ window_geometry_ = geo;
2140+ window_geometry_.x = 0;
2141+ window_geometry_.y = 0;
2142+ absolute_window_geometry_ = absolute_geo;
2143+}
2144+
2145+namespace
2146+{
2147+ const int top_spacing = 9;
2148+ const int content_width = 941;
2149+ const int icon_vertical_margin = 5;
2150+ const int spacing_between_icon_and_content = 8;
2151+}
2152+
2153+void View::SetupViews()
2154+{
2155+ layout_ = new nux::HLayout();
2156+
2157+ icon_ = new Icon("", icon_size, true);
2158+ nux::Layout* icon_layout = new nux::VLayout();
2159+ icon_layout->SetVerticalExternalMargin(icon_vertical_margin);
2160+ icon_layout->AddView(icon_.GetPointer(), 0, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL);
2161+ layout_->AddLayout(icon_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT);
2162+ layout_->AddLayout(new nux::SpaceLayout(spacing_between_icon_and_content,
2163+ spacing_between_icon_and_content,
2164+ spacing_between_icon_and_content,
2165+ spacing_between_icon_and_content), 0);
2166+
2167+
2168+ content_layout_ = new nux::VLayout();
2169+ layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP);
2170+ SetLayout(layout_.GetPointer());
2171+
2172+ // add the top spacing
2173+ content_layout_->AddLayout(new nux::SpaceLayout(top_spacing,top_spacing,top_spacing,top_spacing), 0);
2174+
2175+ // add the search bar to the composite
2176+ search_bar_ = new unity::SearchBar(content_width, true);
2177+ search_bar_->disable_glow = true;
2178+ search_bar_->search_hint = default_text;
2179+ search_bar_->search_changed.connect(sigc::mem_fun(this, &View::OnSearchChanged));
2180+ AddChild(search_bar_.GetPointer());
2181+ content_layout_->AddView(search_bar_.GetPointer(), 0, nux::MINOR_POSITION_LEFT);
2182+
2183+ button_views_ = new nux::VLayout();
2184+ button_views_->SetMaximumWidth(content_width);
2185+
2186+ content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT);
2187+}
2188+
2189+void View::OnSearchChanged(std::string const& search_string)
2190+{
2191+ LOG_DEBUG(logger) << "got search change";
2192+ search_changed.emit(search_string);
2193+ if (search_string.empty())
2194+ {
2195+ search_bar_->search_hint = default_text;
2196+ }
2197+ else
2198+ {
2199+ search_bar_->search_hint = "";
2200+ }
2201+}
2202+
2203+
2204+void View::OnKeyDown (unsigned long event_type, unsigned long keysym,
2205+ unsigned long event_state, const TCHAR* character,
2206+ unsigned short key_repeat_count)
2207+{
2208+ if (keysym == NUX_VK_ESCAPE)
2209+ {
2210+ LOG_DEBUG(logger) << "got escape key";
2211+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2212+ }
2213+}
2214+
2215+void View::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
2216+{
2217+ if (!content_geo_.IsPointInside(x, y))
2218+ {
2219+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2220+ }
2221+}
2222+
2223+void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
2224+{
2225+ renderer_.DrawFull(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_, true);
2226+}
2227+
2228+void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
2229+{
2230+ renderer_.DrawInner(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_);
2231+
2232+ if (IsFullRedraw())
2233+ {
2234+ nux::GetPainter().PushBackgroundStack();
2235+ layout_->ProcessDraw(gfx_context, force_draw);
2236+ nux::GetPainter().PopBackgroundStack();
2237+ }
2238+ else
2239+ {
2240+ layout_->ProcessDraw(gfx_context, force_draw);
2241+ }
2242+
2243+ renderer_.DrawInnerCleanup(gfx_context, layout_->GetGeometry(), absolute_window_geometry_, window_geometry_);
2244+}
2245+
2246+// Keyboard navigation
2247+bool View::AcceptKeyNavFocus()
2248+{
2249+ return false;
2250+}
2251+
2252+// Introspectable
2253+std::string View::GetName() const
2254+{
2255+ return "HudView";
2256+}
2257+
2258+void View::AddProperties(GVariantBuilder* builder)
2259+{
2260+
2261+}
2262+
2263+bool View::InspectKeyEvent(unsigned int eventType,
2264+ unsigned int key_sym,
2265+ const char* character)
2266+{
2267+ if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ESCAPE))
2268+ {
2269+ if (search_bar_->search_string == "")
2270+ {
2271+ ubus.SendMessage(UBUS_HUD_CLOSE_REQUEST);
2272+ }
2273+ else
2274+ {
2275+ search_bar_->search_string = "";
2276+ search_bar_->search_hint = default_text;
2277+ }
2278+ return true;
2279+ }
2280+ return false;
2281+}
2282+
2283+nux::Area* View::FindKeyFocusArea(unsigned int key_symbol,
2284+ unsigned long x11_key_code,
2285+ unsigned long special_keys_state)
2286+{
2287+ // Do what nux::View does, but if the event isn't a key navigation,
2288+ // designate the text entry to process it.
2289+
2290+ nux::KeyNavDirection direction = nux::KEY_NAV_NONE;
2291+ switch (x11_key_code)
2292+ {
2293+ case NUX_VK_UP:
2294+ direction = nux::KEY_NAV_UP;
2295+ break;
2296+ case NUX_VK_DOWN:
2297+ direction = nux::KEY_NAV_DOWN;
2298+ break;
2299+ case NUX_VK_LEFT:
2300+ direction = nux::KEY_NAV_LEFT;
2301+ break;
2302+ case NUX_VK_RIGHT:
2303+ direction = nux::KEY_NAV_RIGHT;
2304+ break;
2305+ case NUX_VK_LEFT_TAB:
2306+ direction = nux::KEY_NAV_TAB_PREVIOUS;
2307+ break;
2308+ case NUX_VK_TAB:
2309+ direction = nux::KEY_NAV_TAB_NEXT;
2310+ break;
2311+ case NUX_VK_ENTER:
2312+ case NUX_KP_ENTER:
2313+ // Not sure if Enter should be a navigation key
2314+ direction = nux::KEY_NAV_ENTER;
2315+ break;
2316+ default:
2317+ direction = nux::KEY_NAV_NONE;
2318+ break;
2319+ }
2320+
2321+ if (has_key_focus_)
2322+ {
2323+ return this;
2324+ }
2325+ else if (direction == nux::KEY_NAV_NONE)
2326+ {
2327+ // then send the event to the search entry
2328+ return search_bar_->text_entry();
2329+ }
2330+ else if (next_object_to_key_focus_area_)
2331+ {
2332+ return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
2333+ }
2334+ return NULL;
2335+}
2336+
2337+}
2338+}
2339
2340=== added file 'plugins/unityshell/src/HudView.h'
2341--- plugins/unityshell/src/HudView.h 1970-01-01 00:00:00 +0000
2342+++ plugins/unityshell/src/HudView.h 2012-02-06 11:00:29 +0000
2343@@ -0,0 +1,118 @@
2344+/*
2345+ * Copyright (C) 2010 Canonical Ltd
2346+ *
2347+ * This program is free software: you can redistribute it and/or modify
2348+ * it under the terms of the GNU General Public License version 3 as
2349+ * published by the Free Software Foundation.
2350+ *
2351+ * This program is distributed in the hope that it will be useful,
2352+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2353+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2354+ * GNU General Public License for more details.
2355+ *
2356+ * You should have received a copy of the GNU General Public License
2357+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2358+ *
2359+ * Authored by: Gordon Allott <gord.allott@canonical.com>
2360+ */
2361+
2362+#ifndef UNITY_HUD_VIEW_H_
2363+#define UNITY_HUD_VIEW_H_
2364+
2365+#include <string>
2366+
2367+#include <NuxGraphics/GraphicsEngine.h>
2368+#include <Nux/Nux.h>
2369+#include <Nux/PaintLayer.h>
2370+#include <Nux/View.h>
2371+#include <Nux/VLayout.h>
2372+#include <StaticCairoText.h>
2373+
2374+#include <glib.h>
2375+
2376+#include <UnityCore/Hud.h>
2377+#include "Introspectable.h"
2378+
2379+#include "UBusWrapper.h"
2380+#include "HudIcon.h"
2381+#include "HudButton.h"
2382+#include "SearchBar.h"
2383+#include "OverlayRenderer.h"
2384+
2385+namespace unity
2386+{
2387+namespace hud
2388+{
2389+
2390+class View : public nux::View, public unity::debug::Introspectable
2391+{
2392+ NUX_DECLARE_OBJECT_TYPE(HudView, nux::View);
2393+ typedef nux::ObjectPtr<View> Ptr;
2394+public:
2395+ View();
2396+ ~View();
2397+
2398+ void ResetToDefault();
2399+
2400+ void Relayout();
2401+ nux::View* default_focus() const;
2402+
2403+ void SetQueries(Hud::Queries queries);
2404+ void SetIcon(std::string icon_name);
2405+
2406+ void AboutToShow();
2407+ void AboutToHide();
2408+
2409+ void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo);
2410+
2411+ sigc::signal<void, std::string> search_changed;
2412+ sigc::signal<void, std::string> search_activated;
2413+ sigc::signal<void, Query::Ptr> query_activated;
2414+ sigc::signal<void, Query::Ptr> query_selected;
2415+
2416+protected:
2417+ virtual Area* FindKeyFocusArea(unsigned int key_symbol,
2418+ unsigned long x11_key_code,
2419+ unsigned long special_keys_state);
2420+
2421+ void SetupViews();
2422+ void OnSearchChanged(std::string const& search_string);
2423+ virtual long PostLayoutManagement(long LayoutResult);
2424+private:
2425+ void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key);
2426+ void OnKeyDown (unsigned long event_type, unsigned long event_keysym,
2427+ unsigned long event_state, const TCHAR* character,
2428+ unsigned short key_repeat_count);
2429+ void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);
2430+ void DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw);
2431+ bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
2432+ bool AcceptKeyNavFocus();
2433+ nux::Geometry GetBestFitGeometry(nux::Geometry const& for_geo);
2434+
2435+ std::string GetName() const;
2436+ void AddProperties(GVariantBuilder* builder);
2437+
2438+private:
2439+ UBusManager ubus;
2440+ nux::ObjectPtr<nux::Layout> layout_;
2441+ nux::ObjectPtr<nux::Layout> content_layout_;
2442+ nux::ObjectPtr<nux::VLayout> button_views_;
2443+ std::list<HudButton::Ptr> buttons_;
2444+
2445+ //FIXME - replace with dash search bar once modifications to dash search bar land
2446+ SearchBar::Ptr search_bar_;
2447+ Icon::Ptr icon_;
2448+ bool visible_;
2449+
2450+ Hud::Queries queries_;
2451+ nux::Geometry content_geo_;
2452+ OverlayRenderer renderer_;
2453+ nux::Geometry window_geometry_;
2454+ nux::Geometry absolute_window_geometry_;
2455+};
2456+
2457+
2458+}
2459+}
2460+#endif
2461+
2462
2463=== modified file 'plugins/unityshell/src/IMTextEntry.cpp'
2464--- plugins/unityshell/src/IMTextEntry.cpp 2012-01-26 12:59:18 +0000
2465+++ plugins/unityshell/src/IMTextEntry.cpp 2012-02-06 11:00:29 +0000
2466@@ -27,12 +27,10 @@
2467
2468 namespace unity
2469 {
2470-namespace dash
2471-{
2472
2473 namespace
2474 {
2475-nux::logging::Logger logger("unity.dash.imtextentry");
2476+nux::logging::Logger logger("unity.imtextentry");
2477 }
2478
2479 NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry);
2480@@ -338,4 +336,3 @@
2481 }
2482
2483 }
2484-}
2485
2486=== modified file 'plugins/unityshell/src/IMTextEntry.h'
2487--- plugins/unityshell/src/IMTextEntry.h 2012-01-03 00:51:51 +0000
2488+++ plugins/unityshell/src/IMTextEntry.h 2012-02-06 11:00:29 +0000
2489@@ -30,8 +30,6 @@
2490
2491 namespace unity
2492 {
2493-namespace dash
2494-{
2495
2496 using namespace unity::glib;
2497 using namespace nux;
2498@@ -80,6 +78,5 @@
2499 };
2500
2501 }
2502-}
2503
2504 #endif
2505
2506=== modified file 'plugins/unityshell/src/IconTexture.cpp'
2507--- plugins/unityshell/src/IconTexture.cpp 2011-11-08 18:21:44 +0000
2508+++ plugins/unityshell/src/IconTexture.cpp 2012-02-06 11:00:29 +0000
2509@@ -24,6 +24,7 @@
2510 #include <pango/pangocairo.h>
2511
2512 #include <Nux/Nux.h>
2513+#include <NuxCore/Logger.h>
2514 #include <NuxGraphics/GLThread.h>
2515 #include <UnityCore/GLibWrapper.h>
2516 #include <UnityCore/Variant.h>
2517@@ -37,6 +38,7 @@
2518 namespace
2519 {
2520 const char* const DEFAULT_ICON = "text-x-preview";
2521+nux::logging::Logger logger("unity.icontexture");
2522 }
2523
2524 using namespace unity;
2525@@ -67,7 +69,7 @@
2526 {
2527 _icon_name = g_strdup(icon_name ? icon_name : DEFAULT_ICON);
2528
2529- if (!g_strcmp0(_icon_name, "") == 0 && !defer_icon_loading)
2530+ if (g_strcmp0(_icon_name, "") != 0 && !defer_icon_loading)
2531 LoadIcon();
2532 }
2533
2534@@ -95,8 +97,11 @@
2535
2536 void IconTexture::LoadIcon()
2537 {
2538- static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview";
2539-
2540+ LOG_DEBUG(logger) << "LoadIcon called (" << _icon_name << ") - loading: " << _loading;
2541+static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview";
2542+ if (!g_strcmp0(_icon_name, ""))
2543+ return;
2544+
2545 if (_loading)
2546 return;
2547 _loading = true;
2548@@ -144,6 +149,7 @@
2549 _texture_height,
2550 sigc::mem_fun(this, &IconTexture::CreateTextureCallback));
2551 QueueDraw();
2552+ _loading = false;
2553 }
2554
2555 void IconTexture::IconLoaded(std::string const& icon_name, unsigned size,
2556@@ -162,6 +168,9 @@
2557 if (icon_name != DEFAULT_ICON)
2558 SetByIconName(DEFAULT_ICON, _size);
2559 }
2560+
2561+ texture_updated.emit(_texture_cached.GetPointer());
2562+ QueueDraw();
2563 }
2564
2565 void IconTexture::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
2566
2567=== modified file 'plugins/unityshell/src/IconTexture.h'
2568--- plugins/unityshell/src/IconTexture.h 2011-12-08 01:23:11 +0000
2569+++ plugins/unityshell/src/IconTexture.h 2012-02-06 11:00:29 +0000
2570@@ -53,6 +53,8 @@
2571
2572 nux::BaseTexture* texture();
2573
2574+ sigc::signal<void, nux::BaseTexture*> texture_updated;
2575+
2576 protected:
2577 // Key navigation
2578 virtual bool AcceptKeyNavFocus();
2579@@ -61,7 +63,8 @@
2580 std::string GetName() const;
2581 void AddProperties(GVariantBuilder* builder);
2582 virtual bool DoCanFocus();
2583-
2584+ GdkPixbuf* _pixbuf_cached;
2585+
2586 protected:
2587 void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
2588
2589@@ -74,7 +77,7 @@
2590 char* _icon_name;
2591 unsigned int _size;
2592
2593- GdkPixbuf* _pixbuf_cached;
2594+
2595 nux::ObjectPtr<nux::BaseTexture> _texture_cached;
2596 // FIXME: make these two a nux::Size.
2597 int _texture_width;
2598
2599=== modified file 'plugins/unityshell/src/OverlayRenderer.cpp'
2600--- plugins/unityshell/src/OverlayRenderer.cpp 2012-02-03 21:56:04 +0000
2601+++ plugins/unityshell/src/OverlayRenderer.cpp 2012-02-06 11:00:29 +0000
2602@@ -50,7 +50,7 @@
2603 void Init();
2604 void OnBackgroundColorChanged(GVariant* args);
2605
2606- void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
2607+ void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_draw);
2608 void DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
2609 void DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
2610
2611@@ -118,12 +118,12 @@
2612 parent->need_redraw.emit();
2613 }
2614
2615-void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry)
2616+void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_edges)
2617 {
2618 bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE;
2619 nux::Geometry geo = content_geo;
2620
2621- if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK)
2622+ if (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges)
2623 {
2624 // Paint the edges
2625 {
2626@@ -475,9 +475,9 @@
2627 pimpl_->bg_effect_helper_.blur_type = BLUR_NONE;
2628 }
2629
2630-void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo)
2631+void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges)
2632 {
2633- pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo);
2634+ pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo, force_edges);
2635 }
2636
2637 void OverlayRenderer::DrawInner(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo)
2638
2639=== modified file 'plugins/unityshell/src/OverlayRenderer.h'
2640--- plugins/unityshell/src/OverlayRenderer.h 2012-01-27 06:58:20 +0000
2641+++ plugins/unityshell/src/OverlayRenderer.h 2012-02-06 11:00:29 +0000
2642@@ -70,7 +70,7 @@
2643 * absolute_geo: your views GetAbsoluteGeometry()
2644 * geo: your views GetGeometry()
2645 */
2646- void DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo);
2647+ void DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges=false);
2648
2649 /*
2650 * Draws just the stack that is overlay behind the inner_geometry using push/pop layers, call in DrawContent() before drawing your content
2651
2652=== renamed file 'plugins/unityshell/src/DashSearchBar.cpp' => 'plugins/unityshell/src/SearchBar.cpp'
2653--- plugins/unityshell/src/DashSearchBar.cpp 2012-01-26 22:17:41 +0000
2654+++ plugins/unityshell/src/SearchBar.cpp 2012-02-06 11:00:29 +0000
2655@@ -25,6 +25,7 @@
2656 #include <Nux/VLayout.h>
2657 #include <Nux/Layout.h>
2658 #include <Nux/WindowCompositor.h>
2659+#include <NuxCore/Logger.h>
2660
2661 #include <NuxImage/CairoGraphics.h>
2662 #include <NuxImage/ImageSurface.h>
2663@@ -36,7 +37,7 @@
2664 #include <glib.h>
2665 #include <glib/gi18n-lib.h>
2666
2667-#include "DashSearchBar.h"
2668+#include "SearchBar.h"
2669 #include <UnityCore/Variant.h>
2670
2671 #include "CairoTexture.h"
2672@@ -48,12 +49,17 @@
2673 namespace
2674 {
2675 const float kExpandDefaultIconOpacity = 1.0f;
2676+const int external_margin_vertical = 8;
2677+const int external_margin_horizontal = 7;
2678+}
2679+
2680+namespace
2681+{
2682+ nux::logging::Logger logger("unity");
2683 }
2684
2685 namespace unity
2686 {
2687-namespace dash
2688-{
2689
2690 NUX_IMPLEMENT_OBJECT_TYPE(SearchBar);
2691
2692@@ -62,18 +68,53 @@
2693 , search_hint("")
2694 , showing_filters(false)
2695 , can_refine_search(false)
2696+ , disable_glow(false)
2697+ , show_filter_hint_(true)
2698 , search_bar_width_(642)
2699 , live_search_timeout_(0)
2700 , start_spinner_timeout_(0)
2701 {
2702+ Init();
2703+}
2704+
2705+SearchBar::SearchBar(int search_bar_width, bool show_filter_hint_, NUX_FILE_LINE_DECL)
2706+ : View(NUX_FILE_LINE_PARAM)
2707+ , search_hint("")
2708+ , showing_filters(false)
2709+ , can_refine_search(false)
2710+ , disable_glow(false)
2711+ , show_filter_hint_(show_filter_hint_)
2712+ , search_bar_width_(search_bar_width)
2713+ , live_search_timeout_(0)
2714+ , start_spinner_timeout_(0)
2715+{
2716+ Init();
2717+}
2718+
2719+SearchBar::SearchBar(int search_bar_width, NUX_FILE_LINE_DECL)
2720+ : View(NUX_FILE_LINE_PARAM)
2721+ , search_hint("")
2722+ , showing_filters(false)
2723+ , can_refine_search(false)
2724+ , disable_glow(false)
2725+ , show_filter_hint_(true)
2726+ , search_bar_width_(search_bar_width)
2727+ , live_search_timeout_(0)
2728+ , start_spinner_timeout_(0)
2729+{
2730+ Init();
2731+}
2732+
2733+void SearchBar::Init()
2734+{
2735 nux::BaseTexture* icon = dash::Style::Instance().GetSearchMagnifyIcon();
2736
2737 bg_layer_ = new nux::ColorLayer(nux::Color(0xff595853), true);
2738
2739 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
2740 layout_->SetHorizontalInternalMargin(0);
2741- layout_->SetVerticalExternalMargin(8);
2742- layout_->SetHorizontalExternalMargin(7);
2743+ layout_->SetVerticalExternalMargin(external_margin_vertical);
2744+ layout_->SetHorizontalExternalMargin(external_margin_horizontal);
2745 SetLayout(layout_);
2746
2747 spinner_ = new SearchBarSpinner();
2748@@ -102,42 +143,44 @@
2749 layered_layout_->SetMaximumWidth(search_bar_width_);
2750 layout_->AddView(layered_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
2751
2752- std::string filter_str = _("<small><b>Filter results</b></small>");
2753- show_filters_ = new nux::StaticCairoText(filter_str.c_str());
2754- show_filters_->SetVisible(false);
2755- show_filters_->SetFont("Ubuntu 10");
2756- show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
2757- show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT);
2758- show_filters_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; });
2759-
2760- nux::BaseTexture* arrow;
2761- arrow = dash::Style::Instance().GetGroupExpandIcon();
2762- expand_icon_ = new IconTexture(arrow,
2763- arrow->GetWidth(),
2764- arrow->GetHeight());
2765- expand_icon_->SetOpacity(kExpandDefaultIconOpacity);
2766- expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight());
2767- expand_icon_->SetVisible(false);
2768- expand_icon_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; });
2769-
2770- filter_layout_ = new nux::HLayout();
2771- filter_layout_->SetHorizontalInternalMargin(8);
2772- filter_layout_->SetHorizontalExternalMargin(6);
2773- filter_space_ = new nux::SpaceLayout(100, 10000, 0, 1);
2774- filter_layout_->AddLayout(filter_space_, 1);
2775- filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER);
2776-
2777- arrow_layout_ = new nux::VLayout();
2778- arrow_top_space_ = new nux::SpaceLayout(2, 2, 12, 12);
2779- arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 8, 8);
2780- arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER);
2781- arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER);
2782- arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER);
2783-
2784- filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER);
2785-
2786- layout_->AddView(filter_layout_, 1, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL);
2787-
2788+ if (show_filter_hint_)
2789+ {
2790+ std::string filter_str = _("<small><b>Filter results</b></small>");
2791+ show_filters_ = new nux::StaticCairoText(filter_str.c_str());
2792+ show_filters_->SetVisible(false);
2793+ show_filters_->SetFont("Ubuntu 10");
2794+ show_filters_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
2795+ show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT);
2796+ show_filters_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; });
2797+
2798+ nux::BaseTexture* arrow;
2799+ arrow = dash::Style::Instance().GetGroupExpandIcon();
2800+ expand_icon_ = new IconTexture(arrow,
2801+ arrow->GetWidth(),
2802+ arrow->GetHeight());
2803+ expand_icon_->SetOpacity(kExpandDefaultIconOpacity);
2804+ expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight());
2805+ expand_icon_->SetVisible(false);
2806+ expand_icon_->mouse_click.connect([&] (int x, int y, unsigned long b, unsigned long k) { showing_filters = !showing_filters; });
2807+
2808+ filter_layout_ = new nux::HLayout();
2809+ filter_layout_->SetHorizontalInternalMargin(8);
2810+ filter_layout_->SetHorizontalExternalMargin(6);
2811+ filter_space_ = new nux::SpaceLayout(100, 10000, 0, 1);
2812+ filter_layout_->AddLayout(filter_space_, 1);
2813+ filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER);
2814+
2815+ arrow_layout_ = new nux::VLayout();
2816+ arrow_top_space_ = new nux::SpaceLayout(2, 2, 12, 12);
2817+ arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 8, 8);
2818+ arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER);
2819+ arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER);
2820+ arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER);
2821+
2822+ filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER);
2823+
2824+ layout_->AddView(filter_layout_, 1, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL);
2825+ }
2826 sig_manager_.Add(new Signal<void, GtkSettings*, GParamSpec*>
2827 (gtk_settings_get_default(),
2828 "notify::gtk-font-name",
2829@@ -151,9 +194,21 @@
2830 showing_filters.changed.connect(sigc::mem_fun(this, &SearchBar::OnShowingFiltersChanged));
2831 can_refine_search.changed.connect([&] (bool can_refine)
2832 {
2833- show_filters_->SetVisible(can_refine);
2834- expand_icon_->SetVisible(can_refine);
2835- });
2836+ if (show_filter_hint_)
2837+ {
2838+ show_filters_->SetVisible(can_refine);
2839+ expand_icon_->SetVisible(can_refine);
2840+ }
2841+ });
2842+
2843+ disable_glow.changed.connect([&](bool disabled)
2844+ {
2845+ layout_->SetVerticalExternalMargin(0);
2846+ layout_->SetHorizontalExternalMargin(0);
2847+ UpdateBackground(true);
2848+ QueueDraw();
2849+ });
2850+
2851 }
2852
2853 SearchBar::~SearchBar()
2854@@ -259,18 +314,21 @@
2855
2856 void SearchBar::OnShowingFiltersChanged(bool is_showing)
2857 {
2858- dash::Style& style = dash::Style::Instance();
2859- if (is_showing)
2860- expand_icon_->SetTexture(style.GetGroupUnexpandIcon());
2861- else
2862- expand_icon_->SetTexture(style.GetGroupExpandIcon());
2863+ if (show_filter_hint_)
2864+ {
2865+ dash::Style& style = dash::Style::Instance();
2866+ if (is_showing)
2867+ expand_icon_->SetTexture(style.GetGroupUnexpandIcon());
2868+ else
2869+ expand_icon_->SetTexture(style.GetGroupExpandIcon());
2870+ }
2871 }
2872
2873 void SearchBar::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
2874 {
2875 nux::Geometry geo = GetGeometry();
2876
2877- UpdateBackground();
2878+ UpdateBackground(false);
2879
2880 GfxContext.PushClippingRectangle(geo);
2881
2882@@ -344,21 +402,33 @@
2883 spinner_->SetState(is_empty ? STATE_READY : STATE_CLEAR);
2884 }
2885
2886-void SearchBar::UpdateBackground()
2887+void SearchBar::UpdateBackground(bool force)
2888 {
2889-#define PADDING 12
2890-#define RADIUS 5
2891+ int PADDING = 12;
2892+ int RADIUS = 5;
2893 int x, y, width, height;
2894 nux::Geometry geo = GetGeometry();
2895 geo.width = layered_layout_->GetGeometry().width;
2896
2897- if (geo.width == last_width_ && geo.height == last_height_)
2898+ LOG_DEBUG(logger) << "height: "
2899+ << geo.height << " - "
2900+ << layered_layout_->GetGeometry().height << " - "
2901+ << pango_entry_->GetGeometry().height;
2902+
2903+ if (geo.width == last_width_
2904+ && geo.height == last_height_
2905+ && force == false)
2906 return;
2907
2908 last_width_ = geo.width;
2909 last_height_ = geo.height;
2910
2911+ if (disable_glow)
2912+ PADDING = 2;
2913+
2914+
2915 x = y = PADDING - 1;
2916+
2917 width = last_width_ - (2 * PADDING);
2918 height = last_height_ - (2 * PADDING) + 1;
2919
2920@@ -473,5 +543,4 @@
2921 g_variant_builder_add (builder, "{sv}", "search_string", g_variant_new_string (pango_entry_->GetText().c_str()) );
2922 }
2923
2924-} // namespace dash
2925 } // namespace unity
2926
2927=== renamed file 'plugins/unityshell/src/DashSearchBar.h' => 'plugins/unityshell/src/SearchBar.h'
2928--- plugins/unityshell/src/DashSearchBar.h 2012-01-17 15:39:16 +0000
2929+++ plugins/unityshell/src/SearchBar.h 2012-02-06 11:00:29 +0000
2930@@ -17,8 +17,8 @@
2931 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
2932 */
2933
2934-#ifndef DASH_SEARCH_BAR_H
2935-#define DASH_SEARCH_BAR_H
2936+#ifndef SEARCH_BAR_H
2937+#define SEARCH_BAR_H
2938
2939 #include <gtk/gtk.h>
2940
2941@@ -32,7 +32,7 @@
2942 #include <Nux/TextEntry.h>
2943 #include <UnityCore/GLibSignal.h>
2944
2945-#include "DashSearchBarSpinner.h"
2946+#include "SearchBarSpinner.h"
2947 #include "IconTexture.h"
2948 #include "IMTextEntry.h"
2949 #include "Introspectable.h"
2950@@ -40,8 +40,6 @@
2951
2952 namespace unity
2953 {
2954-namespace dash
2955-{
2956
2957 using namespace unity::glib;
2958
2959@@ -49,7 +47,10 @@
2960 {
2961 NUX_DECLARE_OBJECT_TYPE(SearchBar, nux::View);
2962 public:
2963+ typedef nux::ObjectPtr<SearchBar> Ptr;
2964 SearchBar(NUX_FILE_LINE_PROTO);
2965+ SearchBar(int search_width, bool show_filter_hint, NUX_FILE_LINE_PROTO);
2966+ SearchBar(int search_width, NUX_FILE_LINE_PROTO);
2967 ~SearchBar();
2968
2969 void SearchFinished();
2970@@ -59,6 +60,7 @@
2971 nux::Property<std::string> search_hint;
2972 nux::Property<bool> showing_filters;
2973 nux::Property<bool> can_refine_search;
2974+ nux::Property<bool> disable_glow;
2975 nux::ROProperty<bool> im_active;
2976
2977 sigc::signal<void> activated;
2978@@ -67,6 +69,8 @@
2979
2980 private:
2981
2982+ void Init();
2983+
2984 void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL);
2985 void OnSearchHintChanged();
2986
2987@@ -76,7 +80,7 @@
2988 void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
2989 void OnEndKeyFocus();
2990
2991- void UpdateBackground();
2992+ void UpdateBackground(bool force);
2993 void OnSearchChanged(nux::TextEntry* text_entry);
2994 void OnClearClicked(int x, int y, unsigned long button_flags, unsigned long key_flags);
2995 void OnEntryActivated();
2996@@ -85,6 +89,7 @@
2997 std::string get_search_string() const;
2998 bool set_search_string(std::string const& string);
2999 bool get_im_active() const;
3000+ bool show_filter_hint_;
3001
3002 static gboolean OnLiveSearchTimeout(SearchBar* self);
3003 static gboolean OnSpinnerStartCb(SearchBar* self);
3004@@ -110,7 +115,6 @@
3005 IconTexture* expand_icon_;
3006 int search_bar_width_;
3007
3008-
3009 int last_width_;
3010 int last_height_;
3011
3012@@ -121,6 +125,5 @@
3013 };
3014
3015 }
3016-}
3017
3018 #endif
3019
3020=== renamed file 'plugins/unityshell/src/DashSearchBarSpinner.cpp' => 'plugins/unityshell/src/SearchBarSpinner.cpp'
3021--- plugins/unityshell/src/DashSearchBarSpinner.cpp 2011-12-16 22:10:23 +0000
3022+++ plugins/unityshell/src/SearchBarSpinner.cpp 2012-02-06 11:00:29 +0000
3023@@ -17,7 +17,7 @@
3024 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
3025 */
3026
3027-#include "DashSearchBarSpinner.h"
3028+#include "SearchBarSpinner.h"
3029
3030 #include <Nux/VLayout.h>
3031
3032@@ -25,8 +25,6 @@
3033
3034 namespace unity
3035 {
3036-namespace dash
3037-{
3038
3039 NUX_IMPLEMENT_OBJECT_TYPE(SearchBarSpinner);
3040
3041@@ -236,4 +234,3 @@
3042 }
3043
3044 }
3045-}
3046
3047=== renamed file 'plugins/unityshell/src/DashSearchBarSpinner.h' => 'plugins/unityshell/src/SearchBarSpinner.h'
3048--- plugins/unityshell/src/DashSearchBarSpinner.h 2011-12-08 01:23:11 +0000
3049+++ plugins/unityshell/src/SearchBarSpinner.h 2012-02-06 11:00:29 +0000
3050@@ -17,8 +17,8 @@
3051 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
3052 */
3053
3054-#ifndef DASH_SEARCH_BAR_SPINNER_H
3055-#define DASH_SEARCH_BAR_SPINNER_H
3056+#ifndef SEARCH_BAR_SPINNER_H
3057+#define SEARCH_BAR_SPINNER_H
3058
3059 #include <Nux/Nux.h>
3060 #include <Nux/View.h>
3061@@ -29,8 +29,6 @@
3062
3063 namespace unity
3064 {
3065-namespace dash
3066-{
3067
3068 enum SpinnerState
3069 {
3070@@ -80,6 +78,5 @@
3071 };
3072
3073 }
3074-}
3075
3076 #endif
3077
3078=== modified file 'plugins/unityshell/src/UBusMessages.h'
3079--- plugins/unityshell/src/UBusMessages.h 2012-01-31 10:59:11 +0000
3080+++ plugins/unityshell/src/UBusMessages.h 2012-02-06 11:00:29 +0000
3081@@ -78,6 +78,8 @@
3082 // FIXME - fix the nux focus api so we don't need this
3083 #define UBUS_RESULT_VIEW_KEYNAV_CHANGED "RESULT_VIEW_KEYNAV_CHANGED"
3084
3085+#define UBUS_HUD_CLOSE_REQUEST "HUD_CLOSE_REQUEST"
3086+
3087 // Signals sent when the switcher is shown, hidden or changes selection
3088 #define UBUS_SWITCHER_SHOWN "SWITCHER_SHOWN"
3089 #define UBUS_SWITCHER_SELECTION_CHANGED "SWITCHER_SELECTION_CHANGED"
3090
3091=== modified file 'plugins/unityshell/src/unity-search-bar-accessible.cpp'
3092--- plugins/unityshell/src/unity-search-bar-accessible.cpp 2011-09-15 13:58:42 +0000
3093+++ plugins/unityshell/src/unity-search-bar-accessible.cpp 2012-02-06 11:00:29 +0000
3094@@ -20,7 +20,7 @@
3095 * SECTION:unity-search_bar-accessible
3096 * @Title: UnitySearchBarAccessible
3097 * @short_description: Implementation of the ATK interfaces for #SearchBar
3098- * @see_also: SearchBar at DashSearchBar.h
3099+ * @see_also: SearchBar at SearchBar.h
3100 *
3101 * #UnitySearchBarAccessible implements the required ATK interfaces for
3102 * #SearchBar, ie: exposing the different SearchBarIcon on the model as
3103@@ -33,9 +33,9 @@
3104 #include "unity-search-bar-accessible.h"
3105
3106 #include "unitya11y.h"
3107-#include "DashSearchBar.h"
3108+#include "SearchBar.h"
3109
3110-using namespace unity::dash;
3111+using namespace unity;
3112
3113 /* GObject */
3114 static void unity_search_bar_accessible_class_init(UnitySearchBarAccessibleClass* klass);
3115
3116=== modified file 'plugins/unityshell/src/unitya11y.cpp'
3117--- plugins/unityshell/src/unitya11y.cpp 2011-11-07 22:28:01 +0000
3118+++ plugins/unityshell/src/unitya11y.cpp 2012-02-06 11:00:29 +0000
3119@@ -299,7 +299,7 @@
3120 if (object->Type().IsDerivedFromType(unity::dash::ResultViewGrid::StaticObjectType))
3121 return unity_rvgrid_accessible_new(object);
3122
3123- if (object->Type().IsDerivedFromType(unity::dash::SearchBar::StaticObjectType))
3124+ if (object->Type().IsDerivedFromType(unity::SearchBar::StaticObjectType))
3125 return unity_search_bar_accessible_new(object);
3126
3127 if (object->Type().IsDerivedFromType(unity::switcher::SwitcherView::StaticObjectType))
3128
3129=== modified file 'plugins/unityshell/src/unityshell.cpp'
3130--- plugins/unityshell/src/unityshell.cpp 2012-02-04 01:55:49 +0000
3131+++ plugins/unityshell/src/unityshell.cpp 2012-02-06 11:00:29 +0000
3132@@ -52,7 +52,6 @@
3133
3134 #include "unitya11y.h"
3135
3136-#include "ubus-server.h"
3137 #include "UBusMessages.h"
3138 #include "UScreen.h"
3139
3140@@ -119,6 +118,7 @@
3141 , dash_is_open_ (false)
3142 , grab_index_ (0)
3143 , painting_tray_ (false)
3144+ , last_hud_show_time_(0)
3145 {
3146 Timer timer;
3147 gfloat version;
3148@@ -258,6 +258,8 @@
3149 }
3150 #endif
3151
3152+ optionSetShowHudInitiate(boost::bind(&UnityScreen::ShowHudInitiate, this, _1, _2, _3));
3153+ optionSetShowHudTerminate(boost::bind(&UnityScreen::ShowHudTerminate, this, _1, _2, _3));
3154 optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3155 optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3156 optionSetBacklightModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
3157@@ -371,7 +373,7 @@
3158 sout << "<Alt>" << XKeysymToString(above_tab_keysym);
3159
3160 screen->removeAction(&optionGetAltTabNextWindow());
3161-
3162+
3163 CompAction action = CompAction();
3164 action.keyFromString(sout.str());
3165 action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab);
3166@@ -386,7 +388,7 @@
3167 sout << "<Alt><Shift>" << XKeysymToString(above_tab_keysym);
3168
3169 screen->removeAction(&optionGetAltTabPrevWindow());
3170-
3171+
3172 CompAction action = CompAction();
3173 action.keyFromString(sout.str());
3174 action.setState (CompAction::StateInitKey | CompAction::StateAutoGrab);
3175@@ -820,8 +822,8 @@
3176 bool UnityScreen::forcePaintOnTop ()
3177 {
3178 return !allowWindowPaint ||
3179- ((switcher_controller_->Visible() ||
3180- dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
3181+ ((switcher_controller_->Visible() ||
3182+ dash_is_open_) && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
3183 }
3184
3185 void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
3186@@ -967,7 +969,7 @@
3187 {
3188 if (mShowdesktopHandler)
3189 if (mShowdesktopHandler->animate (ms))
3190- {
3191+ {
3192 delete mShowdesktopHandler;
3193 mShowdesktopHandler = NULL;
3194 return true;
3195@@ -996,7 +998,7 @@
3196 return false;
3197
3198 if (w->state () & (CompWindowStateSkipPagerMask |
3199- CompWindowStateSkipTaskbarMask))
3200+ CompWindowStateSkipTaskbarMask))
3201 return false;
3202
3203 if ((w->state () & CompWindowStateHiddenMask))
3204@@ -1669,7 +1671,7 @@
3205 altTabInitiateCommon(action, state, options);
3206 switcher_controller_->Select(1); // always select the current application
3207 }
3208-
3209+
3210 switcher_controller_->NextDetail();
3211
3212 action->setState(action->state() | CompAction::StateTermKey);
3213@@ -1680,7 +1682,7 @@
3214 {
3215 if (switcher_controller_->Visible())
3216 switcher_controller_->PrevDetail();
3217-
3218+
3219 return false;
3220 }
3221
3222@@ -1735,6 +1737,44 @@
3223 PluginAdapter::Default ()->restoreInputFocus ();
3224 }
3225
3226+bool UnityScreen::ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
3227+{
3228+ // to receive the Terminate event
3229+ if (state & CompAction::StateInitKey)
3230+ action->setState(action->state() | CompAction::StateTermKey);
3231+
3232+ last_hud_show_time_ = g_get_monotonic_time();
3233+
3234+ return false;
3235+}
3236+
3237+bool UnityScreen::ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
3238+{
3239+ if (optionGetShowHud().key().toString() == action->key().toString())
3240+ {
3241+ if (switcher_controller_->Visible())
3242+ return false; // early exit if the switcher is open
3243+
3244+ gint64 current_time = g_get_monotonic_time();
3245+ if (current_time - last_hud_show_time_ < 150 * 1000)
3246+ {
3247+ if (hud_controller_->IsVisible())
3248+ {
3249+ ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST);
3250+ }
3251+ else
3252+ {
3253+ hud_controller_->ShowHud();
3254+ }
3255+ last_hud_show_time_ = 0;
3256+ }
3257+ }
3258+
3259+ action->setState(action->state() & ~CompAction::StateTermKey);
3260+
3261+ return false;
3262+}
3263+
3264 gboolean UnityScreen::initPluginActions(gpointer data)
3265 {
3266 CompPlugin* p = CompPlugin::find("expo");
3267@@ -1821,7 +1861,7 @@
3268 bool result = screen->initPluginForScreen(p);
3269 if (p->vTable->name() == "unityshell")
3270 initAltTabNextWindow();
3271-
3272+
3273 return result;
3274 }
3275
3276@@ -1834,8 +1874,8 @@
3277 return "Unity";
3278 }
3279
3280-bool isNuxWindow (CompWindow* value)
3281-{
3282+bool isNuxWindow (CompWindow* value)
3283+{
3284 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3285 auto id = value->id();
3286
3287@@ -1862,7 +1902,7 @@
3288 void UnityScreen::RaiseInputWindows()
3289 {
3290 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
3291-
3292+
3293 for (auto window : xwns)
3294 {
3295 CompWindow* cwin = screen->findWindow(window);
3296@@ -1995,7 +2035,7 @@
3297 if (!window->onCurrentDesktop ())
3298 return false;
3299
3300- /* Only withdrawn windows
3301+ /* Only withdrawn windows
3302 * which are marked hidden
3303 * are excluded */
3304 if (!window->shaded () &&
3305@@ -2003,8 +2043,8 @@
3306 (window->state () & CompWindowStateHiddenMask))
3307 return false;
3308
3309- if (window->geometry ().x () + window->geometry ().width () <= 0 ||
3310- window->geometry ().y () + window->geometry ().height () <= 0 ||
3311+ if (window->geometry ().x () + window->geometry ().width () <= 0 ||
3312+ window->geometry ().y () + window->geometry ().height () <= 0 ||
3313 window->geometry ().x () >= (int) screen->width ()||
3314 window->geometry ().y () >= (int) screen->height ())
3315 return false;
3316@@ -2110,7 +2150,7 @@
3317 !(lastState & CompWindowStateFullscreenMask))
3318 UnityScreen::get (screen)->fullscreen_windows_.push_back(window);
3319 else if (lastState & CompWindowStateFullscreenMask &&
3320- !(window->state () & CompWindowStateFullscreenMask))
3321+ !(window->state () & CompWindowStateFullscreenMask))
3322 UnityScreen::get (screen)->fullscreen_windows_.remove(window);
3323
3324 PluginAdapter::Default()->NotifyStateChange(window, window->state(), lastState);
3325@@ -2259,9 +2299,9 @@
3326 {
3327 case UnityshellOptions::BackgroundColor:
3328 {
3329- nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f,
3330- optionGetBackgroundColorGreen() / 65535.0f,
3331- optionGetBackgroundColorBlue() / 65535.0f,
3332+ nux::Color override_color (optionGetBackgroundColorRed() / 65535.0f,
3333+ optionGetBackgroundColorGreen() / 65535.0f,
3334+ optionGetBackgroundColorBlue() / 65535.0f,
3335 optionGetBackgroundColorAlpha() / 65535.0f);
3336
3337 override_color.red = override_color.red / override_color.alpha;
3338@@ -2309,6 +2349,7 @@
3339 launcher_options->icon_size = optionGetIconSize();
3340 launcher_options->tile_size = optionGetIconSize() + 6;
3341
3342+ hud_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1;
3343 /* The launcher geometry includes 1px used to draw the right margin
3344 * that must not be considered when drawing the dash */
3345 dash_controller_->launcher_width = launcher_controller_->launcher().GetAbsoluteWidth() - 1;
3346@@ -2497,6 +2538,11 @@
3347 /* Setup Places */
3348 dash_controller_.reset(new dash::Controller());
3349 dash_controller_->on_realize.connect(sigc::mem_fun(this, &UnityScreen::OnDashRealized));
3350+
3351+ /* Setup Hud */
3352+ hud_controller_.reset(new hud::Controller());
3353+ AddChild(hud_controller_.get());
3354+ LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
3355
3356 // Setup Shortcut Hint
3357 InitHints();
3358@@ -2646,7 +2692,7 @@
3359
3360 if (mShowdesktopHandler)
3361 delete mShowdesktopHandler;
3362-
3363+
3364 if (focusdesktop_handle_)
3365 g_source_remove(focusdesktop_handle_);
3366
3367
3368=== modified file 'plugins/unityshell/src/unityshell.h'
3369--- plugins/unityshell/src/unityshell.h 2012-01-29 06:08:20 +0000
3370+++ plugins/unityshell/src/unityshell.h 2012-02-06 11:00:29 +0000
3371@@ -58,6 +58,8 @@
3372 #include <compiztoolbox/compiztoolbox.h>
3373 #include <dlfcn.h>
3374
3375+#include "HudController.h"
3376+
3377 namespace unity
3378 {
3379
3380@@ -202,6 +204,9 @@
3381 bool altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3382 bool altTabPrevWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3383
3384+ /* handle hud key activations */
3385+ bool ShowHudInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3386+ bool ShowHudTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3387 bool launcherSwitcherForwardInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3388 bool launcherSwitcherPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3389 bool launcherSwitcherTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options);
3390@@ -268,6 +273,7 @@
3391 dash::Controller::Ptr dash_controller_;
3392 panel::Controller::Ptr panel_controller_;
3393 switcher::Controller::Ptr switcher_controller_;
3394+ hud::Controller::Ptr hud_controller_;
3395
3396 shortcut::Controller::Ptr shortcut_controller_;
3397 std::list<shortcut::AbstractHint*> hints_;
3398@@ -322,6 +328,7 @@
3399 CompWindowList fullscreen_windows_;
3400 bool painting_tray_;
3401 unsigned int tray_paint_mask_;
3402+ gint64 last_hud_show_time_;
3403
3404 #ifndef USE_GLES
3405 ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP;
3406@@ -396,7 +403,7 @@
3407 UnityMinimizedHandler *mMinimizeHandler;
3408
3409 UnityShowdesktopHandler *mShowdesktopHandler;
3410-
3411+
3412 private:
3413
3414 guint focusdesktop_handle_;
3415
3416=== modified file 'plugins/unityshell/unityshell.xml.in'
3417--- plugins/unityshell/unityshell.xml.in 2012-02-01 00:06:29 +0000
3418+++ plugins/unityshell/unityshell.xml.in 2012-02-06 11:00:29 +0000
3419@@ -40,9 +40,14 @@
3420 </requirement>
3421 </deps>
3422 <options>
3423- <group>
3424+ <group>
3425 <_short>Behaviour</_short>
3426- <option name="launcher_hide_mode" type="int">
3427+ <option name="show_hud" type="key">
3428+ <_short>Key to show the HUD</_short>
3429+ <_long>Make the HUD appear with this key</_long>
3430+ <default>&lt;Alt&gt;</default>
3431+ </option>
3432+ <option name="launcher_hide_mode" type="int">
3433 <_short>Hide Launcher</_short>
3434 <_long>Make the launcher hide automatically after some time of inactivity: always or just when the focussed window is not over the launcher</_long>
3435 <min>0</min>
3436@@ -64,16 +69,16 @@
3437 <value>3</value>
3438 <_name>Dodge Active Window</_name>
3439 </desc>
3440- </option>
3441- <option name="show_launcher" type="key">
3442+ </option>
3443+ <option name="show_launcher" type="key">
3444 <_short>Key to show the launcher</_short>
3445 <_long>Make the launcher appear with that key</_long>
3446 <default>&lt;Super&gt;</default>
3447 </option>
3448 <option name="keyboard_focus" type="key">
3449- <_short>Key to put keyboard-focus on launcher</_short>
3450- <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long>
3451- <default>&lt;Alt&gt;F1</default>
3452+ <_short>Key to put keyboard-focus on launcher</_short>
3453+ <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long>
3454+ <default>&lt;Alt&gt;F1</default>
3455 </option>
3456 <option name="execute_command" type="key">
3457 <_short>Key to execute a command</_short>
3458@@ -118,37 +123,37 @@
3459 <_long>fixme</_long>
3460 <default>&lt;Alt&gt;&lt;Shift&gt;Tab</default>
3461 </option>
3462- <option name="alt_tab_right" type="key">
3463- <_short>Go right in the switcher</_short>
3464- <_long>fixme</_long>
3465- <default>&lt;Alt&gt;Right</default>
3466- <passive_grab>false</passive_grab>
3467- <internal/>
3468- </option>
3469- <option name="alt_tab_left" type="key">
3470- <_short>Go left in the switcher</_short>
3471- <_long>fixme</_long>
3472- <default>&lt;Alt&gt;Left</default>
3473- <passive_grab>false</passive_grab>
3474- <internal/>
3475- </option>
3476+ <option name="alt_tab_right" type="key">
3477+ <_short>Go right in the switcher</_short>
3478+ <_long>fixme</_long>
3479+ <default>&lt;Alt&gt;Right</default>
3480+ <passive_grab>false</passive_grab>
3481+ <internal/>
3482+ </option>
3483+ <option name="alt_tab_left" type="key">
3484+ <_short>Go left in the switcher</_short>
3485+ <_long>fixme</_long>
3486+ <default>&lt;Alt&gt;Left</default>
3487+ <passive_grab>false</passive_grab>
3488+ <internal/>
3489+ </option>
3490 <option name="alt_tab_detail_start" type="key">
3491- <_short>Key to expose the windows in the switcher</_short>
3492- <_long>fixme</_long>
3493- <default>&lt;Alt&gt;Down</default>
3494- <passive_grab>false</passive_grab>
3495- <internal/>
3496+ <_short>Key to expose the windows in the switcher</_short>
3497+ <_long>fixme</_long>
3498+ <default>&lt;Alt&gt;Down</default>
3499+ <passive_grab>false</passive_grab>
3500+ <internal/>
3501 </option>
3502- <option name="alt_tab_detail_stop" type="key">
3503- <_short>Key to collapse windows in the switcher</_short>
3504- <_long>fixme</_long>
3505- <default>&lt;Alt&gt;Up</default>
3506- <passive_grab>false</passive_grab>
3507- <internal/>
3508- </option>
3509+ <option name="alt_tab_detail_stop" type="key">
3510+ <_short>Key to collapse windows in the switcher</_short>
3511+ <_long>fixme</_long>
3512+ <default>&lt;Alt&gt;Up</default>
3513+ <passive_grab>false</passive_grab>
3514+ <internal/>
3515+ </option>
3516 <option name="alt_tab_next_window" type="key">
3517- <_short>Key to flip through windows in the switcher</_short>
3518- <_long>fixme</_long>
3519+ <_short>Key to flip through windows in the switcher</_short>
3520+ <_long>fixme</_long>
3521 <passive_grab>false</passive_grab>
3522 </option>
3523 <option name="alt_tab_prev_window" type="key">
3524@@ -156,11 +161,11 @@
3525 <_long>fixme</_long>
3526 <passive_grab>false</passive_grab>
3527 </option>
3528- <option name="show_minimized_windows" type="bool">
3529- <_short>Show minimized windows in switcher</_short>
3530- <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long>
3531- <default>true</default>
3532- </option>
3533+ <option name="show_minimized_windows" type="bool">
3534+ <_short>Show minimized windows in switcher</_short>
3535+ <_long>Hack to enable minimized windows in switcher. Disable and report bugs if problems are caused</_long>
3536+ <default>true</default>
3537+ </option>
3538 </group>
3539 <group>
3540 <_short>Experimental</_short>
3541@@ -359,7 +364,7 @@
3542 <max>100</max>
3543 <default>75</default>
3544 </option>
3545-
3546+
3547 <option name="devices_option" type="int">
3548 <_short>Show Devices</_short>
3549 <_long>Show devices in the launcher</_long>
3550
3551=== modified file 'po/POTFILES.in'
3552--- po/POTFILES.in 2012-01-24 09:02:23 +0000
3553+++ po/POTFILES.in 2012-02-06 11:00:29 +0000
3554@@ -6,7 +6,7 @@
3555 plugins/unityshell/src/SpacerLauncherIcon.cpp
3556 plugins/unityshell/src/TrashLauncherIcon.cpp
3557 plugins/unityshell/src/BFBLauncherIcon.cpp
3558-plugins/unityshell/src/DashSearchBar.cpp
3559+plugins/unityshell/src/SearchBar.cpp
3560 plugins/unityshell/src/DashView.cpp
3561 plugins/unityshell/src/DesktopLauncherIcon.cpp
3562 plugins/unityshell/src/FilterExpanderLabel.cpp
3563
3564=== modified file 'standalone-clients/CMakeLists.txt'
3565--- standalone-clients/CMakeLists.txt 2012-01-24 08:53:48 +0000
3566+++ standalone-clients/CMakeLists.txt 2012-02-06 11:00:29 +0000
3567@@ -47,10 +47,10 @@
3568 ${UNITY_SRC}/BackgroundEffectHelper.h
3569 ${UNITY_SRC}/BGHash.cpp
3570 ${UNITY_SRC}/BGHash.h
3571- ${UNITY_SRC}/DashSearchBar.cpp
3572- ${UNITY_SRC}/DashSearchBar.h
3573- ${UNITY_SRC}/DashSearchBarSpinner.cpp
3574- ${UNITY_SRC}/DashSearchBarSpinner.h
3575+ ${UNITY_SRC}/SearchBar.cpp
3576+ ${UNITY_SRC}/SearchBar.h
3577+ ${UNITY_SRC}/SearchBarSpinner.cpp
3578+ ${UNITY_SRC}/SearchBarSpinner.h
3579 ${UNITY_SRC}/DashView.cpp
3580 ${UNITY_SRC}/DashView.h
3581 ${UNITY_SRC}/DashViewPrivate.cpp
3582@@ -84,6 +84,10 @@
3583 ${UNITY_SRC}/PlacesSimpleTile.h
3584 ${UNITY_SRC}/PlacesVScrollBar.cpp
3585 ${UNITY_SRC}/PlacesVScrollBar.h
3586+ ${UNITY_SRC}/DashView.cpp
3587+ ${UNITY_SRC}/DashView.h
3588+ ${UNITY_SRC}/DashViewPrivate.cpp
3589+ ${UNITY_SRC}/DashViewPrivate.h
3590 ${UNITY_SRC}/DashStyle.cpp
3591 ${UNITY_SRC}/IconLoader.cpp
3592 ${UNITY_SRC}/IconLoader.h
3593@@ -456,6 +460,39 @@
3594 )
3595 add_dependencies (bg-hash unity-core-${UNITY_API_VERSION})
3596
3597+add_executable (hud
3598+ StandaloneHud.cpp
3599+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
3600+ ${UNITY_SRC}/BackgroundEffectHelper.h
3601+ ${UNITY_SRC}/DashSettings.cpp
3602+ ${UNITY_SRC}/DashSettings.h
3603+ ${UNITY_SRC}/DashStyle.cpp
3604+ ${UNITY_SRC}/HudButton.cpp
3605+ ${UNITY_SRC}/HudIcon.cpp
3606+ ${UNITY_SRC}/HudIcon.h
3607+ ${UNITY_SRC}/HudIconTextureSource.cpp
3608+ ${UNITY_SRC}/HudIconTextureSource.h
3609+ ${UNITY_SRC}/HudView.cpp
3610+ ${UNITY_SRC}/IMTextEntry.cpp
3611+ ${UNITY_SRC}/Introspectable.cpp
3612+ ${UNITY_SRC}/IconTexture.cpp
3613+ ${UNITY_SRC}/IconLoader.cpp
3614+ ${UNITY_SRC}/IconRenderer.cpp
3615+ ${UNITY_SRC}/IconTextureSource.cpp
3616+ ${UNITY_SRC}/JSONParser.cpp
3617+ ${UNITY_SRC}/OverlayRenderer.cpp
3618+ ${UNITY_SRC}/SearchBar.cpp
3619+ ${UNITY_SRC}/SearchBarSpinner.cpp
3620+ ${UNITY_SRC}/StaticCairoText.cpp
3621+ ${UNITY_SRC}/TextureCache.cpp
3622+ ${UNITY_SRC}/Timer.cpp
3623+ ${UNITY_SRC}/UBusWrapper.cpp
3624+ ${UNITY_SRC}/ubus-server.cpp
3625+ ${UNITY_SRC}/UScreen.cpp
3626+ ${UNITY_SRC}/UScreen.h
3627+ )
3628+add_dependencies (hud unity-core-${UNITY_API_VERSION})
3629+
3630 add_executable (test-shortcut
3631 TestShortcut.cpp
3632 ${UNITY_SRC}/AbstractSeparator.cpp
3633
3634=== added file 'standalone-clients/StandaloneHud.cpp'
3635--- standalone-clients/StandaloneHud.cpp 1970-01-01 00:00:00 +0000
3636+++ standalone-clients/StandaloneHud.cpp 2012-02-06 11:00:29 +0000
3637@@ -0,0 +1,171 @@
3638+/*
3639+ * Copyright 2010 Canonical Ltd.
3640+ *
3641+ * This program is free software: you can redistribute it and/or modify it
3642+ * under the terms of the GNU General Public License version 3, as published
3643+ * by the Free Software Foundation.
3644+ *
3645+ * This program is distributed in the hope that it will be useful, but
3646+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3647+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
3648+ * PURPOSE. See the GNU General Public License for more details.
3649+ *
3650+ * You should have received a copy of the GNU General Public License
3651+ * version 3 along with this program. If not, see
3652+ * <http://www.gnu.org/licenses/>
3653+ *
3654+ * Authored by: Gordon Allott <gord.allott@canonical.com>
3655+ *
3656+ */
3657+
3658+#include <sstream>
3659+#include "Nux/Nux.h"
3660+#include "Nux/VLayout.h"
3661+#include "Nux/Button.h"
3662+#include "Nux/TextureArea.h"
3663+#include "Nux/WindowThread.h"
3664+#include "NuxGraphics/GraphicsEngine.h"
3665+#include <gtk/gtk.h>
3666+
3667+#include "HudView.h"
3668+#include "DashStyle.h"
3669+#include "DashSettings.h"
3670+#include <NuxCore/Logger.h>
3671+
3672+namespace
3673+{
3674+ nux::logging::Logger logger("unity.tests.Hud");
3675+}
3676+
3677+class TestRunner
3678+{
3679+public:
3680+ TestRunner ();
3681+ ~TestRunner ();
3682+
3683+ static void InitWindowThread (nux::NThread* thread, void* InitData);
3684+ void Init ();
3685+ nux::Layout *layout;
3686+ unity::hud::View* hud_view_;
3687+ unity::dash::Settings dash_settings_;
3688+
3689+private:
3690+ unity::hud::Hud hud_service_;
3691+};
3692+
3693+TestRunner::TestRunner ()
3694+ : hud_service_("com.canonical.hud", "/com/canonical/hud")
3695+{
3696+}
3697+
3698+TestRunner::~TestRunner ()
3699+{
3700+}
3701+
3702+void TestRunner::Init ()
3703+{
3704+ LOG_WARNING(logger) << "test init";
3705+ layout = new nux::VLayout();
3706+
3707+ hud_view_ = new unity::hud::View();
3708+
3709+ layout->AddView (hud_view_, 1, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL);
3710+ nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus());
3711+
3712+ nux::GetWindowThread()->SetLayout (layout);
3713+
3714+ // things the controller normally does
3715+ hud_service_.queries_updated.connect([&] (unity::hud::Hud::Queries queries) {
3716+ hud_view_->SetQueries(queries);
3717+ std::string icon_name = "";
3718+ for (auto query = queries.begin(); query != queries.end(); query++)
3719+ {
3720+ if (!(*query)->icon_name.empty())
3721+ {
3722+ LOG_DEBUG(logger) << "Setting icon name to: " << (*query)->icon_name;
3723+ icon_name = (*query)->icon_name;
3724+ break;
3725+ }
3726+ }
3727+
3728+ hud_view_->SetIcon(icon_name);
3729+
3730+ });
3731+
3732+ hud_view_->query_activated.connect([&] (unity::hud::Query::Ptr query) {
3733+ hud_service_.ExecuteQuery(query, 0);
3734+ });
3735+
3736+ hud_view_->query_selected.connect([&] (unity::hud::Query::Ptr query) {
3737+ hud_view_->SetIcon(query->icon_name);
3738+ });
3739+
3740+ hud_view_->search_changed.connect([&] (std::string search_string) {
3741+ hud_service_.RequestQuery(search_string);
3742+ });
3743+
3744+ hud_view_->search_activated.connect([&] (std::string search_string) {
3745+ hud_service_.ExecuteQueryBySearch(search_string, 0);
3746+ });
3747+
3748+ hud_service_.RequestQuery("");
3749+
3750+ hud_view_->SetWindowGeometry(layout->GetAbsoluteGeometry(), layout->GetGeometry());
3751+
3752+}
3753+
3754+void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData)
3755+{
3756+ TestRunner *self = (TestRunner *) InitData;
3757+ self->Init ();
3758+}
3759+
3760+void
3761+ControlThread (nux::NThread* thread,
3762+ void* data)
3763+{
3764+ // sleep for 3 seconds
3765+ nux::SleepForMilliseconds (3000);
3766+ printf ("ControlThread successfully started\n");
3767+}
3768+
3769+
3770+int main(int argc, char **argv)
3771+{
3772+ nux::SystemThread* st = NULL;
3773+ nux::WindowThread* wt = NULL;
3774+
3775+ // no real tests right now, just make sure we don't get any criticals and such
3776+ // waiting on nice perceptual diff support before we can build real tests
3777+ // for views
3778+
3779+ g_type_init ();
3780+ gtk_init (&argc, &argv);
3781+
3782+ nux::NuxInitialize(0);
3783+
3784+ // Slightly higher as we're more likely to test things we know will fail
3785+ nux::logging::configure_logging("unity.hud=debug");
3786+
3787+ nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
3788+ LOG_DEBUG(logger) << "starting the standalone hud";
3789+ // The instances for the pseudo-singletons.
3790+ unity::dash::Style dash_style;
3791+
3792+ TestRunner *test_runner = new TestRunner ();
3793+ wt = nux::CreateGUIThread(TEXT("Hud Prototype Test"),
3794+ 1200, 768,
3795+ 0,
3796+ &TestRunner::InitWindowThread,
3797+ test_runner);
3798+
3799+ st = nux::CreateSystemThread (NULL, ControlThread, wt);
3800+
3801+ if (st)
3802+ st->Start (NULL);
3803+
3804+ wt->Run (NULL);
3805+ delete st;
3806+ delete wt;
3807+ return 0;
3808+}
3809
3810=== modified file 'tests/CMakeLists.txt'
3811--- tests/CMakeLists.txt 2012-02-01 03:39:14 +0000
3812+++ tests/CMakeLists.txt 2012-02-06 11:00:29 +0000
3813@@ -99,6 +99,8 @@
3814
3815 # The service that provides DBus services to test against
3816 add_executable(test-gtest-service
3817+ test_service_hud.c
3818+ test_service_hud.h
3819 test_service_lens.c
3820 test_service_lens.h
3821 test_service_main.c
3822@@ -183,7 +185,8 @@
3823 test_utils.h
3824 test_ratings_filter.cpp
3825 test_results.cpp
3826- )
3827+ test_hud.cpp
3828+ )
3829 target_link_libraries(test-gtest-dbus ${GTEST_BOTH_LIBRARIES})
3830 add_test(UnityGTestDBus test-gtest-dbus)
3831 add_dependencies(test-gtest-dbus unity-core-${UNITY_API_VERSION} test-gtest-service)
3832
3833=== added file 'tests/test_hud.cpp'
3834--- tests/test_hud.cpp 1970-01-01 00:00:00 +0000
3835+++ tests/test_hud.cpp 2012-02-06 11:00:29 +0000
3836@@ -0,0 +1,104 @@
3837+#include <gtest/gtest.h>
3838+#include <glib-object.h>
3839+#include <UnityCore/GLibWrapper.h>
3840+#include <UnityCore/Hud.h>
3841+
3842+using namespace std;
3843+
3844+namespace
3845+{
3846+
3847+GMainLoop* loop_ = NULL;
3848+unity::hud::Hud *hud;
3849+
3850+class TestHud : public ::testing::Test
3851+{
3852+public:
3853+ TestHud()
3854+ : query_return_result(false)
3855+ , connected_result(false)
3856+ {
3857+ }
3858+ unity::hud::Hud::Queries queries;
3859+ bool query_return_result;
3860+ bool connected_result;
3861+};
3862+
3863+TEST_F(TestHud, TestConstruction)
3864+{
3865+ loop_ = g_main_loop_new(NULL, FALSE);
3866+ hud = new unity::hud::Hud("com.canonical.Unity.Test", "/com/canonical/hud");
3867+
3868+ // performs a check on the hud, if the hud is connected, report a sucess
3869+ auto timeout_check = [] (gpointer data) -> gboolean
3870+ {
3871+ TestHud* self = static_cast<TestHud*>(data);
3872+ if (hud->connected)
3873+ {
3874+ self->connected_result = true;
3875+ g_main_loop_quit(loop_);
3876+ return FALSE;
3877+ }
3878+ else
3879+ {
3880+ self->connected_result = false;
3881+ return TRUE;
3882+ }
3883+ };
3884+
3885+
3886+ // if the hud is not connected when this lambda runs, fail.
3887+ auto timeout_bailout = [] (gpointer data) -> gboolean
3888+ {
3889+ TestHud* self = static_cast<TestHud*>(data);
3890+ // reached timeout, failed testing
3891+ self->connected_result = false;
3892+ g_main_loop_quit(loop_);
3893+ return FALSE;
3894+ };
3895+
3896+ g_timeout_add_seconds(1, timeout_check, this);
3897+ g_timeout_add_seconds(10, timeout_bailout, this);
3898+
3899+ g_main_loop_run(loop_);
3900+
3901+ EXPECT_EQ(connected_result, true);
3902+}
3903+
3904+TEST_F(TestHud, TestQueryReturn)
3905+{
3906+ query_return_result = false;
3907+
3908+ // make sure we receive the queries
3909+ auto query_connection = [this](unity::hud::Hud::Queries queries_)
3910+ {
3911+ query_return_result = true;
3912+ g_main_loop_quit(loop_);
3913+ queries = queries_;
3914+ };
3915+
3916+ auto timeout_bailout = [] (gpointer data) -> gboolean
3917+ {
3918+ TestHud* self = static_cast<TestHud*>(data);
3919+ self->query_return_result = false;
3920+ g_main_loop_quit(loop_);
3921+ return FALSE;
3922+ };
3923+
3924+ hud->queries_updated.connect(query_connection);
3925+
3926+ guint source_id = g_timeout_add_seconds(10, timeout_bailout, this);
3927+
3928+ // next check we get 30 entries from this specific known callback
3929+ hud->RequestQuery("Request30Queries");
3930+ g_main_loop_run(loop_);
3931+ EXPECT_EQ(query_return_result, true);
3932+ EXPECT_NE(queries.size(), 0);
3933+ g_source_remove(source_id);
3934+
3935+ // finally close the connection - Nothing to check for here
3936+ hud->CloseQuery();
3937+}
3938+
3939+
3940+}
3941
3942=== added file 'tests/test_service_hud.c'
3943--- tests/test_service_hud.c 1970-01-01 00:00:00 +0000
3944+++ tests/test_service_hud.c 2012-02-06 11:00:29 +0000
3945@@ -0,0 +1,268 @@
3946+#include "test_service_hud.h"
3947+#include <unity.h>
3948+#include <gio/gio.h>
3949+
3950+const char * hud_interface =
3951+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
3952+"<node name=\"/\">\n"
3953+" <interface name=\"com.canonical.hud\">\n"
3954+"<!-- Properties -->\n"
3955+" <!-- None -->\n"
3956+"\n"
3957+"<!-- Functions -->\n"
3958+" <method name=\"StartQuery\">\n"
3959+" <!-- in -->\n"
3960+" <arg type=\"s\" name=\"query\" direction=\"in\" />\n"
3961+" <arg type=\"i\" name=\"entries\" direction=\"in\" />\n"
3962+" <!-- out -->\n"
3963+" <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
3964+" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
3965+" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
3966+" </method>\n"
3967+"\n"
3968+" <method name=\"ExecuteQuery\">\n"
3969+" <arg type=\"v\" name=\"key\" direction=\"in\" />\n"
3970+" <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n"
3971+" </method>\n"
3972+"\n"
3973+" <method name=\"CloseQuery\">\n"
3974+" <arg type=\"v\" name=\"querykey\" direction=\"in\" />\n"
3975+" </method>\n"
3976+"\n"
3977+"<!-- Signals -->\n"
3978+" <signal name=\"UpdatedQuery\">\n"
3979+" <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
3980+" <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
3981+" <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
3982+" </signal>\n"
3983+"\n"
3984+"<!-- End of interesting stuff -->\n"
3985+"\n"
3986+" </interface>\n"
3987+"</node>\n"
3988+;
3989+static void bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data);
3990+static void bus_method (GDBusConnection *connection,
3991+ const gchar *sender,
3992+ const gchar *object_path,
3993+ const gchar *interface_name,
3994+ const gchar *method_name,
3995+ GVariant *parameters,
3996+ GDBusMethodInvocation *invocation,
3997+ gpointer user_data);
3998+
3999+G_DEFINE_TYPE(ServiceHud, service_hud, G_TYPE_OBJECT);
4000+static GDBusNodeInfo * node_info = NULL;
4001+static GDBusInterfaceInfo * iface_info = NULL;
4002+static GDBusInterfaceVTable bus_vtable = {
4003+ method_call: bus_method,
4004+ get_property: NULL,
4005+ set_property: NULL,
4006+};
4007+
4008+
4009+struct _ServiceHudPrivate
4010+{
4011+ GDBusConnection * bus;
4012+ GCancellable * bus_lookup;
4013+ guint bus_registration;
4014+};
4015+
4016+static void
4017+service_hud_dispose(GObject* object)
4018+{
4019+ ServiceHud* self = SERVICE_HUD(object);
4020+ if (self->priv->bus_lookup != NULL) {
4021+ g_cancellable_cancel(self->priv->bus_lookup);
4022+ g_object_unref(self->priv->bus_lookup);
4023+ self->priv->bus_lookup = NULL;
4024+ }
4025+
4026+ if (self->priv->bus_registration != 0) {
4027+ g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration);
4028+ self->priv->bus_registration = 0;
4029+ }
4030+
4031+ if (self->priv->bus != NULL) {
4032+ g_object_unref(self->priv->bus);
4033+ self->priv->bus = NULL;
4034+ }
4035+
4036+}
4037+
4038+static void
4039+service_hud_class_init(ServiceHudClass* klass)
4040+{
4041+ G_OBJECT_CLASS(klass)->dispose = service_hud_dispose;
4042+ g_type_class_add_private (klass, sizeof (ServiceHudPrivate));
4043+
4044+ if (node_info == NULL)
4045+ {
4046+ GError * error = NULL;
4047+
4048+ node_info = g_dbus_node_info_new_for_xml(hud_interface, &error);
4049+ if (error != NULL)
4050+ {
4051+ g_error("Unable to parse HUD interface: %s", error->message);
4052+ g_error_free(error);
4053+ }
4054+ }
4055+
4056+ if (node_info != NULL && iface_info == NULL)
4057+ {
4058+ iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.hud");
4059+ if (iface_info == NULL)
4060+ {
4061+ g_error("Unable to find interface 'com.canonical.hud'");
4062+ }
4063+ }
4064+
4065+}
4066+
4067+static void
4068+service_hud_init(ServiceHud* self)
4069+{
4070+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_HUD, ServiceHudPrivate);
4071+ self->priv->bus = NULL;
4072+ self->priv->bus_lookup = NULL;
4073+ self->priv->bus_registration = 0;
4074+
4075+ self->priv->bus_lookup = g_cancellable_new();
4076+ g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self);
4077+
4078+}
4079+
4080+ServiceHud*
4081+service_hud_new()
4082+{
4083+ return g_object_new(SERVICE_TYPE_HUD, NULL);
4084+}
4085+
4086+static void
4087+bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data)
4088+{
4089+ GError * error = NULL;
4090+ ServiceHud * self = SERVICE_HUD(user_data);
4091+ GDBusConnection * bus;
4092+
4093+ bus = g_bus_get_finish(res, &error);
4094+ if (error != NULL) {
4095+ g_critical("Unable to get bus: %s", error->message);
4096+ g_error_free(error);
4097+ return;
4098+ }
4099+
4100+ self->priv->bus = bus;
4101+
4102+ /* Register object */
4103+ self->priv->bus_registration = g_dbus_connection_register_object(bus,
4104+ /* path */ "/com/canonical/hud",
4105+ /* interface */ iface_info,
4106+ /* vtable */ &bus_vtable,
4107+ /* userdata */ self,
4108+ /* destroy */ NULL,
4109+ /* error */ &error);
4110+
4111+ if (error != NULL) {
4112+ g_critical ("Unable to create bus connection object, %s", error->message);
4113+ g_error_free(error);
4114+ return;
4115+ }
4116+
4117+ return;
4118+}
4119+
4120+static void
4121+bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
4122+{
4123+ if (g_strcmp0(method_name, "StartQuery") == 0)
4124+ {
4125+ GVariant * ret = NULL;
4126+ gchar * query = NULL;
4127+ int num_entries = 0;
4128+
4129+ g_variant_get(parameters, "(si)", &query, &num_entries);
4130+
4131+ /* Build into into a variant */
4132+ GVariantBuilder ret_builder;
4133+ g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE);
4134+ g_variant_builder_add_value(&ret_builder, g_variant_new_string("target"));
4135+ GVariantBuilder builder;
4136+
4137+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
4138+
4139+ int i = 0;
4140+ for (i = 0; i < num_entries; i++)
4141+ {
4142+ gchar* target = g_strdup_printf("test-%i", i);
4143+ gchar* icon = g_strdup_printf("icon-%i", i);
4144+ gchar* future_icon = g_strdup(icon);
4145+ gchar* completion_text = g_strdup_printf("completion-%i", i);
4146+ gchar* accelerator = g_strdup_printf("<alt>+whatever");
4147+
4148+ GVariantBuilder tuple;
4149+ g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
4150+ g_variant_builder_add_value(&tuple, g_variant_new_string(target));
4151+ g_variant_builder_add_value(&tuple, g_variant_new_string(icon));
4152+ g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon));
4153+ g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text));
4154+ g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator));
4155+ // build a fake key
4156+ GVariant* key;
4157+ {
4158+ GVariantBuilder keybuilder;
4159+ g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
4160+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4161+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4162+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4163+ g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
4164+
4165+ key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
4166+ }
4167+ g_variant_ref_sink(key);
4168+ g_variant_builder_add_value(&tuple, key);
4169+ g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple));
4170+ g_free(target);
4171+ g_free(icon);
4172+ g_free(future_icon);
4173+ g_free(completion_text);
4174+ }
4175+ g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder));
4176+
4177+ GVariant* query_key;
4178+ {
4179+ GVariantBuilder keybuilder;
4180+ g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
4181+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4182+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4183+ g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
4184+ g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
4185+
4186+ query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
4187+ }
4188+ g_variant_ref_sink(query_key);
4189+ g_variant_builder_add_value(&ret_builder, query_key);
4190+
4191+ ret = g_variant_builder_end(&ret_builder);
4192+
4193+ g_dbus_method_invocation_return_value(invocation, ret);
4194+ g_free(query);
4195+ }
4196+ else if (g_strcmp0(method_name, "ExecuteQuery") == 0)
4197+ {
4198+ GVariant * key = NULL;
4199+ key = g_variant_get_child_value(parameters, 0);
4200+ g_dbus_method_invocation_return_value(invocation, NULL);
4201+ g_variant_unref(key);
4202+ }
4203+ else if (g_strcmp0(method_name, "CloseQuery") == 0)
4204+ {
4205+ GVariant * key = NULL;
4206+ key = g_variant_get_child_value(parameters, 0);
4207+ g_dbus_method_invocation_return_value(invocation, NULL);
4208+ g_variant_unref(key);
4209+ }
4210+
4211+ return;
4212+}
4213+
4214
4215=== added file 'tests/test_service_hud.h'
4216--- tests/test_service_hud.h 1970-01-01 00:00:00 +0000
4217+++ tests/test_service_hud.h 2012-02-06 11:00:29 +0000
4218@@ -0,0 +1,46 @@
4219+#ifndef _SERVICE_HUD_H_
4220+#define _SERVICE_HUD_H_
4221+
4222+#include <glib-object.h>
4223+G_BEGIN_DECLS
4224+
4225+#define SERVICE_TYPE_HUD (service_hud_get_type ())
4226+
4227+#define SERVICE_HUD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
4228+ SERVICE_TYPE_HUD, ServiceHud))
4229+
4230+#define SERVICE_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
4231+ SERVICE_TYPE_HUD, ServiceHudClass))
4232+
4233+#define SERVICE_IS_HUD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
4234+ SERVICE_TYPE_HUD))
4235+
4236+#define SERVICE_IS_HUD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
4237+ SERVICE_TYPE_HUD))
4238+
4239+#define ServiceHud_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
4240+ SERVICE_TYPE_HUD, ServiceHudClass))
4241+
4242+typedef struct _ServiceHud ServiceHud;
4243+typedef struct _ServiceHudClass ServiceHudClass;
4244+typedef struct _ServiceHudPrivate ServiceHudPrivate;
4245+
4246+struct _ServiceHud
4247+{
4248+ GObject parent;
4249+
4250+ ServiceHudPrivate *priv;
4251+};
4252+
4253+struct _ServiceHudClass
4254+{
4255+ GObjectClass parent_class;
4256+};
4257+
4258+GType service_hud_get_type(void) G_GNUC_CONST;
4259+
4260+ServiceHud* service_hud_new(void);
4261+
4262+G_END_DECLS
4263+
4264+#endif /* _SERVICE_HUD_H_ */
4265
4266=== modified file 'tests/test_service_main.c'
4267--- tests/test_service_main.c 2011-07-26 09:08:42 +0000
4268+++ tests/test_service_main.c 2012-02-06 11:00:29 +0000
4269@@ -2,6 +2,7 @@
4270
4271 #include "test_service_lens.h"
4272 #include "test_service_model.h"
4273+#include "test_service_hud.h"
4274
4275 static void on_bus_aquired(GDBusConnection* conn, const gchar* name, gpointer null);
4276 static void handle_method_call(GDBusConnection *connection,
4277@@ -34,6 +35,7 @@
4278 static GMainLoop* loop_ = NULL;
4279 static ServiceLens* lens_ = NULL;
4280 static ServiceModel* model_ = NULL;
4281+static ServiceHud* hud_ = NULL;
4282
4283 gint
4284 main(gint argc, gchar** argv)
4285@@ -44,6 +46,7 @@
4286
4287 lens_ = service_lens_new();
4288 model_ = service_model_new();
4289+ hud_ = service_hud_new();
4290
4291 g_bus_own_name(G_BUS_TYPE_SESSION,
4292 "com.canonical.Unity.Test",
4293@@ -57,8 +60,9 @@
4294 g_main_loop_run(loop_);
4295 g_main_loop_unref(loop_);
4296
4297- g_object_unref(lens_);
4298- g_object_unref(model_);
4299+ //g_object_unref(lens_);
4300+ //g_object_unref(model_);
4301+ g_object_unref(hud_);
4302 g_dbus_node_info_unref(introspection_data);
4303
4304 return 0;