diff options
| author | Didier Roche <didier.roche@canonical.com> | 2011-01-27 14:02:27 +0100 |
|---|---|---|
| committer | Didier Roche <didier.roche@canonical.com> | 2011-01-27 14:02:27 +0100 |
| commit | e14f00498a05617397e23fe346c4cccf6d152e18 (patch) | |
| tree | b24df34739f0619e5dba5ff7fe196e3ed12961c9 | |
| parent | 872e53d8a3f09b1a7f6f6e9e79fbcc941a0965cf (diff) | |
| parent | c25c21944e7390e0a775ab85e1e8acd8b268267b (diff) | |
Import upstream version 3.2.16upstream-3.2.16
(bzr r55.4.40)
62 files changed, 2842 insertions, 328 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b420e36f1..99a09174f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ subdirs (services tests tools doc) set (PROJECT_NAME "unity") set (UNITY_MAJOR 3) set (UNITY_MINOR 2) -set (UNITY_MICRO 14) +set (UNITY_MICRO 16) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "3.0") diff --git a/config.h.cmake b/config.h.cmake index b3103c5d4..c6d4d75db 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -2,6 +2,7 @@ #define CONFIG_H #cmakedefine PREFIXDIR "@PREFIXDIR@" +#cmakedefine DATADIR "@DATADIR@" #cmakedefine PKGDATADIR "@PKGDATADIR@" #cmakedefine LOCALE_DIR "@LOCALE_DIR@" #cmakedefine VERSION "@VERSION@" diff --git a/po/POTFILES.in b/po/POTFILES.in index 032d26aa8..822687432 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,7 +1,6 @@ -unity-private/launcher/application-controller.vala -unity-private/places/places-default-renderer-group.vala -unity-private/places/places-place-home-renderer.vala -unity-private/places/places-place-search-entry.vala -unity-private/places/places-trash-controller.vala -unity-private/places/places-volume-child-controller.vala - +src/BamfLauncherIcon.cpp +src/DeviceLauncherIcon.cpp +src/LauncherController.cpp +src/PlaceLauncherIcon.cpp +src/PlacesHomeView.cpp +src/TrashLauncherIcon.cpp diff --git a/po/unity.pot b/po/unity.pot index 1a702835b..279f8c526 100644 --- a/po/unity.pot +++ b/po/unity.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: ayatana-dev@lists.launchpad.net\n" -"POT-Creation-Date: 2011-01-19 10:31-0500\n" +"POT-Creation-Date: 2011-01-25 00:10-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/services/panel-service.c b/services/panel-service.c index 6b23d7331..ab97d5690 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -977,10 +977,25 @@ panel_service_show_entry (PanelService *self, priv->last_menu_button = 0; } - if (entry != NULL && GTK_IS_MENU (entry->menu)) + if (entry != NULL) { + if (GTK_IS_MENU (entry->menu)) + { + priv->last_menu = entry->menu; + } + else + { + /* For some reason, this entry doesn't have a menu. To simplify the + rest of the code and to keep scrubbing fluidly, we'll create a + stub menu for the duration of this scrub. */ + priv->last_menu = GTK_MENU (gtk_menu_new ()); + g_signal_connect (priv->last_menu, "deactivate", + G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (priv->last_menu, "destroy", + G_CALLBACK (gtk_widget_destroyed), &priv->last_menu); + } + priv->last_entry = entry; - priv->last_menu = entry->menu; priv->last_x = x; priv->last_y = y; priv->last_menu_button = button; diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp index ad037d588..c8865cc6e 100644 --- a/src/BamfLauncherIcon.cpp +++ b/src/BamfLauncherIcon.cpp @@ -25,6 +25,7 @@ #include "PluginAdapter.h" #include "FavoriteStore.h" +#include <glib/gi18n-lib.h> #include <gio/gdesktopappinfo.h> #include <libindicator/indicator-desktop-shortcuts.h> #include <core/core.h> @@ -645,7 +646,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () menu_item = dbusmenu_menuitem_new (); g_object_ref (menu_item); - dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Open New Window"); + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Open New Window")); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); @@ -661,7 +662,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () g_object_ref (menu_item); dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK); - dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Keep In Launcher"); + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Keep In Launcher")); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); @@ -683,7 +684,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () menu_item = dbusmenu_menuitem_new (); g_object_ref (menu_item); - dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Quit"); + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit")); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); diff --git a/src/DeviceLauncherIcon.cpp b/src/DeviceLauncherIcon.cpp new file mode 100644 index 000000000..4b31176e4 --- /dev/null +++ b/src/DeviceLauncherIcon.cpp @@ -0,0 +1,291 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "DeviceLauncherIcon.h" + +#include "ubus-server.h" +#include "UBusMessages.h" + +#include <glib/gi18n-lib.h> + +#define DEFAULT_ICON "drive-removable-media" + +DeviceLauncherIcon::DeviceLauncherIcon (Launcher *launcher, GVolume *volume) +: SimpleLauncherIcon(launcher), + _volume (volume) +{ + g_signal_connect (_volume, "removed", + G_CALLBACK (&DeviceLauncherIcon::OnRemoved), this); + + UpdateDeviceIcon (); + +} + +DeviceLauncherIcon::~DeviceLauncherIcon() +{ + +} + +void +DeviceLauncherIcon::UpdateDeviceIcon () +{ + { + gchar *name; + gchar *escape; + + name = g_volume_get_name (_volume); + escape = g_markup_escape_text (name, -1); + + SetTooltipText (escape); + + g_free (escape); + g_free (name); + } + + { + GIcon *icon; + + icon = g_volume_get_icon (_volume); + if (G_IS_THEMED_ICON (icon)) + { + const gchar * const *names; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); + + if (names) + SetIconName (names[0]); + else + SetIconName (DEFAULT_ICON); + } + else if (G_IS_FILE_ICON (icon)) + { + GFile *file; + + file = g_file_icon_get_file (G_FILE_ICON (icon)); + if (file) + { + gchar *path; + + path = g_file_get_path (file); + SetIconName (path); + + g_free (path); + } + else + SetIconName (DEFAULT_ICON); + } + else + { + SetIconName (DEFAULT_ICON); + } + + g_object_unref (icon); + } + + SetQuirk (QUIRK_VISIBLE, true); + SetQuirk (QUIRK_RUNNING, false); + SetIconType (TYPE_DEVICE); +} + +nux::Color +DeviceLauncherIcon::BackgroundColor () +{ + return nux::Color (0xFF333333); +} + +nux::Color +DeviceLauncherIcon::GlowColor () +{ + return nux::Color (0xFF333333); +} + +void +DeviceLauncherIcon::OnMouseClick (int button) +{ + SimpleLauncherIcon::OnMouseClick (button); + + if (button == 1) + { + Activate (); + } +} + +std::list<DbusmenuMenuitem *> +DeviceLauncherIcon::GetMenus () +{ + std::list<DbusmenuMenuitem *> result; + DbusmenuMenuitem *menu_item; + + menu_item = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Open")); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (&DeviceLauncherIcon::OnOpen), this); + result.push_back (menu_item); + + if (g_volume_can_eject (_volume)) + { + menu_item = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Eject")); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (&DeviceLauncherIcon::OnEject), this); + result.push_back (menu_item); + } + + return result; +} + +void +DeviceLauncherIcon::ShowMount (GMount *mount) +{ + gchar *name; + + name = g_volume_get_name (_volume); + if (G_IS_MOUNT (mount)) + { + GFile *root; + + root = g_mount_get_root (mount); + if (G_IS_FILE (root)) + { + gchar *uri; + GError *error = NULL; + + uri = g_file_get_uri (root); + + g_app_info_launch_default_for_uri (uri, NULL, &error); + if (error) + { + g_warning ("Cannot open volume '%s': Unable to show %s: %s", name, uri, error->message); + g_error_free (error); + } + + g_free (uri); + g_object_unref (root); + } + else + { + g_warning ("Cannot open volume '%s': Mount has no root", name); + } + } + else + { + g_warning ("Cannot open volume '%s': Mount-point is invalid", name); + } + + g_free (name); +} + +void +DeviceLauncherIcon::Activate () +{ + GMount *mount; + gchar *name; + + SetQuirk (QUIRK_STARTING, true); + + name = g_volume_get_name (_volume); + mount = g_volume_get_mount (_volume); + if (G_IS_MOUNT (mount)) + { + ShowMount (mount); + g_object_unref (mount); + } + else + { + g_volume_mount (_volume, + (GMountMountFlags)0, + NULL, + NULL, + (GAsyncReadyCallback)&DeviceLauncherIcon::OnMountReady, + this); + } + + g_free (name); +} + +void +DeviceLauncherIcon::OnMountReady (GObject *object, GAsyncResult *result, DeviceLauncherIcon *self) +{ + GError *error = NULL; + + if (g_volume_mount_finish (self->_volume, result, &error)) + { + GMount *mount; + + mount = g_volume_get_mount (self->_volume); + self->ShowMount (mount); + + g_object_unref (mount); + } + else + { + gchar *name; + + name = g_volume_get_name (self->_volume); + g_warning ("Cannot open volume '%s': %s", + name, + error ? error->message : "Mount operation failed"); + g_error_free (error); + } +} + +void +DeviceLauncherIcon::OnEjectReady (GObject *object, + GAsyncResult *result, + DeviceLauncherIcon *self) +{ + g_volume_eject_with_operation_finish (self->_volume, result, NULL); +} + +void +DeviceLauncherIcon::Eject () +{ + g_debug ("%s", G_STRLOC); + g_volume_eject_with_operation (_volume, + (GMountUnmountFlags)0, + NULL, + NULL, + (GAsyncReadyCallback)OnEjectReady, + this); + g_debug ("%s", G_STRLOC); +} + +void +DeviceLauncherIcon::OnOpen (DbusmenuMenuitem *item, int time, DeviceLauncherIcon *self) +{ + self->Activate (); +} + +void +DeviceLauncherIcon::OnEject (DbusmenuMenuitem *item, int time, DeviceLauncherIcon *self) +{ + g_debug ("%s", G_STRLOC); + self->Eject (); + g_debug ("%s", G_STRLOC); +} + +void +DeviceLauncherIcon::OnRemoved (GVolume *volume, DeviceLauncherIcon *self) +{ + self->Remove (); +} diff --git a/src/DeviceLauncherIcon.h b/src/DeviceLauncherIcon.h new file mode 100644 index 000000000..6c13e8a19 --- /dev/null +++ b/src/DeviceLauncherIcon.h @@ -0,0 +1,56 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _DEVICE_LAUNCHER_ICON_H__H +#define _DEVICE_LAUNCHER_ICON_H__H + +#include "SimpleLauncherIcon.h" + +#include <gio/gio.h> + +class DeviceLauncherIcon : public SimpleLauncherIcon +{ + +public: + DeviceLauncherIcon (Launcher *launcher, GVolume *volume); + ~DeviceLauncherIcon (); + + virtual nux::Color BackgroundColor (); + virtual nux::Color GlowColor (); + +protected: + void OnMouseClick (int button); + void UpdateDeviceIcon (); + std::list<DbusmenuMenuitem *> GetMenus (); + +private: + void Activate (); + void ShowMount (GMount *mount); + void Eject (); + static void OnOpen (DbusmenuMenuitem *item, int time, DeviceLauncherIcon *self); + static void OnEject (DbusmenuMenuitem *item, int time, DeviceLauncherIcon *self); + static void OnRemoved (GVolume *volume, DeviceLauncherIcon *self); + static void OnMountReady (GObject *object, GAsyncResult *result, DeviceLauncherIcon *self); + static void OnEjectReady (GObject *object, GAsyncResult *result, DeviceLauncherIcon *self); + +private: + GVolume *_volume; +}; + +#endif // _DEVICE_LAUNCHER_ICON_H__H diff --git a/src/DeviceLauncherSection.cpp b/src/DeviceLauncherSection.cpp new file mode 100644 index 000000000..110974a1b --- /dev/null +++ b/src/DeviceLauncherSection.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "DeviceLauncherIcon.h" + +#include "DeviceLauncherSection.h" + +DeviceLauncherSection::DeviceLauncherSection (Launcher *launcher) +: _launcher (launcher) +{ + _monitor = g_volume_monitor_get (); + g_signal_connect (_monitor, "volume-added", + G_CALLBACK (&DeviceLauncherSection::OnVolumeAdded), this); + + g_idle_add ((GSourceFunc)&DeviceLauncherSection::PopulateEntries, this); +} + +DeviceLauncherSection::~DeviceLauncherSection () +{ + g_object_unref (_monitor); +} + +bool +DeviceLauncherSection::PopulateEntries (DeviceLauncherSection *self) +{ + GList *volumes, *v; + + volumes = g_volume_monitor_get_volumes (self->_monitor); + for (v = volumes; v; v = v->next) + { + GVolume *volume = (GVolume *)v->data; + DeviceLauncherIcon *icon = new DeviceLauncherIcon (self->_launcher, volume); + + self->IconAdded.emit (icon); + + g_object_unref (volume); + } + + g_list_free (volumes); + + return false; +} + +void +DeviceLauncherSection::OnVolumeAdded (GVolumeMonitor *monitor, + GVolume *volume, + DeviceLauncherSection *self) +{ + DeviceLauncherIcon *icon = new DeviceLauncherIcon (self->_launcher, volume); + self->IconAdded.emit (icon); +} diff --git a/src/DeviceLauncherSection.h b/src/DeviceLauncherSection.h new file mode 100644 index 000000000..30b32318f --- /dev/null +++ b/src/DeviceLauncherSection.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _DEVICE_LAUNCHER_SECTION_H_ +#define _DEVICE_LAUNCHER_SECTION_H_ + +#include <sigc++/sigc++.h> +#include <sigc++/signal.h> + +#include "Launcher.h" +#include "LauncherIcon.h" + +#include <gio/gio.h> + +class DeviceLauncherSection : public sigc::trackable +{ +public: + DeviceLauncherSection (Launcher *launcher); + ~DeviceLauncherSection (); + + sigc::signal<void, LauncherIcon *> IconAdded; + +private: + static bool PopulateEntries (DeviceLauncherSection *self); + static void OnVolumeAdded (GVolumeMonitor *monitor, + GVolume *volume, + DeviceLauncherSection *self); + +public: + Launcher *_launcher; + GVolumeMonitor *_monitor; +}; + +#endif // _DEVICE_LAUNCHER_SECTION_H_ diff --git a/src/IconTexture.cpp b/src/IconTexture.cpp index e83e7278d..e8b1d4efc 100644 --- a/src/IconTexture.cpp +++ b/src/IconTexture.cpp @@ -112,7 +112,7 @@ IconTexture::Refresh () nux::TextureLayer* texture_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), texxform, // The Oject that defines the texture wraping and coordinate transformation. nux::Color::White, // The color used to modulate the texture. - false, // Write the alpha value of the texture to the destination buffer. + true, // Write the alpha value of the texture to the destination buffer. rop // Use the given raster operation to set the blending when the layer is being rendered. ); diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 3a5fabb70..165c1d517 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -39,6 +39,9 @@ #include "QuicklistManager.h" #include "QuicklistView.h" +#include "ubus-server.h" +#include "UBusMessages.h" + #define URGENT_BLINKS 3 #define WIGGLE_CYCLES 6 @@ -273,7 +276,8 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _hidden = false; _mouse_inside_launcher = false; _mouse_inside_trigger = false; - _force_show_launcher = false; + _key_show_launcher = false; + _placeview_show_launcher = false; _window_over_launcher = false; _render_drag_window = false; _backlight_always_on = false; @@ -296,6 +300,14 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _drag_window = NULL; _offscreen_drag_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (2, 2, 1, nux::BITFMT_R8G8B8A8); _offscreen_progress_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (2, 2, 1, nux::BITFMT_R8G8B8A8); + + UBusServer *ubus = ubus_server_get_default (); + ubus_server_register_interest (ubus, UBUS_PLACE_VIEW_SHOWN, + (UBusCallback)&Launcher::OnPlaceViewShown, + this); + ubus_server_register_interest (ubus, UBUS_PLACE_VIEW_HIDDEN, + (UBusCallback)&Launcher::OnPlaceViewHidden, + this); } Launcher::~Launcher() @@ -953,16 +965,38 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, /* End Render Layout Logic */ -void Launcher::ForceShowLauncherStart () +/* Launcher Show/Hide logic */ + +void Launcher::StartKeyShowLauncher () { - _force_show_launcher = true; + _key_show_launcher = true; EnsureHiddenState (); + // trigger the timer now as we want to hide the launcher immediately + // if we release the key after 1s happened. + SetupAutohideTimer (); } -void Launcher::ForceShowLauncherEnd () +void Launcher::EndKeyShowLauncher () { - _force_show_launcher = false; - SetupAutohideTimer (); + _key_show_launcher = false; + EnsureHiddenState (); +} + +void Launcher::OnPlaceViewShown (GVariant *data, void *val) +{ + Launcher *self = (Launcher*)val; + self->_placeview_show_launcher = true; + // trigger the timer now as we want to hide the launcher immediately + // if we close the dash after 1s happened. + self->EnsureHiddenState (); + self->SetupAutohideTimer (); +} + +void Launcher::OnPlaceViewHidden (GVariant *data, void *val) +{ + Launcher *self = (Launcher*)val; + self->_placeview_show_launcher = false; + self->EnsureHiddenState (); } void Launcher::SetHidden (bool hidden) @@ -982,8 +1016,8 @@ gboolean Launcher::OnAutohideTimeout (gpointer data) { Launcher *self = (Launcher*) data; - self->EnsureHiddenState (); self->_autohide_handle = 0; + self->EnsureHiddenState (); return false; } @@ -992,9 +1026,11 @@ Launcher::EnsureHiddenState () { if (!_mouse_inside_trigger && !_mouse_inside_launcher && - !_force_show_launcher && + !_key_show_launcher && + !_placeview_show_launcher && _launcher_action_state == ACTION_NONE && !QuicklistManager::Default ()->Current() && + !_autohide_handle && _window_over_launcher) SetHidden (true); else @@ -1012,7 +1048,7 @@ Launcher::CheckWindowOverLauncher () { CompWindow *window = *it; int intersect_types = CompWindowTypeNormalMask | CompWindowTypeDialogMask | - CompWindowTypeModalDialogMask; + CompWindowTypeModalDialogMask | CompWindowTypeUtilMask; if (!(window->type () & intersect_types) || !window->isMapped () || !window->isViewable ()) continue; @@ -1063,6 +1099,8 @@ bool Launcher::AutohideEnabled () return _autohide; } +/* End Launcher Show/Hide logic */ + gboolean Launcher::StrutHack (gpointer data) { Launcher *self = (Launcher *) data; diff --git a/src/Launcher.h b/src/Launcher.h index 0da4e5494..12f3a64f6 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -84,8 +84,8 @@ public: void SetAutohide (bool autohide, nux::View *show_trigger); bool AutohideEnabled (); - void ForceShowLauncherStart (); - void ForceShowLauncherEnd (); + void StartKeyShowLauncher (); + void EndKeyShowLauncher (); void SetBacklightAlwaysOn (bool always_on); bool GetBacklightAlwaysOn (); @@ -219,6 +219,9 @@ private: void OnOrderChanged (); void OnIconNeedsRedraw (LauncherIcon *icon); + + static void OnPlaceViewHidden (GVariant *data, void *val); + static void OnPlaceViewShown (GVariant *data, void *val); void RenderIndicators (nux::GraphicsEngine& GfxContext, RenderArg const &arg, @@ -271,7 +274,8 @@ private: bool _hidden; bool _mouse_inside_launcher; bool _mouse_inside_trigger; - bool _force_show_launcher; + bool _key_show_launcher; + bool _placeview_show_launcher; bool _window_over_launcher; bool _render_drag_window; bool _backlight_always_on; diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp index cca2802bd..cc0c34930 100644 --- a/src/LauncherController.cpp +++ b/src/LauncherController.cpp @@ -24,6 +24,7 @@ #include "PluginAdapter.h" #include "TrashLauncherIcon.h" +#include <glib/gi18n-lib.h> #include <Nux/Nux.h> #include <Nux/BaseWindow.h> @@ -39,10 +40,17 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n _launcher->SetModel (_model); _favorite_store = FavoriteStore::GetDefault (); - g_timeout_add (500, (GSourceFunc) &LauncherController::BamfTimerCallback, this); + _place_section = new PlaceLauncherSection (_launcher); + _place_section->IconAdded.connect (sigc::mem_fun (this, &LauncherController::OnIconAdded)); + + _device_section = new DeviceLauncherSection (_launcher); + _device_section->IconAdded.connect (sigc::mem_fun (this, &LauncherController::OnIconAdded)); + InsertExpoAction (); InsertTrash (); - + + g_timeout_add (500, (GSourceFunc) &LauncherController::BamfTimerCallback, this); + _launcher->request_reorder_smart.connect (sigc::mem_fun (this, &LauncherController::OnLauncherRequestReorderSmart)); _launcher->request_reorder_before.connect (sigc::mem_fun (this, &LauncherController::OnLauncherRequestReorderBefore)); } @@ -50,6 +58,8 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n LauncherController::~LauncherController() { _favorite_store->UnReference (); + delete _place_section; + delete _device_section; } void @@ -172,6 +182,12 @@ LauncherController::OnLauncherRequestReorderSmart (LauncherIcon *icon, LauncherI } void +LauncherController::OnIconAdded (LauncherIcon *icon) +{ + this->RegisterIcon (icon); +} + +void LauncherController::OnExpoClicked (int button) { if (button == 1) @@ -192,11 +208,11 @@ LauncherController::InsertExpoAction () SimpleLauncherIcon *expoIcon; expoIcon = new SimpleLauncherIcon (_launcher); - expoIcon->SetTooltipText ("Workspace Switcher"); + expoIcon->SetTooltipText (_("Workspace Switcher")); expoIcon->SetIconName ("workspace-switcher"); expoIcon->SetQuirk (LauncherIcon::QUIRK_VISIBLE, true); expoIcon->SetQuirk (LauncherIcon::QUIRK_RUNNING, false); - expoIcon->SetIconType (LauncherIcon::TYPE_END); + expoIcon->SetIconType (LauncherIcon::TYPE_EXPO); expoIcon->MouseClick.connect (sigc::mem_fun (this, &LauncherController::OnExpoClicked)); diff --git a/src/LauncherController.h b/src/LauncherController.h index c963246e9..fa500aa3e 100644 --- a/src/LauncherController.h +++ b/src/LauncherController.h @@ -29,7 +29,9 @@ #include "BamfLauncherIcon.h" #include "LauncherModel.h" +#include "DeviceLauncherSection.h" #include "FavoriteStore.h" +#include "PlaceLauncherSection.h" #include <libbamf/libbamf.h> #include <sigc++/sigc++.h> @@ -45,19 +47,22 @@ public: ~LauncherController(); private: - BamfMatcher* _matcher; - CompAction* _expo_action; - CompScreen* _screen; - Launcher* _launcher; - LauncherModel* _model; - nux::BaseWindow* _window; - FavoriteStore* _favorite_store; - int _sort_priority; + BamfMatcher* _matcher; + CompAction* _expo_action; + CompScreen* _screen; + Launcher* _launcher; + LauncherModel* _model; + nux::BaseWindow* _window; + FavoriteStore* _favorite_store; + int _sort_priority; + PlaceLauncherSection* _place_section; + DeviceLauncherSection* _device_section; void SortAndSave (); void OnLauncherRequestReorderSmart (LauncherIcon *icon, LauncherIcon *other, bool save); void OnLauncherRequestReorderBefore (LauncherIcon *icon, LauncherIcon *before, bool save); + void OnIconAdded (LauncherIcon *icon); void InsertExpoAction (); diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h index 989adb54a..0708fd62a 100644 --- a/src/LauncherIcon.h +++ b/src/LauncherIcon.h @@ -53,6 +53,7 @@ public: TYPE_BEGIN, TYPE_FAVORITE, TYPE_APPLICATION, + TYPE_EXPO, TYPE_PLACE, TYPE_DEVICE, TYPE_TRASH, diff --git a/src/PanelIndicatorObjectEntryView.h b/src/PanelIndicatorObjectEntryView.h index f4214ca30..4399eda19 100644 --- a/src/PanelIndicatorObjectEntryView.h +++ b/src/PanelIndicatorObjectEntryView.h @@ -30,7 +30,6 @@ #include "Introspectable.h" #define PANEL_HEIGHT 24 -//#define PADDING 6 #define SPACING 3 class PanelIndicatorObjectEntryView : public nux::TextureArea, public Introspectable diff --git a/src/PanelIndicatorObjectView.cpp b/src/PanelIndicatorObjectView.cpp index e8e3348ae..4f642028f 100644 --- a/src/PanelIndicatorObjectView.cpp +++ b/src/PanelIndicatorObjectView.cpp @@ -43,10 +43,14 @@ PanelIndicatorObjectView::PanelIndicatorObjectView (IndicatorObjectProxy *proxy) _proxy (proxy), _entries () { - printf ("IndicatorAdded: %s\n", _proxy->GetName ().c_str ()); + g_debug ("IndicatorAdded: %s", _proxy->GetName ().c_str ()); _layout = new nux::HLayout ("", NUX_TRACKER_LOCATION); SetCompositionLayout (_layout); + + // default in Nux is 32, we have some PanelIndicatorObjectEntryView which are smaller than that. + // so redefining the minimum value for them. + SetMinimumWidth (MINIMUM_INDICATOR_WIDTH); _proxy->OnEntryAdded.connect (sigc::mem_fun (this, &PanelIndicatorObjectView::OnEntryAdded)); _proxy->OnEntryMoved.connect (sigc::mem_fun (this, &PanelIndicatorObjectView::OnEntryMoved)); @@ -84,7 +88,7 @@ PanelIndicatorObjectView::OnEntryAdded (IndicatorObjectEntryProxy *proxy) { PanelIndicatorObjectEntryView *view = new PanelIndicatorObjectEntryView (proxy); _layout->AddView (view, 0, nux::eCenter, nux::eFull); - _layout->SetContentDistribution (nux::eStackLeft); + _layout->SetContentDistribution (nux::eStackRight); _entries.push_back (view); diff --git a/src/PanelIndicatorObjectView.h b/src/PanelIndicatorObjectView.h index 346b95a68..3ac2ccc6f 100644 --- a/src/PanelIndicatorObjectView.h +++ b/src/PanelIndicatorObjectView.h @@ -27,6 +27,8 @@ #include "Introspectable.h" +#define MINIMUM_INDICATOR_WIDTH 12 + class PanelIndicatorObjectView : public nux::View, public Introspectable { public: diff --git a/src/PanelMenuView.cpp b/src/PanelMenuView.cpp index 51d75fa0f..1e5637486 100644 --- a/src/PanelMenuView.cpp +++ b/src/PanelMenuView.cpp @@ -43,6 +43,10 @@ static void on_active_window_changed (BamfMatcher *matcher, BamfView *new_view, PanelMenuView *self); +static void on_name_changed (BamfView* bamf_view, + gchar* old_name, + gchar* new_name, + PanelMenuView* self); PanelMenuView::PanelMenuView (int padding) : _matcher (NULL), @@ -68,6 +72,8 @@ PanelMenuView::PanelMenuView (int padding) _layout = _menu_layout; _padding = padding; + _name_changed_callback_instance = NULL; + _name_changed_callback_id = 0; _window_buttons = new WindowButtons (); _window_buttons->NeedRedraw (); @@ -78,6 +84,7 @@ PanelMenuView::PanelMenuView (int padding) _panel_titlebar_grab_area = new PanelTitlebarGrabArea (); _panel_titlebar_grab_area->mouse_down.connect (sigc::mem_fun (this, &PanelMenuView::OnMaximizedGrab)); + _panel_titlebar_grab_area->mouse_doubleclick.connect (sigc::mem_fun (this, &PanelMenuView::OnRestoreClicked)); win_manager = WindowManager::Default (); @@ -117,7 +124,6 @@ void PanelMenuView::SetProxy (IndicatorObjectProxy *proxy) { _proxy = proxy; - printf ("IndicatorAdded: %s\n", _proxy->GetName ().c_str ()); _proxy->OnEntryAdded.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryAdded)); _proxy->OnEntryMoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryMoved)); @@ -575,11 +581,19 @@ PanelMenuView::AllMenusClosed () } void +PanelMenuView::OnNameChanged (gchar* new_name, gchar* old_name) +{ + Refresh (); + FullRedraw (); +} + +void PanelMenuView::OnActiveWindowChanged (BamfView *old_view, BamfView *new_view) { _is_maximized = false; + if (BAMF_IS_WINDOW (new_view)) { BamfWindow *window = BAMF_WINDOW (new_view); @@ -588,6 +602,18 @@ PanelMenuView::OnActiveWindowChanged (BamfView *old_view, if (_decor_map.find (xid) == _decor_map.end ()) _decor_map[xid] = true; + + // first see if we need to remove and old callback + if (_name_changed_callback_id != 0) + g_signal_handler_disconnect (_name_changed_callback_instance, + _name_changed_callback_id); + + // register callback for new view and store handler-id + _name_changed_callback_instance = G_OBJECT (new_view); + _name_changed_callback_id = g_signal_connect (_name_changed_callback_instance, + "name-changed", + (GCallback) on_name_changed, + this); } Refresh (); @@ -772,3 +798,12 @@ on_active_window_changed (BamfMatcher *matcher, { self->OnActiveWindowChanged (old_view, new_view); } + +static void +on_name_changed (BamfView* bamf_view, + gchar* old_name, + gchar* new_name, + PanelMenuView* self) +{ + self->OnNameChanged (new_name, old_name); +} diff --git a/src/PanelMenuView.h b/src/PanelMenuView.h index 56cad37c8..9bb743d90 100644 --- a/src/PanelMenuView.h +++ b/src/PanelMenuView.h @@ -65,6 +65,7 @@ public: void OnEntryRefreshed (PanelIndicatorObjectEntryView *view); void OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active); void OnActiveWindowChanged (BamfView *old_view, BamfView *new_view); + void OnNameChanged (gchar* new_name, gchar* old_name); void OnSpreadInitiate (std::list <guint32> &); void OnSpreadTerminate (std::list <guint32> &); @@ -111,5 +112,7 @@ private: std::map<guint32, bool> _decor_map; int _padding; + gpointer _name_changed_callback_instance; + gulong _name_changed_callback_id; }; #endif diff --git a/src/PanelTitlebarGrabAreaView.cpp b/src/PanelTitlebarGrabAreaView.cpp index 2ed79e01c..b76a16988 100644 --- a/src/PanelTitlebarGrabAreaView.cpp +++ b/src/PanelTitlebarGrabAreaView.cpp @@ -15,6 +15,7 @@ * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> + * Authored by: Didier Roche <didier.roche@canonical.com> */ #include "Nux/Nux.h" @@ -30,6 +31,8 @@ #include <glib.h> +#define DELTA_MOUSE_DOUBLE_CLICK 500000000 + enum { BUTTON_CLOSE=0, @@ -40,7 +43,16 @@ enum PanelTitlebarGrabArea::PanelTitlebarGrabArea () : InputArea (NUX_TRACKER_LOCATION) -{ +{ + // FIXME: the two following functions should be used instead of the insane trick with fixed value. But nux is broken + // right now and we need jay to focus on other things + /*InputArea::EnableDoubleClick (true); + InputArea::OnMouseDoubleClick.connect (sigc::mem_fun (this, &PanelTitlebarGrabArea::RecvMouseDoubleClick));*/ + InputArea::OnMouseClick.connect (sigc::mem_fun (this, &PanelTitlebarGrabArea::RecvMouseClick)); + _last_click_time.tv_sec = 0; + _last_click_time.tv_nsec = 0; + + // connect the *Click events before the *Down ones otherwise, weird race happens InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelTitlebarGrabArea::RecvMouseDown)); } @@ -49,6 +61,43 @@ PanelTitlebarGrabArea::~PanelTitlebarGrabArea () { } +void PanelTitlebarGrabArea::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + mouse_down.emit (x, y); +} + +void PanelTitlebarGrabArea::RecvMouseDoubleClick (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + mouse_doubleclick.emit (); +} + +// TODO: can be safely removed once OnMouseDoubleClick is fixed in nux +void PanelTitlebarGrabArea::RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + struct timespec event_time, delta; + clock_gettime(CLOCK_MONOTONIC, &event_time); + delta = time_diff (_last_click_time, event_time); + + if ((delta.tv_sec == 0) && (delta.tv_nsec < DELTA_MOUSE_DOUBLE_CLICK)) + RecvMouseDoubleClick (x, y, button_flags, key_flags); + + _last_click_time.tv_sec = event_time.tv_sec; + _last_click_time.tv_nsec = event_time.tv_nsec; +} + +struct timespec PanelTitlebarGrabArea::time_diff (struct timespec start, struct timespec end) +{ + struct timespec temp; + if ((end.tv_nsec - start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec-1; + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + return temp; +} + const gchar * PanelTitlebarGrabArea::GetName () { @@ -72,10 +121,3 @@ PanelTitlebarGrabArea::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); } - -void PanelTitlebarGrabArea::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) -{ - mouse_down.emit (x, y); -} - - diff --git a/src/PanelTitlebarGrabAreaView.h b/src/PanelTitlebarGrabAreaView.h index 184e5cd04..0dfd4555d 100644 --- a/src/PanelTitlebarGrabAreaView.h +++ b/src/PanelTitlebarGrabAreaView.h @@ -15,11 +15,16 @@ * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> + * Authored by: Didier Roche <didier.roche@canonical.com> */ #ifndef PANEL_TITLEBAR_GRAB_AREA_H #define PANEL_TITLEBAR_GRAB_AREA_H_H + +// TODO: remove once double click will work in nux +#include <time.h> + #include <Nux/View.h> #include "Introspectable.h" @@ -34,13 +39,20 @@ public: ~PanelTitlebarGrabArea (); sigc::signal <void, int, int> mouse_down; + sigc::signal <void> mouse_doubleclick; protected: + void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseDoubleClick (int x, int y, unsigned long button_flags, unsigned long key_flags); + // TODO: can be safely removed once OnMouseDoubleClick is fixed in nux + void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags); + struct timespec time_diff (struct timespec start, struct timespec end); + + struct timespec _last_click_time; + const gchar * GetName (); const gchar * GetChildsName (); void AddProperties (GVariantBuilder *builder); - - void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); }; #endif diff --git a/src/PlaceEntry.h b/src/PlaceEntry.h index df50cb8c6..5dfe74acf 100644 --- a/src/PlaceEntry.h +++ b/src/PlaceEntry.h @@ -28,6 +28,7 @@ class PlaceEntry : public sigc::trackable { public: + virtual const gchar * GetId () = 0; virtual const gchar * GetName () = 0; virtual const gchar * GetIcon () = 0; virtual const gchar * GetDescription () = 0; diff --git a/src/PlaceEntryRemote.cpp b/src/PlaceEntryRemote.cpp index 7448c2be6..43f034575 100644 --- a/src/PlaceEntryRemote.cpp +++ b/src/PlaceEntryRemote.cpp @@ -139,6 +139,12 @@ PlaceEntryRemote::InitFromKeyFile (GKeyFile *key_file, /* Overrides */ const gchar * +PlaceEntryRemote::GetId () +{ + return _dbus_path; +} + +const gchar * PlaceEntryRemote::GetName () { return _name; diff --git a/src/PlaceEntryRemote.h b/src/PlaceEntryRemote.h index 74aa6836e..b93104512 100644 --- a/src/PlaceEntryRemote.h +++ b/src/PlaceEntryRemote.h @@ -41,7 +41,8 @@ public: void InitFromKeyFile (GKeyFile *key_file, const gchar *group); /* Overrides */ - const gchar * GetName (); + const gchar * GetId (); + const gchar * GetName (); const gchar * GetIcon (); const gchar * GetDescription (); diff --git a/src/PlaceFactory.cpp b/src/PlaceFactory.cpp new file mode 100644 index 000000000..6ae877f97 --- /dev/null +++ b/src/PlaceFactory.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "PlaceFactory.h" +#include "PlaceFactoryFile.h" + +static PlaceFactory *default_factory = NULL; + +PlaceFactory * +PlaceFactory::GetDefault () +{ + if (!default_factory) + default_factory = new PlaceFactoryFile (); + + return default_factory; +} + +void +PlaceFactory::SetDefault (PlaceFactory *factory) +{ + if (default_factory) + delete default_factory; + + default_factory = factory; +} diff --git a/src/PlaceFactory.h b/src/PlaceFactory.h index cd6dd07c4..bdd609258 100644 --- a/src/PlaceFactory.h +++ b/src/PlaceFactory.h @@ -30,6 +30,11 @@ class PlaceFactory : public sigc::trackable { public: + static PlaceFactory * GetDefault (); + + // For testing + static void SetDefault (PlaceFactory *factory); + // This could be empty, if the loading of places is async, so you // should be listening to the signals too virtual std::vector<Place *>& GetPlaces () = 0; diff --git a/src/PlaceFactoryFile.cpp b/src/PlaceFactoryFile.cpp index d663f5ab5..fbd25d066 100644 --- a/src/PlaceFactoryFile.cpp +++ b/src/PlaceFactoryFile.cpp @@ -29,7 +29,7 @@ PlaceFactoryFile::PlaceFactoryFile (const char *directory) { /* Use the default lookup location */ if (directory == NULL) - _directory = g_build_filename (PKGDATADIR, "places", NULL); + _directory = g_build_filename (DATADIR, "unity", "places", NULL); else _directory = g_strdup (directory); diff --git a/src/PlaceLauncherIcon.cpp b/src/PlaceLauncherIcon.cpp new file mode 100644 index 000000000..7c9dd8620 --- /dev/null +++ b/src/PlaceLauncherIcon.cpp @@ -0,0 +1,113 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "PlaceLauncherIcon.h" + +#include "ubus-server.h" +#include "UBusMessages.h" + +#include <glib/gi18n-lib.h> + +PlaceLauncherIcon::PlaceLauncherIcon (Launcher *launcher, PlaceEntry *entry) +: SimpleLauncherIcon(launcher), + _entry (entry) +{ + gchar *escape; + + escape = g_markup_escape_text (entry->GetName (), -1); + + SetTooltipText (escape); + SetIconName (entry->GetIcon ()); + SetQuirk (QUIRK_VISIBLE, true); + SetQuirk (QUIRK_RUNNING, false); + SetIconType (TYPE_PLACE); + + g_free (escape); +} + +PlaceLauncherIcon::~PlaceLauncherIcon() +{ + +} + +nux::Color +PlaceLauncherIcon::BackgroundColor () +{ + return nux::Color (0xFF333333); +} + +nux::Color +PlaceLauncherIcon::GlowColor () +{ + return nux::Color (0xFF333333); +} + +void +PlaceLauncherIcon::OnMouseClick (int button) +{ + SimpleLauncherIcon::OnMouseClick (button); + + if (button == 1) + { + Activate (0, ""); + } +} + +void +PlaceLauncherIcon::UpdatePlaceIcon () +{ + +} + +std::list<DbusmenuMenuitem *> +PlaceLauncherIcon::GetMenus () +{ + std::list<DbusmenuMenuitem *> result; + DbusmenuMenuitem *menu_item; + + menu_item = dbusmenu_menuitem_new (); + + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Open")); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); + + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (&PlaceLauncherIcon::OnOpen), this); + + result.push_back (menu_item); + + return result; +} + +void +PlaceLauncherIcon::Activate (guint section_id, const char *search_string) +{ + ubus_server_send_message (ubus_server_get_default (), + UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, + g_variant_new ("(sus)", + _entry->GetId (), + section_id, + search_string)); +} + +void +PlaceLauncherIcon::OnOpen (DbusmenuMenuitem *item, int time, PlaceLauncherIcon *self) +{ + self->Activate (0, ""); +} diff --git a/src/PlaceLauncherIcon.h b/src/PlaceLauncherIcon.h new file mode 100644 index 000000000..f5f96ad50 --- /dev/null +++ b/src/PlaceLauncherIcon.h @@ -0,0 +1,51 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _PLACE_LAUNCHER_ICON_H__H +#define _PLACE_LAUNCHER_ICON_H__H + +#include "PlaceEntry.h" + +#include "SimpleLauncherIcon.h" + + +class PlaceLauncherIcon : public SimpleLauncherIcon +{ + +public: + PlaceLauncherIcon (Launcher *launcher, PlaceEntry *entry); + ~PlaceLauncherIcon (); + + virtual nux::Color BackgroundColor (); + virtual nux::Color GlowColor (); + +protected: + void OnMouseClick (int button); + void UpdatePlaceIcon (); + std::list<DbusmenuMenuitem *> GetMenus (); + +private: + void Activate (guint section_id, const char *search_string); + static void OnOpen (DbusmenuMenuitem *item, int time, PlaceLauncherIcon *self); + +private: + PlaceEntry *_entry; +}; + +#endif // _PLACE_LAUNCHER_ICON_H__H diff --git a/src/PlaceLauncherSection.cpp b/src/PlaceLauncherSection.cpp new file mode 100644 index 000000000..f4d6aefc2 --- /dev/null +++ b/src/PlaceLauncherSection.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "PlaceLauncherIcon.h" + +#include "PlaceLauncherSection.h" + +PlaceLauncherSection::PlaceLauncherSection (Launcher *launcher) +: _launcher (launcher) +{ + _factory = PlaceFactory::GetDefault (); + _factory->place_added.connect (sigc::mem_fun (this, &PlaceLauncherSection::OnPlaceAdded)); + + PopulateEntries (); +} + +PlaceLauncherSection::~PlaceLauncherSection () +{ + +} + +void +PlaceLauncherSection::OnPlaceAdded (Place *place) +{ + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; + + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); + PlaceLauncherIcon *icon = new PlaceLauncherIcon (_launcher, entry); + + IconAdded.emit (icon); + } +} + +void +PlaceLauncherSection::PopulateEntries () +{ + std::vector<Place *> places = _factory->GetPlaces (); + std::vector<Place *>::iterator it; + + for (it = places.begin (); it != places.end (); ++it) + { + Place *place = static_cast<Place *> (*it); + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; + + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); + PlaceLauncherIcon *icon = new PlaceLauncherIcon (_launcher, entry); + + IconAdded.emit (icon); + } + } +} + diff --git a/src/PlaceLauncherSection.h b/src/PlaceLauncherSection.h new file mode 100644 index 000000000..41b5116b2 --- /dev/null +++ b/src/PlaceLauncherSection.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _PLACE_LAUNCHER_SECTION_H_ +#define _PLACE_LAUNCHER_SECTION_H_ + +#include <sigc++/sigc++.h> +#include <sigc++/signal.h> + +#include "PlaceFactory.h" + +#include "Launcher.h" +#include "LauncherIcon.h" + + +class PlaceLauncherSection : public sigc::trackable +{ +public: + PlaceLauncherSection (Launcher *launcher); + ~PlaceLauncherSection (); + + sigc::signal<void, LauncherIcon *> IconAdded; + +private: + void PopulateEntries (); + void OnPlaceAdded (Place *place); + + Launcher *_launcher; + PlaceFactory *_factory; +}; + +#endif // _PLACE_LAUNCHER_SECTION_H_ diff --git a/src/PlacesController.cpp b/src/PlacesController.cpp index 28c7def89..42988caee 100644 --- a/src/PlacesController.cpp +++ b/src/PlacesController.cpp @@ -32,8 +32,8 @@ #include "PlacesController.h" PlacesController::PlacesController () +: _visible (false) { - // register interest with ubus so that we get activation messages UBusServer *ubus = ubus_server_get_default (); ubus_server_register_interest (ubus, UBUS_HOME_BUTTON_ACTIVATED, @@ -45,15 +45,24 @@ PlacesController::PlacesController () _factory = new PlaceFactoryFile (); - _window = new PlacesView (); - _window->Reference (); + _window_layout = new nux::HLayout (); + + _window = new nux::BaseWindow ("Dash"); + _window->SetBackgroundColor (nux::Color (0.0, 0.0, 0.0, 0.9)); + _window->SinkReference (); _window->SetConfigureNotifyCallback(&PlacesController::WindowConfigureCallback, this); _window->ShowWindow(false); - _window->EnableInputWindow(true); _window->InputWindowEnableStruts(false); _window->OnMouseDownOutsideArea.connect (sigc::mem_fun (this, &PlacesController::RecvMouseDownOutsideOfView)); + _view = new PlacesView (); + _window_layout->AddView(_view, 1); + _window_layout->SetContentDistribution(nux::eStackLeft); + _window_layout->SetVerticalExternalMargin(0); + _window_layout->SetHorizontalExternalMargin(0); + + _window->SetLayout (_window_layout); } PlacesController::~PlacesController () @@ -63,21 +72,41 @@ PlacesController::~PlacesController () void PlacesController::Show () { - // show called - _window->Show (); + if (_visible) + return; + + _window->ShowWindow (true, false); + _window->EnableInputWindow (true, 1); + _window->GrabPointer (); + _window->GrabKeyboard (); + _window->NeedRedraw (); + _window->CaptureMouseDownAnyWhereElse (true); + + _visible = true; + + ubus_server_send_message (ubus_server_get_default (), UBUS_PLACE_VIEW_SHOWN, NULL); } void PlacesController::Hide () { - _window->Hide (); + if (!_visible) + return; + + _window->CaptureMouseDownAnyWhereElse (false); + _window->ForceStopFocus (1, 1); + _window->UnGrabPointer (); + _window->UnGrabKeyboard (); + _window->EnableInputWindow (false); + _window->ShowWindow (false, false); + + _visible = false; + + ubus_server_send_message (ubus_server_get_default (), UBUS_PLACE_VIEW_HIDDEN, NULL); } void PlacesController::ToggleShowHide () { - if (_window->IsVisible ()) - Hide (); - else - Show (); + _visible ? Hide () : Show (); } /* Configure callback for the window */ diff --git a/src/PlacesController.h b/src/PlacesController.h index c185e9fb1..ecc602dc9 100644 --- a/src/PlacesController.h +++ b/src/PlacesController.h @@ -29,6 +29,8 @@ #include "PlacesView.h" #include "Introspectable.h" +#include <Nux/BaseWindow.h> + class PlacesController : public Introspectable { public: @@ -51,8 +53,11 @@ protected: void RecvMouseDownOutsideOfView (int x, int y, unsigned long button_flags, unsigned long key_flags); private: - PlacesView *_window; + nux::BaseWindow *_window; + nux::HLayout *_window_layout; + PlacesView *_view; PlaceFactoryFile *_factory; + bool _visible; }; #endif // PLACES_CONTROLLER_H diff --git a/src/PlacesGroup.cpp b/src/PlacesGroup.cpp new file mode 100644 index 000000000..76db84ade --- /dev/null +++ b/src/PlacesGroup.cpp @@ -0,0 +1,243 @@ +/* + * Copyright 2011 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License version 3, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the applicable version of the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of both the GNU Lesser General Public + * License version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include <sigc++/sigc++.h> + +#include <Nux/Nux.h> +#include <Nux/VLayout.h> +#include <Nux/HLayout.h> +#include <Nux/BaseWindow.h> +#include <NuxCore/Math/MathInc.h> + +#include "StaticCairoText.h" + +#include "Introspectable.h" + +#include <sigc++/trackable.h> +#include <sigc++/signal.h> +#include <sigc++/functors/ptr_fun.h> +#include <sigc++/functors/mem_fun.h> + +#include "PlacesGroup.h" +#include <glib.h> +#include <glib/gi18n-lib.h> + +PlacesGroup::PlacesGroup (NUX_FILE_LINE_DECL) : +View (NUX_FILE_LINE_PARAM) +{ + //~ OnMouseDown.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseDown)); + //~ OnMouseUp.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseUp)); + //~ OnMouseClick.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseClick)); + //~ OnMouseMove.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseMove)); + //~ OnMouseEnter.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseEnter)); + //~ OnMouseLeave.connect (sigc::mem_fun (this, &PlacesGroup::RecvMouseLeave)); + + _label = new nux::StaticCairoText ("", NUX_TRACKER_LOCATION); + _label->SinkReference (); + _label->SetFont ("Ubuntu normal 11"); + _label->SetTextEllipsize (nux::StaticCairoText::NUX_ELLIPSIZE_END); + _label->SetTextAlignment (nux::StaticCairoText::NUX_ALIGN_LEFT); + _label->SetMaximumWidth (320); + _label->SetMinimumWidth (1); + + _title = new nux::StaticCairoText ("", NUX_TRACKER_LOCATION); + _title->SinkReference (); + _title->SetFont ("Ubuntu normal 11"); + _title->SetTextEllipsize (nux::StaticCairoText::NUX_ELLIPSIZE_END); + _title->SetTextAlignment (nux::StaticCairoText::NUX_ALIGN_RIGHT); + _title->SetMaximumWidth (320); + _title->SetMinimumWidth (1); + + _header_layout = new nux::HLayout ("", NUX_TRACKER_LOCATION); + _header_layout->SinkReference (); + + _header_layout->AddView (_title, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL); + _header_layout->AddSpace (1, 1); + _header_layout->AddView (_label, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL); + + _group_layout = new nux::VLayout ("", NUX_TRACKER_LOCATION); + _group_layout->SinkReference (); + + _group_layout->AddLayout (_header_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FULL); + + _content = NULL; + _expanded = false; + _title_string = NULL; + _row_height = 0; + _total_items = 0; + _visible_items = 0; + + SetCompositionLayout (_group_layout); + +} + +PlacesGroup::~PlacesGroup () +{ + _label->UnReference (); + _title->UnReference (); + + g_free (_title_string); + + _group_layout->RemoveChildObject (_header_layout); + + if (_content != NULL) + { + _group_layout->RemoveChildObject (_content); + _content->UnReference (); + } + + _header_layout->UnReference (); + _group_layout->UnReference (); + +} + +void PlacesGroup::SetTitle (const char *title) +{ + _title_string = g_strdup (title); + UpdateTitle (); +} + +void PlacesGroup::SetEmblem (const char *path_to_emblem) +{ +} + +void PlacesGroup::SetLayout (nux::Layout *layout) +{ + _content = layout; + _content->Reference (); + + // By setting the stretch factor of the GridHLayout to 0, the height of the grid + // will be forced to the height that is necessary to include all its elements. + _group_layout->AddLayout (_content, 0); + + ComputeChildLayout (); + NeedRedraw (); +} + +nux::Layout * +PlacesGroup::GetLayout () +{ + return _content; +} + +void PlacesGroup::SetRowHeight (unsigned int row_height) +{ + _row_height = row_height; +} + +void PlacesGroup::SetItemDetail (unsigned int total_items, unsigned int visible_items) +{ + _total_items = total_items; + _visible_items = visible_items; + UpdateLabel (); +} + +void PlacesGroup::SetExpanded (bool expanded) +{ + if (_expanded == expanded) + return; + + _expanded = expanded; + UpdateLabel (); +} + +void +PlacesGroup::UpdateTitle () +{ + _title->SetText (_title_string); + ComputeChildLayout (); + NeedRedraw (); +} + +void +PlacesGroup::UpdateLabel () +{ + if (_expanded) + { + _label->SetText (_("See less results")); + } + else + { + char *result_string = NULL; + result_string = g_strdup_printf (g_dngettext(NULL, "See %s less results", + "See one less result", + _total_items - _visible_items)); + + _label->SetText (result_string); + g_free ((result_string)); + } + + ComputeChildLayout (); + NeedRedraw (); +} + + +long PlacesGroup::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) +{ + long ret = TraverseInfo; + ret = PostProcessEvent2 (ievent, ret, ProcessEventInfo); + return ret; +} + +void PlacesGroup::Draw (nux::GraphicsEngine& GfxContext, + bool forceDraw) +{ + // Check if the texture have been computed. If they haven't, exit the function. + nux::Geometry base = GetGeometry (); + nux::GetPainter ().PaintBackground (GfxContext, GetGeometry ()); + + + GfxContext.PushClippingRectangle (base); + + _group_layout->NeedRedraw (); + + GfxContext.PopClippingRectangle (); +} + +void +PlacesGroup::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + nux::Geometry base = GetGeometry (); + GfxContext.PushClippingRectangle (base); + + _group_layout->ProcessDraw (GfxContext, force_draw); + + GfxContext.PopClippingRectangle(); +} + +void +PlacesGroup::PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + +} + +void +PlacesGroup::PreLayoutManagement () +{ + nux::View::PreLayoutManagement (); +} + +long +PlacesGroup::PostLayoutManagement (long LayoutResult) +{ + return nux::View::PostLayoutManagement (LayoutResult); +} + diff --git a/src/PlacesGroup.h b/src/PlacesGroup.h new file mode 100644 index 000000000..c1481eaab --- /dev/null +++ b/src/PlacesGroup.h @@ -0,0 +1,94 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef PLACES_GROUP_H +#define PLACES_GROUP_H + +#include <sigc++/sigc++.h> + +#include <Nux/Nux.h> +#include <Nux/VLayout.h> +#include <Nux/BaseWindow.h> +#include <NuxCore/Math/MathInc.h> + +#include "StaticCairoText.h" + +#include "Introspectable.h" + +#include <sigc++/trackable.h> +#include <sigc++/signal.h> +#include <sigc++/functors/ptr_fun.h> +#include <sigc++/functors/mem_fun.h> + +class PlacesGroup : public nux::View +{ +public: + + PlacesGroup (NUX_FILE_LINE_PROTO); + ~PlacesGroup (); + + void SetTitle (const char *title); + void SetEmblem (const char *path_to_emblem); + + void SetLayout (nux::Layout *layout); + nux::Layout *GetLayout (); + void SetRowHeight (unsigned int row_height); + void SetItemDetail (unsigned int total_items, unsigned int visible_items); + void SetExpanded (bool expanded); + +protected: + nux::StaticCairoText *_label; + nux::StaticCairoText *_title; + + char *_title_string; + unsigned int _row_height; + unsigned int _total_items; + unsigned int _visible_items; + + nux::Layout *_content; + nux::VLayout *_group_layout; + nux::HLayout *_header_layout; + + bool _expanded; + void UpdateTitle (); + void UpdateLabel (); + + virtual long ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo); + virtual void Draw (nux::GraphicsEngine &GfxContext, bool force_draw); + virtual void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw); + virtual void PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw); + + virtual void PreLayoutManagement (); + virtual long PostLayoutManagement (long LayoutResult); + + void RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + + sigc::signal<void, PlacesGroup*> sigMouseEnter; + sigc::signal<void, PlacesGroup*> sigMouseLeave; + sigc::signal<void, PlacesGroup*, int, int> sigMouseReleased; + sigc::signal<void, PlacesGroup*, int, int> sigMouseClick; + sigc::signal<void, PlacesGroup*, int, int> sigMouseDrag; +}; + +#endif diff --git a/src/PlacesHomeView.cpp b/src/PlacesHomeView.cpp index b4b21f8cc..80c086dde 100644 --- a/src/PlacesHomeView.cpp +++ b/src/PlacesHomeView.cpp @@ -187,16 +187,19 @@ PlacesHomeView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proce void PlacesHomeView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::GetPainter().PaintBackground (GfxContext, GetGeometry() ); + UpdateBackground (); _bg_layer->SetGeometry (GetGeometry ()); - nux::GetPainter().RenderSinglePaintLayer (GfxContext, GetGeometry(), _bg_layer); + nux::GetPainter().PushDrawLayer (GfxContext, GetGeometry(), _bg_layer); + nux::GetPainter().PopBackground (); } void PlacesHomeView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) { + nux::GetPainter().PushLayer (GfxContext, GetGeometry(), _bg_layer); _layout->ProcessDraw (GfxContext, force_draw); + nux::GetPainter().PopBackground (); } void @@ -209,16 +212,71 @@ long PlacesHomeView::PostLayoutManagement (long LayoutResult) { // I'm imagining this is a good as time as any to update the background - UpdateBackground (); return nux::View::PostLayoutManagement (LayoutResult); } void +PlacesHomeView::DrawRoundedRectangle (cairo_t* cr, + double aspect, + double x, + double y, + double cornerRadius, + double width, + double height) +{ + double radius = cornerRadius / aspect; + + // top-left, right of the corner + cairo_move_to (cr, x + radius, y); + + // top-right, left of the corner + cairo_line_to (cr, x + width - radius, y); + + // top-right, below the corner + cairo_arc (cr, + x + width - radius, + y + radius, + radius, + -90.0f * G_PI / 180.0f, + 0.0f * G_PI / 180.0f); + + // bottom-right, above the corner + cairo_line_to (cr, x + width, y + height - radius); + + // bottom-right, left of the corner + cairo_arc (cr, + x + width - radius, + y + height - radius, + radius, + 0.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + + // bottom-left, right of the corner + cairo_line_to (cr, x + radius, y + height); + + // bottom-left, above the corner + cairo_arc (cr, + x + radius, + y + height - radius, + radius, + 90.0f * G_PI / 180.0f, + 180.0f * G_PI / 180.0f); + + // top-left, right of the corner + cairo_arc (cr, + x + radius, + y + radius, + radius, + 180.0f * G_PI / 180.0f, + 270.0f * G_PI / 180.0f); +} + +void PlacesHomeView::UpdateBackground () { #define PADDING 24 -#define RADIUS 12 +#define RADIUS 6 int x, y, width, height; nux::Geometry geo = GetGeometry (); @@ -229,8 +287,8 @@ PlacesHomeView::UpdateBackground () _last_height = geo.height; x = y = PADDING; - width = _last_width - (PADDING); - height = _last_height - (PADDING); + width = _last_width - (2*PADDING); + height = _last_height - (2*PADDING); nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, _last_width, _last_height); cairo_t *cr = cairo_graphics.GetContext(); @@ -240,14 +298,8 @@ PlacesHomeView::UpdateBackground () cairo_set_source_rgba (cr, 0.5f, 0.5f, 0.5f, 0.2f); - cairo_move_to (cr, x, y + RADIUS); - cairo_curve_to (cr, x, y, x, y, x + RADIUS, y); - cairo_line_to (cr, width - RADIUS, y); - cairo_curve_to (cr, width, y, width, y, width, y + RADIUS); - cairo_line_to (cr, width, height - RADIUS); - cairo_curve_to (cr, width, height, width, height, width - RADIUS, height); - cairo_line_to (cr, x + RADIUS, height); - cairo_curve_to (cr, x, height, x, height, x, height - RADIUS); + DrawRoundedRectangle (cr, 1.0f, x, y, RADIUS, width, height); + cairo_close_path (cr); cairo_fill_preserve (cr); diff --git a/src/PlacesHomeView.h b/src/PlacesHomeView.h index 86119f204..cd8b27b46 100644 --- a/src/PlacesHomeView.h +++ b/src/PlacesHomeView.h @@ -52,6 +52,13 @@ protected: private: void UpdateBackground (); + void DrawRoundedRectangle (cairo_t* cr, + double aspect, + double x, + double y, + double cornerRadius, + double width, + double height); private: nux::AbstractPaintLayer *_bg_layer; diff --git a/src/PlacesResultsController.cpp b/src/PlacesResultsController.cpp new file mode 100644 index 000000000..af54a5571 --- /dev/null +++ b/src/PlacesResultsController.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#include "config.h" + +#include "Nux/Nux.h" +#include "Nux/GridHLayout.h" + +#include "NuxGraphics/GLThread.h" +#include <glib.h> + +#include "ubus-server.h" +#include "UBusMessages.h" + +#include "PlacesResultsController.h" +#include "PlacesGroup.h" +#include "PlacesSimpleTile.h" + + +PlacesResultsController::PlacesResultsController () +{ + _results_view = NULL; +} + +PlacesResultsController::~PlacesResultsController () +{ + _results_view->UnReference (); +} + +void +PlacesResultsController::SetView (PlacesResultsView *view) +{ + if (_results_view != NULL) + _results_view->UnReference (); + + view->Reference (); + _results_view = view; +} + +PlacesResultsView * +PlacesResultsController::GetView () +{ + return _results_view; +} + +void +PlacesResultsController::AddResultToGroup (const char *groupname, + PlacesTile *tile, + const char *_id) +{ + std::string *group_name = new std::string (groupname); + std::string *id = new std::string (_id); + + PlacesGroup *group = NULL; + + if (_groups.find (*group_name) == _groups.end ()) + { + group = CreateGroup (groupname); + } + else + { + group = _groups[*group_name]; + } + + group->GetLayout ()->AddView (tile, 1, nux::eLeft, nux::eFull); + _tiles[*id] = tile; + _tile_group_relations[*id] = *(new std::string (groupname)); + + // Should also catch the onclick signal here on each tile, + // so we can activate or do whatever it is we need to do + + delete group_name; + delete id; +} + +void +PlacesResultsController::RemoveResultFromGroup (const char *groupname, + const char *_id) +{ + std::string *group_name = new std::string (groupname); + std::string *id = new std::string (_id); + + PlacesTile *tile = _tiles[*id]; + PlacesGroup *group = _groups[*group_name]; + + group->GetLayout ()->RemoveChildObject (tile); + + if (group->GetLayout ()->GetChildren ().empty ()) + { + _results_view->RemoveGroup (group); + _groups.erase (*group_name); + group->UnReference (); + } + + _tiles.erase (*id); + + _tile_group_relations.erase (*id); + + delete group_name; + delete id; +} + +void +PlacesResultsController::RemoveResult (const char *_id) +{ + std::string *id = new std::string (_id); + RemoveResultFromGroup (_tile_group_relations [*id].c_str (), _id); + delete id; +} + + + +PlacesGroup * +PlacesResultsController::CreateGroup (const char *groupname) +{ + g_debug ("making a group for %s", groupname); + std::string *group_name = new std::string (groupname); + + PlacesGroup *newgroup = new PlacesGroup (NUX_TRACKER_LOCATION); + newgroup->SinkReference (); + newgroup->SetTitle (groupname); + newgroup->SetRowHeight (92); + newgroup->SetItemDetail (1, 100); + newgroup->SetExpanded (true); + + nux::GridHLayout *layout = new nux::GridHLayout (NUX_TRACKER_LOCATION); + layout->ForceChildrenSize (true); + layout->SetChildrenSize (140, 90); + layout->EnablePartialVisibility (false); + + layout->SetVerticalExternalMargin (4); + layout->SetHorizontalExternalMargin (4); + layout->SetVerticalInternalMargin (4); + layout->SetHorizontalInternalMargin (4); + + newgroup->SetLayout (layout); + + _groups[*group_name] = newgroup; + _results_view->AddGroup (newgroup); + + delete group_name; + + return newgroup; +} + + +/* Introspection */ +const gchar * +PlacesResultsController::GetName () +{ + return "PlacesResultsController"; +} + +void +PlacesResultsController::AddProperties (GVariantBuilder *builder) +{ +} + + + + + + + + diff --git a/src/PlacesResultsController.h b/src/PlacesResultsController.h new file mode 100644 index 000000000..3b297765e --- /dev/null +++ b/src/PlacesResultsController.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef PLACES_RESULTS_CONTROLLER_H +#define PLACES_RESULTS_CONTROLLER_H + +#include <Nux/TextureArea.h> +#include <Nux/View.h> +#include "Nux/Layout.h" +#include <NuxImage/CairoGraphics.h> +#include <NuxGraphics/GraphicsEngine.h> + +#include "PlacesResultsView.h" +#include "PlacesTile.h" +#include "Introspectable.h" + +class PlacesResultsController : public nux::Object, public Introspectable +{ +public: + PlacesResultsController (); + ~PlacesResultsController (); + + void SetView (PlacesResultsView *_results_view); + PlacesResultsView *GetView (); + + + void AddResultToGroup (const char *groupname, + PlacesTile *tile, + const char *id); + void RemoveResult (const char *id); + void RemoveResultFromGroup (const char *groupname, + const char *_id); + +protected: + PlacesGroup *CreateGroup (const char *groupname); + const gchar* GetName (); + void AddProperties (GVariantBuilder *builder); + +private: + PlacesResultsView *_results_view; + std::map<std::string, PlacesGroup *> _groups; + std::map<std::string, PlacesTile *> _tiles; + std::map<std::string, std::string> _tile_group_relations; + +}; + +#endif // PLACES_RESULTS_CONTROLLER_H diff --git a/src/PlacesResultsView.cpp b/src/PlacesResultsView.cpp new file mode 100644 index 000000000..6aaef6c54 --- /dev/null +++ b/src/PlacesResultsView.cpp @@ -0,0 +1,195 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#include "Nux/Nux.h" +#include "Nux/Layout.h" +#include "Nux/WindowCompositor.h" +#include "Nux/VScrollBar.h" +#include "Nux/HScrollBar.h" +#include "Nux/Panel.h" +#include "PlacesGroup.h" +#include "PlacesResultsView.h" + +PlacesResultsView::PlacesResultsView (NUX_FILE_LINE_DECL) + : ScrollView (NUX_FILE_LINE_PARAM) +{ + m_horizontal_scrollbar_enable = false; + m_vertical_scrollbar_enable = true; + _layout = new nux::VLayout ("", NUX_TRACKER_LOCATION); + _layout->SinkReference (); + + _layout->SetContentDistribution(nux::MAJOR_POSITION_TOP); + + setBorder (12); + EnableVerticalScrollBar (true); + + SetCompositionLayout (_layout); +} + +PlacesResultsView::~PlacesResultsView () +{ + _layout->Clear (); + _layout->UnReference (); +} + +void +PlacesResultsView::Draw (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + GfxContext.PushClippingRectangle (GetGeometry() ); + + nux::Geometry base = GetGeometry(); + + if (_layout) + _layout->NeedRedraw(); + + nux::GetPainter().PaintBackground (GfxContext, base); + + if (m_vertical_scrollbar_enable) + { + vscrollbar->NeedRedraw(); + } + + GfxContext.PopClippingRectangle(); +} + +void +PlacesResultsView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + GfxContext.PushClippingRectangle (GetGeometry() ); + + GfxContext.PushClippingRectangle (nux::Rect (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight) ); + + if (_layout) + { + GfxContext.PushClippingRectangle (_layout->GetGeometry() ); + _layout->ProcessDraw (GfxContext, force_draw); + GfxContext.PopClippingRectangle(); + } + + GfxContext.PopClippingRectangle(); + + if (m_vertical_scrollbar_enable) + { + vscrollbar->ProcessDraw (GfxContext, force_draw); + } + + GfxContext.PopClippingRectangle(); +} + +void +PlacesResultsView::AddGroup (PlacesGroup *group) +{ + _layout->AddView (group, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + ComputeChildLayout (); +} + +void +PlacesResultsView::RemoveGroup (PlacesGroup *group) +{ + _layout->RemoveChildObject (group); + ComputeChildLayout (); +} + +void +PlacesResultsView::PositionChildLayout (float offsetX, float offsetY) +{ + ScrollView::PositionChildLayout (offsetX, offsetY); +} + + +void PlacesResultsView::PreLayoutManagement() +{ + ScrollView::PreLayoutManagement(); +} + +long PlacesResultsView::PostLayoutManagement (long LayoutResult) +{ + long result = ScrollView::PostLayoutManagement (LayoutResult); + return result; +} + +long PlacesResultsView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) +{ + long ret = TraverseInfo; + long ProcEvInfo = 0; + + if (ievent.e_event == nux::NUX_MOUSE_PRESSED) + { + if (!m_Geometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) ) + { + ProcEvInfo = nux::eDoNotProcess; + //return TraverseInfo; + } + } + + if (m_vertical_scrollbar_enable) + ret = vscrollbar->ProcessEvent (ievent, ret, ProcEvInfo); + + // The child layout get the Mouse down button only if the MouseDown happened inside the client view Area + nux::Geometry viewGeometry = nux::Geometry (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight); + bool traverse = true; + + if (ievent.e_event == nux::NUX_MOUSE_PRESSED) + { + if (!viewGeometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) ) + { + ProcEvInfo = nux::eDoNotProcess; + traverse = false; + } + } + + if (_layout) + ret = _layout->ProcessEvent (ievent, ret, ProcEvInfo); + + ret = PostProcessEvent2 (ievent, ret, 0); + return ret; +} + +void PlacesResultsView::PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + +} + + + +void +PlacesResultsView::ScrollLeft (float stepx, int mousedx) +{ +} + +void +PlacesResultsView::ScrollRight (float stepx, int mousedx) +{ +} + +void +PlacesResultsView::ScrollUp (float stepy, int mousedy) +{ + ScrollView::ScrollUp (stepy, mousedy); + ComputeChildLayout(); + NeedRedraw(); +} + +void +PlacesResultsView::ScrollDown (float stepy, int mousedy) +{ + ScrollView::ScrollDown (stepy, mousedy); + ComputeChildLayout(); + NeedRedraw(); +} diff --git a/src/PlacesResultsView.h b/src/PlacesResultsView.h new file mode 100644 index 000000000..1f22f7c83 --- /dev/null +++ b/src/PlacesResultsView.h @@ -0,0 +1,74 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef PLACES_RESULTS_VIEW_H +#define PLACES_RESULTS_VIEW_H + +#include <sigc++/sigc++.h> + +#include <Nux/Nux.h> +#include <Nux/VLayout.h> +#include <Nux/ScrollView.h> +#include <Nux/BaseWindow.h> +#include <NuxCore/Math/MathInc.h> + +#include "PlacesGroup.h" +#include "Introspectable.h" + +#include <sigc++/trackable.h> +#include <sigc++/signal.h> +#include <sigc++/functors/ptr_fun.h> +#include <sigc++/functors/mem_fun.h> + +class PlacesResultsView : public nux::ScrollView +{ +public: + PlacesResultsView (NUX_FILE_LINE_PROTO); + ~PlacesResultsView (); + + sigc::signal<void, char *> sigClick; // returns ID of item clicked + sigc::signal<void> sigToggled; + sigc::signal<void, bool> sigStateChanged; + + void AddGroup (PlacesGroup *group); + void RemoveGroup (PlacesGroup *group); + +protected: + virtual void ScrollLeft (float stepx, int mousedx); + virtual void ScrollRight (float stepx, int mousedx); + virtual void ScrollUp (float stepy, int mousedy); + virtual void ScrollDown (float stepy, int mousedy); + +private: + nux::Layout *_layout; + +protected: + + virtual long ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo); + virtual void Draw (nux::GraphicsEngine &GfxContext, bool force_draw); + virtual void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw); + virtual void PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw); + + virtual void PreLayoutManagement (); + virtual long PostLayoutManagement (long LayoutResult); + virtual void PositionChildLayout (float offsetX, float offsetY); + +}; + +#endif // PLACE_RESULTS_VIEW_H diff --git a/src/PlacesSearchBar.cpp b/src/PlacesSearchBar.cpp index 9f158d91c..e9c52c443 100644 --- a/src/PlacesSearchBar.cpp +++ b/src/PlacesSearchBar.cpp @@ -30,6 +30,7 @@ #include <NuxGraphics/RenderingPipe.h> #include <glib.h> +#include <glib/gi18n-lib.h> #include "PlacesSearchBar.h" @@ -42,15 +43,22 @@ PlacesSearchBar::PlacesSearchBar (NUX_FILE_LINE_DECL) _layout = new nux::HLayout (NUX_TRACKER_LOCATION); - _entry = new nux::EditTextBox("Search", NUX_TRACKER_LOCATION); - _entry->SetMinMaxSize (200, 30); - _layout->AddView (_entry, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + _pango_entry = new nux::TextEntry (_("Search"), NUX_TRACKER_LOCATION); + _pango_entry->SetMinimumWidth (200); + // _entry->SetMinimumHeight (30); + //_entry->SetTextBackgroundColor (nux::Color (0xFF000000)); + + _layout->AddView (_pango_entry, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + _layout->SetVerticalExternalMargin (14); + _layout->SetHorizontalExternalMargin (18); + SetCompositionLayout (_layout); } PlacesSearchBar::~PlacesSearchBar () { - delete _bg_layer; + if (_bg_layer) + delete _bg_layer; } const gchar* PlacesSearchBar::GetName () @@ -77,8 +85,6 @@ void PlacesSearchBar::AddProperties (GVariantBuilder *builder) long PlacesSearchBar::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) { - nux::Geometry geo = GetGeometry (); - long ret = TraverseInfo; ret = _layout->ProcessEvent (ievent, ret, ProcessEventInfo); @@ -88,6 +94,8 @@ PlacesSearchBar::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proc void PlacesSearchBar::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) { + UpdateBackground (); + GfxContext.PushClippingRectangle (GetGeometry() ); gPainter.PushDrawLayer (GfxContext, GetGeometry (), _bg_layer); @@ -120,33 +128,99 @@ long PlacesSearchBar::PostLayoutManagement (long LayoutResult) { // I'm imagining this is a good as time as any to update the background - UpdateBackground (); return nux::View::PostLayoutManagement (LayoutResult); } +static void +draw_rounded_rect (cairo_t* cr, + double aspect, + double x, + double y, + double cornerRadius, + double width, + double height) +{ + double radius = cornerRadius / aspect; + + // top-left, right of the corner + cairo_move_to (cr, x + radius, y); + + // top-right, left of the corner + cairo_line_to (cr, x + width - radius, y); + + // top-right, below the corner + cairo_arc (cr, + x + width - radius, + y + radius, + radius, + -90.0f * G_PI / 180.0f, + 0.0f * G_PI / 180.0f); + + // bottom-right, above the corner + cairo_line_to (cr, x + width, y + height - radius); + + // bottom-right, left of the corner + cairo_arc (cr, + x + width - radius, + y + height - radius, + radius, + 0.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + + // bottom-left, right of the corner + cairo_line_to (cr, x + radius, y + height); + + // bottom-left, above the corner + cairo_arc (cr, + x + radius, + y + height - radius, + radius, + 90.0f * G_PI / 180.0f, + 180.0f * G_PI / 180.0f); + + // top-left, right of the corner + cairo_arc (cr, + x + radius, + y + radius, + radius, + 180.0f * G_PI / 180.0f, + 270.0f * G_PI / 180.0f); +} + void PlacesSearchBar::UpdateBackground () { +#define PADDING 8 +#define RADIUS 6 + int x, y, width, height; nux::Geometry geo = GetGeometry (); if (geo.width == _last_width && geo.height == _last_height) return; - + _last_width = geo.width; _last_height = geo.height; + x = y = PADDING; + width = _last_width - (2*PADDING); + height = _last_height - (2*PADDING); + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, _last_width, _last_height); cairo_t *cr = cairo_graphics.GetContext(); - cairo_set_line_width (cr, 1); + cairo_translate (cr, 0.5, 0.5); + cairo_set_line_width (cr, 1.0); + + cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); + + draw_rounded_rect (cr, 1.0f, x, y, RADIUS, width, height); + + cairo_close_path (cr); + + cairo_fill_preserve (cr); - cairo_pattern_t *pat = cairo_pattern_create_linear (0, 0, 0, _last_height); - cairo_pattern_add_color_stop_rgb (pat, 0.0f, 89/255.0f, 88/255.0f, 83/255.0f); - cairo_pattern_add_color_stop_rgb (pat, 1.0f, 50/255.0f, 50/255.0f, 45/255.0f); - cairo_set_source (cr, pat); - cairo_rectangle (cr, 0, 0, _last_width, _last_height); - cairo_fill (cr); - cairo_pattern_destroy (pat); + cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 0.8f); + cairo_stroke (cr); cairo_destroy (cr); @@ -170,7 +244,7 @@ PlacesSearchBar::UpdateBackground () _bg_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), texxform, // The Oject that defines the texture wraping and coordinate transformation. nux::Color::White, // The color used to modulate the texture. - true, // Write the alpha value of the texture to the destination buffer. + false, // Write the alpha value of the texture to the destination buffer. rop // Use the given raster operation to set the blending when the layer is being rendered. ); diff --git a/src/PlacesSearchBar.h b/src/PlacesSearchBar.h index a9d8c61e8..c90958407 100644 --- a/src/PlacesSearchBar.h +++ b/src/PlacesSearchBar.h @@ -27,6 +27,7 @@ #include "Introspectable.h" #include "Nux/EditTextBox.h" +#include "Nux/TextEntry.h" class PlacesSearchBar : public Introspectable, public nux::View { @@ -55,6 +56,7 @@ private: nux::AbstractPaintLayer *_bg_layer; nux::HLayout *_layout; nux::EditTextBox *_entry; + nux::TextEntry *_pango_entry; int _last_width; int _last_height; }; diff --git a/src/PlacesSimpleTile.cpp b/src/PlacesSimpleTile.cpp index b2a235c8e..8f1671e03 100644 --- a/src/PlacesSimpleTile.cpp +++ b/src/PlacesSimpleTile.cpp @@ -44,7 +44,6 @@ PlacesTile (NUX_TRACKER_LOCATION) _cairotext->SetMaximumWidth (140); _layout->AddLayout (new nux::SpaceLayout (0, 0, 12, 12)); - _layout->SinkReference (); _layout->AddView (_icontex, 0, nux::eCenter, nux::eFull); _layout->AddSpace (6, 0); _layout->AddView (_cairotext, 0, nux::eCenter, nux::eFull); @@ -57,6 +56,8 @@ PlacesTile (NUX_TRACKER_LOCATION) _cairotext->GetTextExtents (textwidth, textheight); AddChild (_icontex); + + SetCompositionLayout (_layout); } @@ -64,7 +65,7 @@ PlacesSimpleTile::~PlacesSimpleTile () { _icontex->UnReference (); _cairotext->UnReference (); - _layout->UnReference (); + g_free ((void *)_label); g_free ((void *)_icon); } diff --git a/src/PlacesTile.cpp b/src/PlacesTile.cpp index 6d9703955..860596691 100644 --- a/src/PlacesTile.cpp +++ b/src/PlacesTile.cpp @@ -22,7 +22,11 @@ #include "Nux/Nux.h" #include "PlacesTile.h" PlacesTile::PlacesTile (NUX_FILE_LINE_DECL) : -View (NUX_FILE_LINE_PARAM) +View (NUX_FILE_LINE_PARAM), +_hilight_background (NULL), +_hilight_layer (NULL), +_last_width (0), +_last_height (0) { _state = STATE_DEFAULT; @@ -45,6 +49,12 @@ PlacesTile::UpdateBackground () { nux::Geometry base = GetGeometry (); + if ((base.width == _last_width) && (base.height == _last_height)) + return; + + _last_width = base.width; + _last_height = base.height; + nux::CairoGraphics *cairo_graphics = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, base.width, base.height); cairo_t *cr = cairo_graphics->GetContext(); @@ -62,8 +72,34 @@ PlacesTile::UpdateBackground () cairo_set_line_width (cr, 1.0); cairo_stroke (cr); + cairo_destroy (cr); + + nux::NBitmapData* bitmap = cairo_graphics->GetBitmap(); + + if (_hilight_background) + _hilight_background->UnReference (); + _hilight_background = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); - _hilight_background->Update (cairo_graphics->GetBitmap ()); + _hilight_background->Update (bitmap); + delete bitmap; + + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + nux::TexCoordXForm texxform; + texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); + texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + + if (_hilight_layer) + delete _hilight_layer; + + _hilight_layer = new nux::TextureLayer (_hilight_background->GetDeviceTexture(), + texxform, + nux::Color::White, + true, + rop); delete cairo_graphics; } @@ -144,16 +180,19 @@ long PlacesTile::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proc void PlacesTile::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) { + UpdateBackground (); + // Check if the texture have been computed. If they haven't, exit the function. - nux::Geometry base = _hilight_view->GetGeometry (); + nux::Geometry base = GetGeometry (); + gfxContext.PushClippingRectangle (base); + nux::GetPainter ().PaintBackground (gfxContext, GetGeometry ()); // FIXME: Disabled due to nux issue - if (_state == STATE_HOVER && false) + if (_state == STATE_HOVER) { nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture; - gfxContext.PushClippingRectangle (base); nux::TexCoordXForm texxform; texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); @@ -174,16 +213,23 @@ void PlacesTile::Draw (nux::GraphicsEngine& gfxContext, nux::Color::White); gfxContext.GetRenderStates().SetBlend (false); - - gfxContext.PopClippingRectangle (); } + + gfxContext.PopClippingRectangle (); } void PlacesTile::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) { + UpdateBackground (); GfxContext.PushClippingRectangle (GetGeometry() ); + if (_state == STATE_HOVER) + nux::GetPainter ().PushLayer (GfxContext, GetGeometry (), _hilight_layer); + _layout->ProcessDraw (GfxContext, force_draw); + + if (_state == STATE_HOVER) + nux::GetPainter ().PopBackground (); GfxContext.PopClippingRectangle(); } @@ -196,14 +242,12 @@ void PlacesTile::PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw) void PlacesTile::PreLayoutManagement () { - UpdateBackground (); nux::View::PreLayoutManagement (); } long PlacesTile::PostLayoutManagement (long LayoutResult) { - UpdateBackground (); return nux::View::PostLayoutManagement (LayoutResult); } diff --git a/src/PlacesTile.h b/src/PlacesTile.h index 634b11987..5e416ebdb 100644 --- a/src/PlacesTile.h +++ b/src/PlacesTile.h @@ -93,6 +93,7 @@ protected: nux::Layout *_layout; nux::BaseTexture *_hilight_background; nux::View *_hilight_view; + nux::TextureLayer *_hilight_layer; void UpdateBackground (); void DrawRoundedRectangle (cairo_t* cr, @@ -103,6 +104,9 @@ protected: double width, double height); +private: + int _last_width; + int _last_height; }; #endif // PLACE_TILE_H diff --git a/src/PlacesView.cpp b/src/PlacesView.cpp index 178762c7f..cd3311071 100644 --- a/src/PlacesView.cpp +++ b/src/PlacesView.cpp @@ -22,29 +22,37 @@ #include "NuxGraphics/GLThread.h" #include "UBusMessages.h" +#include "ubus-server.h" +#include "UBusMessages.h" + +#include "PlaceFactory.h" + #include "PlacesView.h" +static void place_entry_activate_request (GVariant *payload, PlacesView *self); + NUX_IMPLEMENT_OBJECT_TYPE (PlacesView); PlacesView::PlacesView (NUX_FILE_LINE_DECL) -: nux::BaseWindow("", NUX_FILE_LINE_PARAM) +: nux::View (NUX_TRACKER_LOCATION) { - Hide (); - _layout = new nux::VLayout (NUX_TRACKER_LOCATION); - - /* FIXME: Not needed this week + _search_bar = new PlacesSearchBar (); - _search_bar->SetMinMaxSize (1024, 48); _layout->AddView (_search_bar, 0, nux::eCenter, nux::eFull); AddChild (_search_bar); - */ _home_view = new PlacesHomeView (); _layout->AddView (_home_view, 1, nux::eCenter, nux::eFull); AddChild (_home_view); - SetLayout (_layout); + SetCompositionLayout (_layout); + + // Register for all the events + UBusServer *ubus = ubus_server_get_default (); + ubus_server_register_interest (ubus, UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, + (UBusCallback)place_entry_activate_request, + this); } PlacesView::~PlacesView () @@ -52,116 +60,77 @@ PlacesView::~PlacesView () } -long PlacesView::ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) +long +PlacesView::ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) { long ret = TraverseInfo; - - nux::IEvent window_event = ievent; - nux::Geometry base = GetGeometry(); - window_event.e_x_root = base.x; - window_event.e_y_root = base.y; - - // The child layout get the Mouse down button only if the MouseDown happened inside the client view Area - nux::Geometry viewGeometry = GetGeometry(); - - if (ievent.e_event == nux::NUX_MOUSE_PRESSED) - { - if (!viewGeometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root)) - { - //ProcEvInfo = nux::eDoNotProcess; - } - } - - // hide if outside our window - if (ievent.e_event == nux::NUX_MOUSE_PRESSED) - { - nux::Geometry home_geo (0, 0, 66, 24); - - if (!(GetGeometry ().IsPointInside (ievent.e_x, ievent.e_y)) - && !home_geo.IsPointInside (ievent.e_x, ievent.e_y)) - { - Hide (); - return nux::eMouseEventSolved; - } - } - - if (_layout) - { - ret = _layout->ProcessEvent (window_event, ret, ProcessEventInfo); - } - + + ret = _layout->ProcessEvent (ievent, ret, ProcessEventInfo); return ret; } -void PlacesView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +void +PlacesView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) { - nux::Geometry base = GetGeometry (); - // Coordinates inside the BaseWindow are relative to the top-left corner (0, 0). - base.x = base.y = 0; - - GfxContext.PushClippingRectangle (base); - nux::Color color (0.0, 0.0, 0.0, 0.9); - // You can use this function to draw a colored Quad: - //nux::GetPainter ().Paint2DQuadColor (GfxContext, GetGeometry (), color); - // or this one: - GfxContext.QRP_Color (0, 0, GetGeometry ().width, GetGeometry ().height, color); - - GfxContext.PopClippingRectangle (); } -void PlacesView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) +void +PlacesView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) { if (_layout) _layout->ProcessDraw (GfxContext, force_draw); } -void PlacesView::PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw) +// +// PlacesView Methods +// +void +PlacesView::SetActiveEntry (PlaceEntry *entry, guint section_id, const char *search_string) { + g_debug ("%s: %s %d %s", G_STRFUNC, entry->GetName (), section_id, search_string); } -long -PlacesView::PostLayoutManagement (long LayoutResult) +// +// UBus handlers +// +void +PlacesView::PlaceEntryActivateRequest (const char *entry_id, + guint section_id, + const char *search_string) { - return nux::BaseWindow::PostLayoutManagement (LayoutResult); -} - - + std::vector<Place *> places = PlaceFactory::GetDefault ()->GetPlaces (); + std::vector<Place *>::iterator it; + + for (it = places.begin (); it != places.end (); ++it) + { + Place *place = static_cast<Place *> (*it); + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; -/*void PlacesView::ShowWindow (bool b, bool start_modal) -{ - nux::BaseWindow::ShowWindow (b, start_modal); -}*/ + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); -void PlacesView::Show () -{ - if (IsVisible ()) - return; - - // FIXME: ShowWindow shouldn't need to be called first - ShowWindow (true, false); - EnableInputWindow (true, 1); - GrabPointer (); - GrabKeyboard (); - NeedRedraw (); -} + if (g_strcmp0 (entry_id, entry->GetId ()) == 0) + { + SetActiveEntry (entry, section_id, search_string); + return; + } + } + } -void PlacesView::Hide () -{ - if (!IsVisible ()) - return; - - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - UnGrabKeyboard (); - EnableInputWindow (false); - ShowWindow (false, false); + g_warning ("%s: Unable to find entry: %s for request: %d %s", + G_STRFUNC, + entry_id, + section_id, + search_string); } - -/* Introspection */ +// +// Introspection +// const gchar * PlacesView::GetName () { @@ -176,5 +145,25 @@ PlacesView::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x)); g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y)); g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); - g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); + g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); +} + +// +// C glue code +// +static void +place_entry_activate_request (GVariant *payload, PlacesView *self) +{ + gchar *id = NULL; + guint section = 0; + gchar *search_string = NULL; + + g_return_if_fail (self); + + g_variant_get (payload, "(sus)", &id, §ion, &search_string); + + self->PlaceEntryActivateRequest (id, section, search_string); + + g_free (id); + g_free (search_string); } diff --git a/src/PlacesView.h b/src/PlacesView.h index 415268e64..39f9f412e 100644 --- a/src/PlacesView.h +++ b/src/PlacesView.h @@ -24,32 +24,34 @@ #include <NuxImage/CairoGraphics.h> #include "NuxGraphics/GraphicsEngine.h" #include "Nux/AbstractPaintLayer.h" -#include <Nux/BaseWindow.h> #include <Nux/VLayout.h> #include "Introspectable.h" +#include "Place.h" +#include "PlaceEntry.h" + #include "PlacesSearchBar.h" #include "PlacesHomeView.h" -class PlacesView : public nux::BaseWindow, public Introspectable +class PlacesView : public nux::View, public Introspectable { - NUX_DECLARE_OBJECT_TYPE (PlacesView, nux::BaseWindow); + NUX_DECLARE_OBJECT_TYPE (PlacesView, nux::View); public: PlacesView (NUX_FILE_LINE_PROTO); ~PlacesView (); - virtual long ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo); - virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); - virtual void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw); - virtual void PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw); - virtual long PostLayoutManagement (long layoutResult); - - //void ShowWindow (bool b, bool start_modal = false); + // nux::View overrides + long ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo); + void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw); - void Show (); - void Hide (); + // Methods + void SetActiveEntry (PlaceEntry *entry, guint section_id, const char *search_string); + // UBus handlers + void PlaceEntryActivateRequest (const char *entry_id, guint section, const gchar *search); + protected: const gchar* GetName (); diff --git a/src/StaticCairoText.cpp b/src/StaticCairoText.cpp index c2b4f5172..f2b5bdc5e 100644 --- a/src/StaticCairoText.cpp +++ b/src/StaticCairoText.cpp @@ -50,9 +50,12 @@ StaticCairoText::~StaticCairoText () g_signal_handlers_disconnect_by_func (settings, (void *) &StaticCairoText::OnFontChanged, this); - delete (_cairoGraphics); - delete (_texture2D); - g_free (_fontstring); + + if (_texture2D) + delete (_texture2D); + + if (_fontstring) + g_free (_fontstring); } void @@ -137,6 +140,9 @@ StaticCairoText::Draw (GraphicsEngine& gfxContext, { Geometry base = GetGeometry (); + if (_texture2D == 0) + UpdateTexture (); + gfxContext.PushClippingRectangle (base); TexCoordXForm texxform; @@ -148,12 +154,12 @@ StaticCairoText::Draw (GraphicsEngine& gfxContext, GL_ONE_MINUS_SRC_ALPHA); gfxContext.QRP_1Tex (base.x, - base.y, - base.width, - base.height, - _texture2D->GetDeviceTexture(), - texxform, - _textColor); + base.y, + base.width, + base.height, + _texture2D->GetDeviceTexture(), + texxform, + _textColor); gfxContext.GetRenderStates().SetBlend (false); @@ -323,7 +329,6 @@ void StaticCairoText::DrawText (cairo_t* cr, GetTextExtents (fontName, textWidth, textHeight); - cairo_set_font_options (cr, gdk_screen_get_font_options (screen)); layout = pango_cairo_create_layout (cr); desc = pango_font_description_from_string (fontName); @@ -393,7 +398,7 @@ void StaticCairoText::UpdateTexture () _cairoGraphics = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ()); - cairo_t *cr = _cairoGraphics->GetContext (); + cairo_t *cr = cairo_reference (_cairoGraphics->GetContext ()); DrawText (cr, GetBaseWidth (), GetBaseHeight (), _textColor); @@ -408,6 +413,8 @@ void StaticCairoText::UpdateTexture () _texture2D = GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); _texture2D->Update (bitmap); + cairo_destroy (cr); + delete _cairoGraphics; } diff --git a/src/TrashLauncherIcon.cpp b/src/TrashLauncherIcon.cpp index e156dcf13..ffb2b3dd7 100644 --- a/src/TrashLauncherIcon.cpp +++ b/src/TrashLauncherIcon.cpp @@ -20,11 +20,12 @@ #include "TrashLauncherIcon.h" #include <gio/gio.h> +#include <glib/gi18n-lib.h> TrashLauncherIcon::TrashLauncherIcon (Launcher* IconManager) : SimpleLauncherIcon(IconManager) { - SetTooltipText ("Trash"); + SetTooltipText (_("Trash")); SetIconName ("user-trash"); SetQuirk (QUIRK_VISIBLE, true); SetQuirk (QUIRK_RUNNING, false); diff --git a/src/UBusMessages.h b/src/UBusMessages.h index cdffadd65..16b2b8295 100644 --- a/src/UBusMessages.h +++ b/src/UBusMessages.h @@ -27,4 +27,13 @@ // When other parts of Unity want to close the place view #define UBUS_PLACE_VIEW_CLOSE_REQUEST "PLACE_VIEW_CLOSE_REQUEST" +// Request a PlaceEntry to be shown. +// Payload should be: (sus) = (id, section, search_string). +// id = entry->GetId(), search_string can be "" +#define UBUS_PLACE_ENTRY_ACTIVATE_REQUEST "PLACE_ENTRY_ACTIVATE_REQUEST" + +// Signal send when places are shown or hidden +#define UBUS_PLACE_VIEW_HIDDEN "PLACE_VIEW_HIDDEN" +#define UBUS_PLACE_VIEW_SHOWN "PLACE_VIEW_SHOWN" + #endif // UBUS_MESSAGES_H diff --git a/src/unity-util-accessible.cpp b/src/unity-util-accessible.cpp index 4aa3124a4..821d65e44 100644 --- a/src/unity-util-accessible.cpp +++ b/src/unity-util-accessible.cpp @@ -194,6 +194,6 @@ unity_util_accessible_remove_global_event_listener (guint remove_listener) void unity_util_accessible_add_window (nux::BaseWindow *window) { - unity_root_accessible_add_window (UNITY_ROOT_ACCESSIBLE (root), - window); + unity_root_accessible_add_window + (UNITY_ROOT_ACCESSIBLE (unity_util_accessible_get_root ()), window); } diff --git a/src/unitya11y.cpp b/src/unitya11y.cpp index 15622ad29..aad3b5e80 100644 --- a/src/unitya11y.cpp +++ b/src/unitya11y.cpp @@ -290,4 +290,3 @@ unity_a11y_get_accessible (nux::Object *object) return accessible_object; } - diff --git a/src/unitya11y.h b/src/unitya11y.h index 8b2941d9f..a583fd1bd 100644 --- a/src/unitya11y.h +++ b/src/unitya11y.h @@ -27,8 +27,6 @@ void unity_a11y_preset_environment (void); void unity_a11y_init (void); void unity_a11y_finalize (void); - AtkObject *unity_a11y_get_accessible (nux::Object *object); - #endif /* UNITY_A11Y_H */ diff --git a/src/unityshell.cpp b/src/unityshell.cpp index bdf858e01..a6d094ee2 100644 --- a/src/unityshell.cpp +++ b/src/unityshell.cpp @@ -36,6 +36,7 @@ #include <dbus/dbus.h> #include <dbus/dbus-glib.h> +#include <glib/gi18n-lib.h> #include <gtk/gtk.h> #include <core/atoms.h> @@ -43,6 +44,8 @@ #include "perf-logger-utility.h" #include "unitya11y.h" +#include "config.h" + /* FIXME: once we get a better method to add the toplevel windows to the accessible root object, this include would not be required */ #include "unity-util-accessible.h" @@ -196,7 +199,7 @@ UnityScreen::showLauncherKeyInitiate (CompAction *action, if (state & CompAction::StateInitKey) action->setState (action->state () | CompAction::StateTermKey); - launcher->ForceShowLauncherStart (); + launcher->StartKeyShowLauncher (); return false; } @@ -205,7 +208,7 @@ UnityScreen::showLauncherKeyTerminate (CompAction *action, CompAction::State state, CompOption::Vector &options) { - launcher->ForceShowLauncherEnd (); + launcher->EndKeyShowLauncher (); return false; } @@ -476,6 +479,10 @@ UnityScreen::UnityScreen (CompScreen *screen) : unity_a11y_init (); + /* i18n init */ + bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + wt->Run (NULL); uScreen = this; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0717822c0..e38f1c59a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -53,6 +53,7 @@ add_executable (test-unit ../src/PlaceEntry.h ../src/PlaceFactoryFile.cpp ../src/PlaceFactoryFile.h + ../src/PlaceFactory.cpp ../src/PlaceFactory.h ../src/PlaceRemote.cpp ../src/PlaceRemote.h @@ -131,6 +132,7 @@ add_executable (test-places ../src/PlaceEntry.h ../src/PlaceFactoryFile.cpp ../src/PlaceFactoryFile.h + ../src/PlaceFactory.cpp ../src/PlaceFactory.h ../src/PlaceRemote.cpp ../src/PlaceRemote.h @@ -156,6 +158,42 @@ add_executable (test-places-tiles ) +add_executable (test-places-group + TestPlacesGroup.cpp + ../src/PlacesGroup.cpp + ../src/PlacesGroup.h + ../src/IconTexture.cpp + ../src/IconTexture.h + ../src/Introspectable.cpp + ../src/Introspectable.h + ../src/StaticCairoText.cpp + ../src/StaticCairoText.h + ../src/PlacesTile.cpp + ../src/PlacesTile.h + ../src/PlacesSimpleTile.cpp + ../src/PlacesSimpleTile.h + ) + +add_executable (test-places-results + TestPlacesResults.cpp + ../src/PlacesResultsController.cpp + ../src/PlacesResultsController.h + ../src/PlacesResultsView.h + ../src/PlacesResultsView.cpp + ../src/PlacesGroup.cpp + ../src/PlacesGroup.h + ../src/PlacesTile.cpp + ../src/PlacesTile.h + ../src/PlacesSimpleTile.cpp + ../src/PlacesSimpleTile.h + ../src/IconTexture.cpp + ../src/IconTexture.h + ../src/Introspectable.cpp + ../src/Introspectable.h + ../src/StaticCairoText.cpp + ../src/StaticCairoText.h + ) + add_executable (test-quicklist ui/TestQuicklist.cpp ui/EventFaker.cpp @@ -184,6 +222,7 @@ add_executable (test-places-backend ../src/PlaceFactoryFile.cpp ../src/PlaceFactoryFile.h ../src/PlaceFactory.h + ../src/PlaceFactory.cpp ../src/PlaceRemote.cpp ../src/PlaceRemote.h ../src/Place.h diff --git a/tests/TestPlaces.cpp b/tests/TestPlaces.cpp index 7f4242b58..59cd59e3d 100644 --- a/tests/TestPlaces.cpp +++ b/tests/TestPlaces.cpp @@ -15,6 +15,7 @@ * <http://www.gnu.org/licenses/> * * Authored by: Gordon Allott <gord.allott@canonical.com> + * Neil Jagdish Patel <neil.patel@canonical.com> * */ @@ -25,94 +26,120 @@ #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" #include <gtk/gtk.h> - +#include "Nux/ComboBoxSimple.h" #include "../src/ubus-server.h" - +#include "Nux/TableCtrl.h" #include "PlacesView.h" -#include "PlacesController.h" #include "UBusMessages.h" -class TestRunner +#include "PlaceFactoryFile.h" +#include "Place.h" +#include "PlaceEntry.h" + +class TestApp { public: - TestRunner (); - ~TestRunner (); - - static void InitWindowThread (nux::NThread* thread, void* InitData); - void Init (); - PlacesController *controller; - nux::HLayout *layout; - -private: - + TestApp () + { + nux::VLayout *layout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); + + _combo = new nux::ComboBoxSimple (NUX_TRACKER_LOCATION); + _combo->SetMinimumWidth (150); + _combo->sigTriggered.connect (sigc::mem_fun (this, &TestApp::OnComboChangedFoRealz)); + layout->AddView (_combo, 0, nux::eCenter, nux::eFix); + + PlacesView *view = new PlacesView (); + view->SetMinMaxSize(1024, 600); + layout->AddView(view, 1, nux::eCenter, nux::eFix); + + _factory = PlaceFactory::GetDefault (); + PopulateEntries (); + _factory->place_added.connect (sigc::mem_fun (this, &TestApp::OnPlaceAdded)); + + layout->SetContentDistribution(nux::eStackCenter); + nux::GetGraphicsThread()->SetLayout (layout); + } + + ~TestApp () + { + + } + + void OnPlaceAdded (Place *place) + { + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; + + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); + _combo->AddItem (entry->GetName ()); + } + } + + void PopulateEntries () + { + std::vector<Place *> places = _factory->GetPlaces (); + std::vector<Place *>::iterator it; + + for (it = places.begin (); it != places.end (); ++it) + { + Place *place = static_cast<Place *> (*it); + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; + + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); + _combo->AddItem (entry->GetName ()); + } + } + } + + void OnComboChangedFoRealz (nux::ComboBoxSimple *simple) + { + std::vector<Place *> places = _factory->GetPlaces (); + std::vector<Place *>::iterator it; + const char *txt = _combo->GetSelectionLabel (); + + // Find entry + for (it = places.begin (); it != places.end (); ++it) + { + Place *place = static_cast<Place *> (*it); + std::vector<PlaceEntry *> entries = place->GetEntries (); + std::vector<PlaceEntry *>::iterator i; + + for (i = entries.begin (); i != entries.end (); ++i) + { + PlaceEntry *entry = static_cast<PlaceEntry *> (*i); + + if (g_strcmp0 (txt, entry->GetName ()) == 0) + { + g_debug ("Activated: %s", entry->GetName ()); + ubus_server_send_message (ubus_server_get_default (), + UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, + g_variant_new ("(sus)", + entry->GetId (), + 0, + "")); + } + } + } + } + + nux::ComboBoxSimple *_combo; + PlaceFactory *_factory; }; -TestRunner::TestRunner () -{ -} -TestRunner::~TestRunner () +void ThreadWidgetInit(nux::NThread* thread, void* InitData) { -} -void TestRunner::Init () -{ - controller = new PlacesController (); } -void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) -{ - TestRunner *self = (TestRunner *) InitData; - self->Init (); -} - -void -ControlThread (nux::NThread* thread, - void* data) -{ - // sleep for 3 seconds - nux::SleepForMilliseconds (3000); - printf ("ControlThread successfully started\n"); - - nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, - data); - - mainWindowThread->SetFakeEventMode (true); - Display* display = mainWindowThread->GetWindow ().GetX11Display (); - - // assemble first button-click event - XEvent buttonPressEvent; - buttonPressEvent.xbutton.type = ButtonPress; - buttonPressEvent.xbutton.serial = 0; - buttonPressEvent.xbutton.send_event = False; - buttonPressEvent.xbutton.display = display; - buttonPressEvent.xbutton.window = 0; - buttonPressEvent.xbutton.root = 0; - buttonPressEvent.xbutton.subwindow = 0; - buttonPressEvent.xbutton.time = CurrentTime; - buttonPressEvent.xbutton.x = 1000; - buttonPressEvent.xbutton.y = 300; - buttonPressEvent.xbutton.x_root = 0; - buttonPressEvent.xbutton.y_root = 0; - buttonPressEvent.xbutton.state = 0; - buttonPressEvent.xbutton.button = Button1; - buttonPressEvent.xbutton.same_screen = True; - - mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, - (XEvent*) &buttonPressEvent); - - while (!mainWindowThread->ReadyForNextFakeEvent ()) - nux::SleepForMilliseconds (10); - - mainWindowThread->SetFakeEventMode (false); -} - - int main(int argc, char **argv) { - UBusServer *ubus; - nux::SystemThread* st = NULL; - nux::WindowThread* wt = NULL; + TestApp *app; g_type_init (); g_thread_init (NULL); @@ -120,25 +147,12 @@ int main(int argc, char **argv) nux::NuxInitialize(0); - g_setenv ("UNITY_ENABLE_PLACES", "1", FALSE); - - TestRunner *test_runner = new TestRunner (); - wt = nux::CreateGUIThread(TEXT("Unity Places"), - 1024, 600, - 0, - &TestRunner::InitWindowThread, - test_runner); - - st = nux::CreateSystemThread (NULL, ControlThread, wt); - - ubus = ubus_server_get_default (); - ubus_server_send_message (ubus, UBUS_HOME_BUTTON_ACTIVATED, NULL); - - if (st) - st->Start (NULL); - - wt->Run (NULL); - delete st; + nux::WindowThread* wt = nux::CreateGUIThread("Unity Places", + 1024, 600, 0, &ThreadWidgetInit, 0); + app = new TestApp (); + + wt->Run(NULL); delete wt; return 0; } + diff --git a/tests/TestPlacesGroup.cpp b/tests/TestPlacesGroup.cpp new file mode 100644 index 000000000..dcbe3c880 --- /dev/null +++ b/tests/TestPlacesGroup.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2010 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include "Nux/Nux.h" +#include "Nux/VLayout.h" +#include "Nux/HLayout.h" +#include "Nux/Button.h" +#include "IconTexture.h" +#include "StaticCairoText.h" +#include "Nux/TextureArea.h" +#include "Nux/WindowThread.h" +#include "NuxGraphics/GraphicsEngine.h" +#include "Nux/GridHLayout.h" +#include <gtk/gtk.h> + +#include "PlacesGroup.h" +#include "PlacesSimpleTile.h" + +class TestRunner +{ +public: + TestRunner (); + ~TestRunner (); + + static void InitWindowThread (nux::NThread* thread, void* InitData); + void Init (); + nux::VLayout *layout; + +private: + +}; + +TestRunner::TestRunner () +{ +} + +TestRunner::~TestRunner () +{ +} + +void TestRunner::Init () +{ + layout = new nux::VLayout (); + PlacesGroup *group1 = new PlacesGroup (); + group1->SetTitle ("Hello World!"); + group1->SetItemDetail (100, 5); + + nux::GridHLayout *group_content = new nux::GridHLayout (NUX_TRACKER_LOCATION); + for (int i = 0; i < 60; i++) + { + nux::ColorLayer color (nux::Color::RandomColor ()); + nux::TextureArea* texture_area = new nux::TextureArea (); + texture_area->SetPaintLayer (&color); + + group_content->AddView (texture_area, 1, nux::eLeft, nux::eFull); + } + + PlacesSimpleTile *tile11 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund."); + PlacesSimpleTile *tile12 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund."); + PlacesSimpleTile *tile13 = new PlacesSimpleTile ("firefox", "FooBar Fox"); + PlacesSimpleTile *tile14 = new PlacesSimpleTile ("THISISNOTAVALIDTEXTURE.NOTREAL", "this icon is not valid"); + + PlacesSimpleTile *tile21 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund."); + PlacesSimpleTile *tile22 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund."); + PlacesSimpleTile *tile23 = new PlacesSimpleTile ("firefox", "FooBar Fox"); + PlacesSimpleTile *tile24 = new PlacesSimpleTile ("THISISNOTAVALIDTEXTURE.NOTREAL", "this icon is not valid"); + + + group_content->AddView (tile11, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile12, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile13, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile14, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile21, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile22, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile23, 1, nux::eLeft, nux::eFull); + group_content->AddView (tile24, 1, nux::eLeft, nux::eFull); + + for (int i = 0; i < 60; i++) + { + nux::ColorLayer color (nux::Color::RandomColor ()); + nux::TextureArea* texture_area = new nux::TextureArea (); + texture_area->SetPaintLayer (&color); + + group_content->AddView (texture_area, 1, nux::eLeft, nux::eFull); + } + + group_content->ForceChildrenSize (true); + group_content->SetChildrenSize (64, 42); + group_content->EnablePartialVisibility (false); + + group_content->SetVerticalExternalMargin (4); + group_content->SetHorizontalExternalMargin (4); + group_content->SetVerticalInternalMargin (4); + group_content->SetHorizontalInternalMargin (4); + + group1->SetLayout (group_content); + + + layout->AddView (group1, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + + nux::GetGraphicsThread()->SetLayout (layout); +} + +void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) +{ + TestRunner *self = (TestRunner *) InitData; + self->Init (); +} + +void +ControlThread (nux::NThread* thread, + void* data) +{ + // sleep for 3 seconds + nux::SleepForMilliseconds (3000); + printf ("ControlThread successfully started\n"); + + nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, + data); +} + + +int main(int argc, char **argv) +{ + nux::SystemThread* st = NULL; + nux::WindowThread* wt = NULL; + + // no real tests right now, just make sure we don't get any criticals and such + // waiting on nice perceptual diff support before we can build real tests + // for views + + g_type_init (); + g_thread_init (NULL); + gtk_init (&argc, &argv); + + nux::NuxInitialize(0); + + g_setenv ("UNITY_ENABLE_PLACES", "1", FALSE); + + TestRunner *test_runner = new TestRunner (); + wt = nux::CreateGUIThread(TEXT("Unity Places Tile Test"), + 1024, 600, + 0, + &TestRunner::InitWindowThread, + test_runner); + + st = nux::CreateSystemThread (NULL, ControlThread, wt); + + if (st) + st->Start (NULL); + + wt->Run (NULL); + delete st; + delete wt; + return 0; +} diff --git a/tests/TestPlacesResults.cpp b/tests/TestPlacesResults.cpp new file mode 100644 index 000000000..9f1e1a9b7 --- /dev/null +++ b/tests/TestPlacesResults.cpp @@ -0,0 +1,219 @@ +/* + * Copyright 2010 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include "Nux/Nux.h" +#include "Nux/VLayout.h" +#include "Nux/HLayout.h" +#include "Nux/Button.h" +#include "IconTexture.h" +#include "StaticCairoText.h" +#include "Nux/TextureArea.h" +#include "Nux/WindowThread.h" +#include "NuxGraphics/GraphicsEngine.h" +#include "Nux/GridHLayout.h" +#include <gtk/gtk.h> + +#include "PlacesSimpleTile.h" +#include "PlacesGroup.h" +#include "PlacesResultsController.h" +#include "PlacesResultsView.h" + +class TestRunner +{ +public: + TestRunner (); + ~TestRunner (); + + static void InitWindowThread (nux::NThread* thread, void* InitData); + void Init (); + nux::VLayout *layout; + PlacesResultsController *controller; + PlacesResultsView *view; + +private: + +}; + +static gboolean +remove_timeout (PlacesResultsController *controller) +{ + controller->RemoveResult ("tile1-1"); + + return FALSE; +} + +TestRunner::TestRunner () +{ +} + +TestRunner::~TestRunner () +{ +} + +void TestRunner::Init () +{ + controller = new PlacesResultsController (); + view = new PlacesResultsView (); + + layout = new nux::VLayout (); + layout->AddView (view, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + + //~ PlacesGroup *group1 = new PlacesGroup (); + //~ group1->SetTitle ("Hello World!"); + //~ group1->SetItemDetail (100, 5); +//~ + //~ nux::GridHLayout *group_content = new nux::GridHLayout (NUX_TRACKER_LOCATION); + //~ for (int i = 0; i < 60; i++) + //~ { + //~ nux::ColorLayer color (nux::Color::RandomColor ()); + //~ nux::TextureArea* texture_area = new nux::TextureArea (); + //~ texture_area->SetPaintLayer (&color); +//~ + //~ group_content->AddView (texture_area, 1, nux::eLeft, nux::eFull); + //~ } +//~ + //~ group_content->ForceChildrenSize (true); + //~ group_content->SetChildrenSize (64, 42); + //~ group_content->EnablePartialVisibility (false); +//~ + //~ group_content->SetVerticalExternalMargin (4); + //~ group_content->SetHorizontalExternalMargin (4); + //~ group_content->SetVerticalInternalMargin (4); + //~ group_content->SetHorizontalInternalMargin (4); +//~ + //~ group1->SetLayout (group_content); +//~ + //~ view->AddGroup (group1); +//~ +//~ + //~ PlacesGroup *group2 = new PlacesGroup (); + //~ group2->SetTitle ("Group2!"); + //~ group2->SetItemDetail (100, 5); +//~ + //~ nux::GridHLayout *group_content2 = new nux::GridHLayout (NUX_TRACKER_LOCATION); + //~ for (int i = 0; i < 60; i++) + //~ { + //~ nux::ColorLayer color (nux::Color::RandomColor ()); + //~ nux::TextureArea* texture_area = new nux::TextureArea (); + //~ texture_area->SetPaintLayer (&color); +//~ + //~ group_content2->AddView (texture_area, 1, nux::eLeft, nux::eFull); + //~ } +//~ + //~ group_content2->ForceChildrenSize (true); + //~ group_content2->SetChildrenSize (64, 42); + //~ group_content2->EnablePartialVisibility (false); +//~ + //~ group_content2->SetVerticalExternalMargin (4); + //~ group_content2->SetHorizontalExternalMargin (4); + //~ group_content2->SetVerticalInternalMargin (4); + //~ group_content2->SetHorizontalInternalMargin (4); +//~ + //~ group2->SetLayout (group_content2); +//~ + //~ view->AddGroup (group2); + + + //~ PlacesGroup *group2 = new PlacesGroup (); + //~ group1->SetTitle ("Second Group"); + //~ group1->SetItemDetail (100, 5); +//~ +//~ +//~ + PlacesSimpleTile *tile11 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund.", 50); + PlacesSimpleTile *tile12 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund.", 50); + PlacesSimpleTile *tile13 = new PlacesSimpleTile ("firefox", "FooBar Fox", 50); + PlacesSimpleTile *tile14 = new PlacesSimpleTile ("THISISNOTAVALIDTEXTURE.NOTREAL", "this icon is not valid", 50); +//~ //~ + PlacesSimpleTile *tile21 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund.", 50); + PlacesSimpleTile *tile22 = new PlacesSimpleTile ("/usr/share/icons/scalable/apps/deluge.svg", "Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund. Der schnelle braune Fuchs sprang über den faulen Hund.", 50); + PlacesSimpleTile *tile23 = new PlacesSimpleTile ("firefox", "FooBar Fox", 50); + PlacesSimpleTile *tile24 = new PlacesSimpleTile ("THISISNOTAVALIDTEXTURE.NOTREAL", "this icon is not valid", 50); +//~ + controller->SetView (view); +//~ //~ + controller->AddResultToGroup ("Group1", tile11, "tile1-1"); + controller->AddResultToGroup ("Group1", tile12, "tile1-2"); + controller->AddResultToGroup ("Group1", tile13, "tile1-3"); + controller->AddResultToGroup ("Group1", tile14, "tile1-4"); +//~ //~ + controller->AddResultToGroup ("Group2", tile21, "tile2-1"); + controller->AddResultToGroup ("Group2", tile22, "tile2-2"); + controller->AddResultToGroup ("Group2", tile23, "tile2-3"); + controller->AddResultToGroup ("Group2", tile24, "tile2-4"); + + nux::GetGraphicsThread()->SetLayout (layout); + + g_timeout_add_seconds (2, (GSourceFunc)remove_timeout, controller); +} + +void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData) +{ + TestRunner *self = (TestRunner *) InitData; + self->Init (); +} + +void +ControlThread (nux::NThread* thread, + void* data) +{ + // sleep for 3 seconds + nux::SleepForMilliseconds (3000); + printf ("ControlThread successfully started\n"); + + nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, + data); +} + + +int main(int argc, char **argv) +{ + nux::SystemThread* st = NULL; + nux::WindowThread* wt = NULL; + + // no real tests right now, just make sure we don't get any criticals and such + // waiting on nice perceptual diff support before we can build real tests + // for views + + g_type_init (); + g_thread_init (NULL); + gtk_init (&argc, &argv); + + nux::NuxInitialize(0); + + g_setenv ("UNITY_ENABLE_PLACES", "1", FALSE); + + TestRunner *test_runner = new TestRunner (); + wt = nux::CreateGUIThread(TEXT("Unity Places Tile Test"), + 1024, 600, + 0, + &TestRunner::InitWindowThread, + test_runner); + + st = nux::CreateSystemThread (NULL, ControlThread, wt); + + if (st) + st->Start (NULL); + + wt->Run (NULL); + delete st; + delete wt; + return 0; +} diff --git a/tools/autopilot.py b/tools/autopilot.py index 5cd006d25..f6978c827 100755 --- a/tools/autopilot.py +++ b/tools/autopilot.py @@ -113,6 +113,9 @@ class Mouse(object): class UnityTests(object): '''Runs a series of unity actions, triggering GL calls''' + + _bfb_x = 24 + _bfb_y = 10 # this is totally lame. This should not be hard coded, but until I can get # unity to run in gdb and debug why introspection is crashing and hardlocking @@ -128,6 +131,8 @@ class UnityTests(object): '''Move mouse to a launcher and hover to show the tooltip''' print 'Showing tool tip...' self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) return self._unity.is_running() @@ -135,6 +140,8 @@ class UnityTests(object): '''Move mouse to a launcher and right click''' print 'Showing quicklist...' self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) sleep(0.25) self._mouse.click(button=3) @@ -147,6 +154,8 @@ class UnityTests(object): '''Click a launcher icon and drag down to move the whole launcher''' print 'Dragging entire launcher...' self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) sleep(0.25) print self._mouse.position() @@ -162,7 +171,9 @@ class UnityTests(object): '''Click a launcher icon and drag it along the edge of the launcher to test moving icons around on the launcher''' print 'Moving launcher icon along edge...' - self._mouse.reset() + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) self._mouse.press() self._mouse.move(self._dest_x + 25, self._dest_y) @@ -175,6 +186,8 @@ class UnityTests(object): it returns to its original position''' print 'Dragging launcher straight out and dropping...' self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) self._mouse.press() self._mouse.move(self._dest_x + 300, self._dest_y) @@ -185,6 +198,8 @@ class UnityTests(object): '''Click a launcher icon and drag it diagonally so that it changes position''' print 'Dragging a launcher icon out, and moving it...''' self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) self._mouse.move(self._dest_x, self._dest_y) self._mouse.press() self._mouse.move(self._dest_x + 300, self._dest_y) |
