diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2010-12-17 17:31:03 +0100 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2010-12-17 17:31:03 +0100 |
| commit | 4b8db9985fddc96d52e2b181c46acb15eacb2d92 (patch) | |
| tree | 68778811154b762e6ceb336390201fbef1cd60ff | |
| parent | 491e2f0f05062b3e1032054d573e876ca4f68ddb (diff) | |
| parent | 8b5d71a9a2292a1d29b1bfcbc98c6866ea72f543 (diff) | |
Import upstream version 3.2.8upstream-3.2.8
(bzr r55.4.37)
98 files changed, 3970 insertions, 2791 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e3eaf5f75..e6253eac3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ subdirs (libunity services tests tools) set (PROJECT_NAME "unity") set (UNITY_MAJOR 3) set (UNITY_MINOR 2) -set (UNITY_MICRO 6) +set (UNITY_MICRO 8) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "3.0") @@ -45,6 +45,7 @@ set (GETTEXT_PACKAGE "unity") set (LOCALE_DIR "${DATADIR}/locale") set (VERSION "${UNITY_VERSION}") set (BUILDDIR "${CMAKE_BINARY_DIR}") +set (TESTVALADIR "${CMAKE_SOURCE_DIR}/tests/vala") configure_file (${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) @@ -54,6 +55,8 @@ configure_file (${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) file (GLOB _datafiles "${CMAKE_CURRENT_SOURCE_DIR}/resources/*") install (FILES ${_datafiles} DESTINATION ${PKGDATADIR}) +install (FILES plugin-unityshell.png DESTINATION ${DATADIR}/ccsm/icons/hicolor/64x64/apps) + # # i18n # @@ -72,19 +75,27 @@ if (${GETTEXT_FOUND} STREQUAL "TRUE") endif (${GETTEXT_FOUND} STREQUAL "TRUE") # +# Enable or disable boot logging +# +option (BOOT_LOGGER "Enable startup performance logging" OFF) +if (BOOT_LOGGER) + SET (BOOT_LOGGER_FLAG "-DENABLE_LOGGER") +endif (BOOT_LOGGER) + +# # src (Compiz Plugin) # -set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dbus-glib-1;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib;x11;libstartup-notification-1.0;gthread-2.0;indicator") +set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dbus-glib-1;dee-1.0;gee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib;x11;libstartup-notification-1.0;gthread-2.0;indicator") find_package (Compiz REQUIRED) include (CompizPlugin) compiz_plugin (unityshell PKGDEPS ${UNITY_PLUGIN_DEPS} - PLUGINDEPS composite opengl - CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR}" + PLUGINDEPS composite opengl scale + CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR} ${BOOT_LOGGER_FLAG}" LIBRARIES "unity" ) - + # # GSettings Schema # diff --git a/config.h.cmake b/config.h.cmake index 675581ebe..0e3414c04 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -6,5 +6,6 @@ #cmakedefine LOCALE_DIR "@LOCALE_DIR@" #cmakedefine VERSION "@VERSION@" #cmakedefine BUILDDIR "@BUILDDIR@" +#cmakedefine TESTVALADIR "@TESTVALADIR@" #endif // CONFIG_H diff --git a/libunity/CMakeLists.txt b/libunity/CMakeLists.txt index e04fafa07..d3480f81f 100644 --- a/libunity/CMakeLists.txt +++ b/libunity/CMakeLists.txt @@ -50,6 +50,8 @@ find_package (Vala) vala_precompile (VALA_C unity-place-activation.vala unity-place-browser.vala unity-place.vala + unity-io.vala + unity-appinfo-manager.vala perf-logger.vala PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 dbus-glib-1 gio-unix-2.0 OPTIONS --thread diff --git a/libunity/perf-logger-utility.h b/libunity/perf-logger-utility.h index aee02abea..7a403464d 100644 --- a/libunity/perf-logger-utility.h +++ b/libunity/perf-logger-utility.h @@ -21,14 +21,23 @@ #include <libunity/unity.h> -#define START_FUNCTION() G_STMT_START { \ - perf_timeline_logger_start_process (perf_timeline_logger_get_default(), G_STRFUNC);\ - } G_STMT_END -#define LOGGER_START_PROCESS(process) { perf_timeline_logger_start_process (perf_timeline_logger_get_default(), process);} +#ifdef ENABLE_LOGGER + #define START_FUNCTION() G_STMT_START { \ + perf_timeline_logger_start_process (perf_timeline_logger_get_default(), G_STRFUNC);\ + } G_STMT_END + #define LOGGER_START_PROCESS(process) { perf_timeline_logger_start_process (perf_timeline_logger_get_default(), process);} -#define END_FUNCTION() G_STMT_START { \ - perf_timeline_logger_end_process (perf_timeline_logger_get_default(), G_STRFUNC);\ - } G_STMT_END -#define LOGGER_END_PROCESS(process) { perf_timeline_logger_end_process (perf_timeline_logger_get_default(), process);} + #define END_FUNCTION() G_STMT_START { \ + perf_timeline_logger_end_process (perf_timeline_logger_get_default(), G_STRFUNC);\ + } G_STMT_END + #define LOGGER_END_PROCESS(process) { perf_timeline_logger_end_process (perf_timeline_logger_get_default(), process);} + #define LOGGER_WRITE_LOG(file) { perf_timeline_logger_write_log (perf_timeline_logger_get_default(), file);} +#else + #define START_FUNCTION() + #define LOGGER_START_PROCESS(process) + #define END_FUNCTION() + #define LOGGER_END_PROCESS(process) + #define LOGGER_WRITE_LOG(file) +#endif /* ENABLE_LOGGER */ #endif /* PERF_LOGGER_H */ diff --git a/libunity/perf-logger.vala b/libunity/perf-logger.vala index 5eeca40e3..1dcd16aad 100644 --- a/libunity/perf-logger.vala +++ b/libunity/perf-logger.vala @@ -59,7 +59,6 @@ namespace Perf public void start_process (string name) { - debug ("shoop de whoop"); if (name in this.process_map.keys) { warning ("already started process: %s", name); @@ -73,7 +72,6 @@ namespace Perf public void end_process (string name) { - debug ("shonk le donk"); double end_time = this.global_timer.elapsed (); print ("the end time is %f", end_time); diff --git a/libunity/ubus-server.c b/libunity/ubus-server.c index 48126d64e..bc1e628f6 100644 --- a/libunity/ubus-server.c +++ b/libunity/ubus-server.c @@ -106,13 +106,13 @@ static UBusMessageInfo* ubus_message_info_new (GVariant *data) { UBusMessageInfo *info; - + info = g_slice_new (UBusMessageInfo); info->data = data; if (data != NULL) g_variant_ref_sink (data); - + return info; } @@ -121,7 +121,7 @@ ubus_message_info_free (UBusMessageInfo *info) { if (info->data != NULL) g_variant_unref (info->data); - + g_slice_free (UBusMessageInfo, info); } @@ -129,7 +129,7 @@ static void ubus_server_init (UBusServer *server) { UBusServerPrivate *priv; - + priv = server->priv = UBUS_SERVER_GET_PRIVATE (server); /* message_interest_table holds the message/DispatchInfo relationship @@ -159,10 +159,10 @@ ubus_server_finalize (GObject *object) { UBusServer *server; UBusServerPrivate *priv; - + server = UBUS_SERVER (object); priv = server->priv; - + g_hash_table_destroy (priv->message_interest_table); g_hash_table_destroy (priv->dispatch_table); @@ -191,9 +191,9 @@ ubus_server_get_default () { UBusServer *server; static gsize singleton; - + if (g_once_init_enter (&singleton)) - { + { server = g_object_new (UBUS_TYPE_SERVER, NULL); g_object_ref_sink (server); g_once_init_leave (&singleton, (gsize) server); @@ -250,14 +250,13 @@ ubus_server_pump_message_queue (UBusServer *server) UBusServerPrivate *priv = server->priv; UBusMessageInfo *info; - priv->message_pump_queued = TRUE; + priv->message_pump_queued = FALSE; // loop through each message queued and call the dispatch functions associated // with it. something in the back of my mind says it would be quicker in some // situations to sort the queue first so that duplicate messages can re-use // the same dispatch_list lookups.. but thats a specific case. - info = g_queue_pop_tail (priv->message_queue); for (; info != NULL; info = g_queue_pop_tail (priv->message_queue)) { @@ -266,7 +265,9 @@ ubus_server_pump_message_queue (UBusServer *server) info->message); if (dispatch_list == NULL) - continue; // no handlers for this message + { + continue; // no handlers for this message + } GSequenceIter *iter = g_sequence_get_begin_iter (dispatch_list); GSequenceIter *end = g_sequence_get_end_iter (dispatch_list); @@ -292,7 +293,7 @@ static void ubus_server_queue_message_pump (UBusServer *server) { UBusServerPrivate *priv; - + g_return_if_fail (UBUS_IS_SERVER (server)); priv = server->priv; @@ -310,9 +311,9 @@ ubus_server_send_message (UBusServer *server, { UBusServerPrivate *priv; UBusMessageInfo *message_info; - + g_return_if_fail (UBUS_IS_SERVER (server)); - g_return_if_fail (message != NULL); + g_return_if_fail (message != NULL); priv = server->priv; message_info = ubus_message_info_new (data); @@ -329,11 +330,11 @@ ubus_server_unregister_interest (UBusServer* server, guint handle) UBusServerPrivate *priv; GSequence *dispatch_list; UBusDispatchInfo *info; - + g_return_if_fail (UBUS_IS_SERVER (server)); g_return_if_fail (handle > 0); - priv = server->priv; + priv = server->priv; info = g_hash_table_lookup (priv->dispatch_table, GUINT_TO_POINTER (handle)); if (info == NULL) diff --git a/libunity/unity-appinfo-manager.vala b/libunity/unity-appinfo-manager.vala index 24d82f04b..ccc4fca09 100644 --- a/libunity/unity-appinfo-manager.vala +++ b/libunity/unity-appinfo-manager.vala @@ -45,15 +45,11 @@ namespace Unity { private Map<string,AppInfo?> appinfo_by_id; /* id or path -> AppInfo */ private Map<string,FileMonitor> monitors; /* parent uri -> monitor */ private Map<string, Gee.List<string>> categories_by_id; /* desktop id or path -> xdg cats */ - private uchar[] buffer; - private size_t buffer_size; private AppInfoManager () { appinfo_by_id = new HashMap<string,AppInfo?> (GLib.str_hash, GLib.str_equal); categories_by_id = new HashMap<string,Gee.List<string>> (GLib.str_hash, GLib.str_equal); - buffer_size = 1024; - buffer = new uchar[buffer_size]; monitors = new HashMap<string,AppInfo?> (GLib.str_hash, GLib.str_equal); foreach (string path in IO.get_system_data_dirs()) @@ -228,7 +224,7 @@ namespace Unity { /* Load it async */ size_t data_size; - void* data; + uint8[] data; FileInputStream input; /* Open from path or by desktop id */ @@ -268,8 +264,8 @@ namespace Unity { try { /* Note that we must manually free 'data' */ - yield IO.read_stream_async (input, buffer, buffer_size, - Priority.DEFAULT, null, + yield IO.read_stream_async (input, + Priority.LOW, null, out data, out data_size); } catch (Error e) @@ -293,9 +289,6 @@ namespace Unity { var appinfo = new DesktopAppInfo.from_keyfile (keyfile); appinfo_by_id.set (id, appinfo); - /* Manually free the raw file data */ - g_free (data); - return appinfo; } diff --git a/libunity/unity-io.vala b/libunity/unity-io.vala index 20d6938d1..e39f8e204 100644 --- a/libunity/unity-io.vala +++ b/libunity/unity-io.vala @@ -37,40 +37,29 @@ namespace Unity.IO { /** * Asynchronously read a stream into memory. This method will close * the input stream when done. - * - * Important: The passed back data must be manually freed using g_free() */ public async void read_stream_async (InputStream input, - void* buffer, - size_t buffer_lenght, - int io_priority, - Cancellable? cancellable, - out void* data, - out size_t size) throws Error + int io_priority = GLib.Priority.LOW, + Cancellable? cancellable = null, + out uint8[] data, + out size_t size) throws IOError { - size_t numread, numwritten; - /* Since the free func of the MemoryOutputStream is null, we own the * ref to the internal buffer when the stream is finalized */ - var output = new MemoryOutputStream (null, 0, realloc, null); - - while (true) - { - numread = yield input.read_async (buffer, buffer_lenght, - io_priority, cancellable); - if (numread <= 0) - break; - - /* We can do sync writes since it's known to be in memory */ - output.write_all (buffer, numread, out numwritten, null); - } + var output = new MemoryOutputStream (null, realloc, null); + yield output.splice_async (input, + OutputStreamSpliceFlags.CLOSE_SOURCE, + io_priority, cancellable); + + /* We can close the mem stream synchronously without risk, + * and we must close() it before stealing the data */ + output.close (null); - data = output.get_data(); + data = output.steal_data(); size = output.get_data_size (); /* Start closing the input stream, but don't wait for it to happen */ - input.close_async.begin(Priority.DEFAULT, null); - output.close (null); + input.close_async.begin(Priority.LOW, null); } /** diff --git a/plugin-unityshell.png b/plugin-unityshell.png Binary files differnew file mode 100644 index 000000000..3b5fb349c --- /dev/null +++ b/plugin-unityshell.png diff --git a/po/unity.pot b/po/unity.pot index 283b0ced6..8cdb2e483 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: 2010-12-07 14:34-0500\n" +"POT-Creation-Date: 2010-12-15 16:03+0000\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/resources/progress_bar_fill.png b/resources/progress_bar_fill.png Binary files differnew file mode 100644 index 000000000..f35aa9a36 --- /dev/null +++ b/resources/progress_bar_fill.png diff --git a/resources/progress_bar_trough.png b/resources/progress_bar_trough.png Binary files differnew file mode 100644 index 000000000..bcc258f2e --- /dev/null +++ b/resources/progress_bar_trough.png diff --git a/services/panel-service.c b/services/panel-service.c index 290d180fd..d8527cce3 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -955,6 +955,7 @@ panel_service_show_entry (PanelService *self, { PanelServicePrivate *priv = self->priv; IndicatorObjectEntry *entry = g_hash_table_lookup (priv->id2entry_hash, entry_id); + IndicatorObject *object = g_hash_table_lookup (priv->entry2indicator_hash, entry); if (priv->last_entry == entry) return; @@ -987,6 +988,7 @@ panel_service_show_entry (PanelService *self, priv->last_menu_move_id = g_signal_connect_after (priv->last_menu, "move-current", G_CALLBACK (on_active_menu_move_current), self); + indicator_object_entry_activate (object, entry, CurrentTime); gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, 0, CurrentTime); g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, entry_id); diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp index 20d2b6af6..334963d3d 100644 --- a/src/BamfLauncherIcon.cpp +++ b/src/BamfLauncherIcon.cpp @@ -83,6 +83,11 @@ BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, EnsureWindowState (); UpdateMenus (); + + PluginAdapter::Default ()->window_minimized.connect (sigc::mem_fun (this, &BamfLauncherIcon::OnWindowMinimized)); + + /* hack */ + SetProgress (0.5f); } BamfLauncherIcon::~BamfLauncherIcon() @@ -99,34 +104,56 @@ BamfLauncherIcon::~BamfLauncherIcon() } void +BamfLauncherIcon::OnWindowMinimized (CompWindow *window) +{ + if (!OwnsWindow (window->id ())) + return; + + Present (0.5f, 600); + UpdateQuirkTimeDelayed (300, LAUNCHER_ICON_QUIRK_SHIMMER); +} + +bool +BamfLauncherIcon::IsSticky () +{ + return bamf_view_is_sticky (BAMF_VIEW (m_App)); +} + +const char* +BamfLauncherIcon::DesktopFile () +{ + return bamf_application_get_desktop_file (m_App); +} + +void BamfLauncherIcon::AddProperties (GVariantBuilder *builder) { LauncherIcon::AddProperties (builder); g_variant_builder_add (builder, "{sv}", "desktop-file", g_variant_new_string (bamf_application_get_desktop_file (m_App))); - + GList *children, *l; BamfView *view; - + children = bamf_view_get_children (BAMF_VIEW (m_App)); GVariant* xids[(int) g_list_length (children)]; - + int i = 0; for (l = children; l; l = l->next) { view = (BamfView *) l->data; - + if (BAMF_IS_WINDOW (view)) { xids[i++] = g_variant_new_uint32 (bamf_window_get_xid (BAMF_WINDOW (view))); - } + } } g_list_free (children); g_variant_builder_add (builder, "{sv}", "xids", g_variant_new_array (G_VARIANT_TYPE_UINT32, xids, i)); } bool -BamfLauncherIcon::IconOwnsWindow (Window w) +BamfLauncherIcon::OwnsWindow (Window w) { GList *children, *l; BamfView *view; @@ -145,7 +172,7 @@ BamfLauncherIcon::IconOwnsWindow (Window w) if (xid == w) { owns = true; - break; + break; } } } @@ -178,6 +205,8 @@ BamfLauncherIcon::Focus () { GList *children, *l; BamfView *view; + bool any_urgent = false; + bool any_on_current = false; children = bamf_view_get_children (BAMF_VIEW (m_App)); @@ -195,12 +224,20 @@ BamfLauncherIcon::Focus () CompWindow *window = m_Screen->findWindow ((Window) xid); if (window) + { + if (bamf_view_is_urgent (view)) + any_urgent = true; windows.push_back (window); + } } } + // not a good sign if (windows.empty ()) + { + g_list_free (children); return; + } /* sort the list */ CompWindowList tmp; @@ -212,10 +249,7 @@ BamfLauncherIcon::Focus () } windows = tmp; - /* filter based on workspace */ - bool any_on_current = false; - for (it = windows.begin (); it != windows.end (); it++) { if ((*it)->defaultViewport () == m_Screen->vp ()) @@ -225,9 +259,36 @@ BamfLauncherIcon::Focus () } } - /* activate our windows */ + if (any_urgent) + { + // we cant use the compiz tracking since it is currently broken + /*for (it = windows.begin (); it != windows.end (); it++) + { + if ((*it)->state () & CompWindowStateDemandsAttentionMask) + { + (*it)->activate (); + break; + } + }*/ + for (l = children; l; l = l->next) + { + view = (BamfView *) l->data; + + if (BAMF_IS_WINDOW (view)) + { + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); + + CompWindow *window = m_Screen->findWindow ((Window) xid); - if (any_on_current) + if (window && bamf_view_is_urgent (view)) + { + window->activate (); + break; + } + } + } + } + else if (any_on_current) { for (it = windows.begin (); it != windows.end (); it++) { @@ -278,6 +339,10 @@ BamfLauncherIcon::Spread () void BamfLauncherIcon::OnMouseClick (int button) { + bool scaleWasActive = PluginAdapter::Default ()->IsScaleActive(); + + SimpleLauncherIcon::OnMouseClick (button); + if (button != 1) return; @@ -287,11 +352,17 @@ BamfLauncherIcon::OnMouseClick (int button) running = bamf_view_is_running (BAMF_VIEW (m_App)); if (!running) + { + if (GetQuirk (LAUNCHER_ICON_QUIRK_STARTING)) + return; + SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, true); OpenInstance (); - else if (active) - Spread (); - else + return; + } + else if (!active) Focus (); + else if (!scaleWasActive) + Spread (); } void @@ -400,44 +471,68 @@ BamfLauncherIcon::UpdateMenus () // make a client for desktop file actions if (!DBUSMENU_IS_MENUITEM (_menu_desktop_shortcuts) && - bamf_application_get_desktop_file (m_App) != NULL) + g_strcmp0 (DesktopFile (), """")) { + GKeyFile *keyfile; + GError *error = NULL; - DbusmenuMenuitem *root = dbusmenu_menuitem_new (); - dbusmenu_menuitem_set_root (root, TRUE); - desktop_shortcuts = indicator_desktop_shortcuts_new (bamf_application_get_desktop_file (m_App), - "Unity"); - const gchar **nicks = indicator_desktop_shortcuts_get_nicks (desktop_shortcuts); - - int index = 0; - if (nicks) { - while (((gpointer*) nicks)[index]) { - const char* name; - DbusmenuMenuitem *item; - name = g_strdup (indicator_desktop_shortcuts_nick_get_name (desktop_shortcuts, - nicks[index])); - ShortcutData *data = g_slice_new0 (ShortcutData); - data->self = this; - data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS (g_object_ref (desktop_shortcuts)); - data->nick = g_strdup (nicks[index]); - - item = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); - dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - g_signal_connect_data (item, "item-activated", - (GCallback) shortcut_activated, (gpointer) data, - (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0); - - dbusmenu_menuitem_child_append (root, item); - - index++; - - g_free ((void *)name); - } + // check that we have the X-Ayatana-Desktop-Shortcuts flag + // not sure if we should do this or if libindicator should shut up + // and not report errors when it can't find the key. + // so FIXME when ted is around + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, DesktopFile (), G_KEY_FILE_NONE, &error); + + if (error != NULL) + { + g_warning ("Could not load desktop file for: %s" , DesktopFile ()); + g_error_free (error); + return; } - _menu_desktop_shortcuts = root; + if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, + "X-Ayatana-Desktop-Shortcuts", NULL)) + { + DbusmenuMenuitem *root = dbusmenu_menuitem_new (); + dbusmenu_menuitem_set_root (root, TRUE); + desktop_shortcuts = indicator_desktop_shortcuts_new (bamf_application_get_desktop_file (m_App), + "Unity"); + const gchar **nicks = indicator_desktop_shortcuts_get_nicks (desktop_shortcuts); + + int index = 0; + if (nicks) + { + while (((gpointer*) nicks)[index]) + { + const char* name; + DbusmenuMenuitem *item; + name = g_strdup (indicator_desktop_shortcuts_nick_get_name (desktop_shortcuts, + nicks[index])); + ShortcutData *data = g_slice_new0 (ShortcutData); + data->self = this; + data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS (g_object_ref (desktop_shortcuts)); + data->nick = g_strdup (nicks[index]); + + item = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + g_signal_connect_data (item, "item-activated", + (GCallback) shortcut_activated, (gpointer) data, + (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0); + + dbusmenu_menuitem_child_append (root, item); + + index++; + + g_free ((void *)name); + } + } + + _menu_desktop_shortcuts = root; + g_key_file_free (keyfile); + + } } } @@ -596,11 +691,34 @@ BamfLauncherIcon::GetMenus () EnsureMenuItemsReady (); - result.push_back (_menu_items["Launch"]); - result.push_back (_menu_items["Pin"]); + std::map<std::string, DbusmenuMenuitem *>::iterator it_m; + std::list<DbusmenuMenuitem *>::iterator it_l; + bool exists; + for (it_m = _menu_items.begin (); it_m != _menu_items.end (); it_m++) + { + const char* key = ((*it_m).first).c_str(); + if (g_strcmp0 (key , "Quit") == 0 && !bamf_view_is_running (BAMF_VIEW (m_App))) + continue; + + exists = false; + std::string label_default = dbusmenu_menuitem_property_get ((*it_m).second, DBUSMENU_MENUITEM_PROP_LABEL); + for(it_l = result.begin(); it_l != result.end(); it_l++) + { + const gchar* type = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_TYPE); + if (type == NULL)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0) + { + std::string label_menu = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_LABEL); + if (label_menu.compare(label_default) == 0) + { + exists = true; + break; + } + } + } - if (bamf_view_is_running (BAMF_VIEW (m_App))) - result.push_back (_menu_items["Quit"]); + if (!exists) + result.push_back((*it_m).second); + } return result; } diff --git a/src/BamfLauncherIcon.h b/src/BamfLauncherIcon.h index 0dd30847e..488ab4740 100644 --- a/src/BamfLauncherIcon.h +++ b/src/BamfLauncherIcon.h @@ -36,8 +36,10 @@ class BamfLauncherIcon : public SimpleLauncherIcon { public: BamfLauncherIcon(Launcher* IconManager, BamfApplication *app, CompScreen *screen); - ~BamfLauncherIcon(); + virtual ~BamfLauncherIcon(); + const char* DesktopFile (); + bool IsSticky (); protected: void OnMouseClick (int button); @@ -46,7 +48,6 @@ protected: void UpdateIconGeometries (nux::Point3 center); void OnCenterStabilized (nux::Point3 center); - bool IconOwnsWindow (Window w); void AddProperties (GVariantBuilder *builder); @@ -66,6 +67,9 @@ private: void Spread (); void EnsureMenuItemsReady (); + + void OnWindowMinimized (CompWindow *window); + bool OwnsWindow (Window w); static void OnClosed (BamfView *view, gpointer data); static void OnUserVisibleChanged (BamfView *view, gboolean visible, gpointer data); diff --git a/src/FavoriteStore.h b/src/FavoriteStore.h index b67fda7b1..de8b13659 100644 --- a/src/FavoriteStore.h +++ b/src/FavoriteStore.h @@ -54,6 +54,7 @@ public: virtual void AddFavorite (const char *desktop_path, gint position) = 0; virtual void RemoveFavorite (const char *desktop_path) = 0; virtual void MoveFavorite (const char *desktop_path, gint position) = 0; + virtual void SetFavorites (std::list<const char*> desktop_paths) = 0; // Signals // Therse only emit if something has changed the GSettings object externally diff --git a/src/FavoriteStoreGSettings.cpp b/src/FavoriteStoreGSettings.cpp index 9c09cb3a8..6ba2c32d0 100644 --- a/src/FavoriteStoreGSettings.cpp +++ b/src/FavoriteStoreGSettings.cpp @@ -323,6 +323,36 @@ FavoriteStoreGSettings::MoveFavorite (const char *desktop_path, Refresh (); } +void +FavoriteStoreGSettings::SetFavorites (std::list<const char *> desktop_paths) +{ + char *favs[desktop_paths.size () + 1]; + favs[desktop_paths.size ()] = NULL; + + int i = 0; + std::list<const char*>::iterator it; + for (it = desktop_paths.begin (); it != desktop_paths.end (); it++) + { + favs[i] = get_basename_or_path (*it); + i++; + } + + m_ignore_signals = true; + if (!g_settings_set_strv (m_settings, "favorites", favs)) + g_warning ("Unable to set favorites from list"); + m_ignore_signals = false; + + i = 0; + while (favs[i] != NULL) + { + g_free (favs[i]); + favs[i] = NULL; + i++; + } + + Refresh (); +} + void FavoriteStoreGSettings::Changed (const gchar *key) { diff --git a/src/FavoriteStoreGSettings.h b/src/FavoriteStoreGSettings.h index dbc2f9e3a..f88fd0b1e 100644 --- a/src/FavoriteStoreGSettings.h +++ b/src/FavoriteStoreGSettings.h @@ -39,6 +39,7 @@ public: void AddFavorite (const char *desktop_path, gint position); void RemoveFavorite (const char *desktop_path); void MoveFavorite (const char *desktop_path, gint position); + void SetFavorites (std::list<const char *> desktop_paths); void Changed (const char *key); diff --git a/src/IndicatorObjectEntryProxy.h b/src/IndicatorObjectEntryProxy.h index c8dff0e12..5ec831506 100644 --- a/src/IndicatorObjectEntryProxy.h +++ b/src/IndicatorObjectEntryProxy.h @@ -36,7 +36,8 @@ public: virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button) = 0; // Signals - sigc::signal<void> Updated; + sigc::signal<void> updated; + sigc::signal<void, bool> active_changed; public: bool label_visible; diff --git a/src/IndicatorObjectEntryProxyRemote.cpp b/src/IndicatorObjectEntryProxyRemote.cpp index 87339c17d..56c30a261 100644 --- a/src/IndicatorObjectEntryProxyRemote.cpp +++ b/src/IndicatorObjectEntryProxyRemote.cpp @@ -104,7 +104,8 @@ IndicatorObjectEntryProxyRemote::SetActive (bool active) _active = active; - Updated.emit (); + active_changed.emit (active); + updated.emit (); } bool @@ -141,7 +142,7 @@ IndicatorObjectEntryProxyRemote::Refresh (const char *__id, icon_sensitive = __image_sensitive; icon_visible = __image_visible; - Updated.emit (); + updated.emit (); } const char * diff --git a/src/IndicatorObjectFactory.h b/src/IndicatorObjectFactory.h index c267a5b2e..a6f2755ef 100644 --- a/src/IndicatorObjectFactory.h +++ b/src/IndicatorObjectFactory.h @@ -45,6 +45,7 @@ public: sigc::signal<void, IndicatorObjectProxy *> OnObjectRemoved; sigc::signal<void, int, int> OnMenuPointerMoved; sigc::signal<void, const char *> OnEntryActivateRequest; + sigc::signal<void, const char *> OnEntryActivated; protected: std::vector<IndicatorObjectProxy *>_indicators; diff --git a/src/IndicatorObjectFactoryRemote.cpp b/src/IndicatorObjectFactoryRemote.cpp index b45efc13e..4257fabcd 100644 --- a/src/IndicatorObjectFactoryRemote.cpp +++ b/src/IndicatorObjectFactoryRemote.cpp @@ -56,6 +56,10 @@ static void on_proxy_signal_received (GDBusProxy *proxy, GVariant *parameters, IndicatorObjectFactoryRemote *remote); +static void on_proxy_name_owner_changed (GDBusProxy *proxy, + GParamSpec *pspec, + IndicatorObjectFactoryRemote *remote); + static void on_sync_ready_cb (GObject *source, GAsyncResult *res, gpointer data); @@ -65,25 +69,9 @@ static bool reconnect_to_service (gpointer data); // Public Methods IndicatorObjectFactoryRemote::IndicatorObjectFactoryRemote () +: _proxy (NULL) { - if (g_getenv ("PANEL_USE_LOCAL_SERVICE")) - { - run_local_panel_service (); - g_timeout_add_seconds (1, (GSourceFunc)reconnect_to_service, this); - } - else - { - // We want to grab the Panel Service object. This is async, which is fine - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - S_NAME, - S_PATH, - S_IFACE, - NULL, - on_proxy_ready_cb, - this); - } + Reconnect (); } IndicatorObjectFactoryRemote::~IndicatorObjectFactoryRemote () @@ -115,14 +103,39 @@ IndicatorObjectFactoryRemote::ForceRefresh () } void +IndicatorObjectFactoryRemote::Reconnect () +{ + if (g_getenv ("PANEL_USE_LOCAL_SERVICE")) + { + run_local_panel_service (); + g_timeout_add_seconds (1, (GSourceFunc)reconnect_to_service, this); + } + else + { + // We want to grab the Panel Service object. This is async, which is fine + reconnect_to_service (this); + } +} + +void IndicatorObjectFactoryRemote::OnRemoteProxyReady (GDBusProxy *proxy) { - _proxy = proxy; + if (_proxy) + { + // We've been connected before; We don't need new proxy, just continue + // rocking with the old one. + g_object_unref (proxy); + } + else + { + _proxy = proxy; - // Connect to interesting signals - // FIXME: Add auto-restarting bits here - g_signal_connect (_proxy, "g-signal", - G_CALLBACK (on_proxy_signal_received), this); + // Connect to interesting signals + g_signal_connect (_proxy, "g-signal", + G_CALLBACK (on_proxy_signal_received), this); + g_signal_connect (_proxy, "notify::g-name-owner", + G_CALLBACK (on_proxy_name_owner_changed), this); + } g_dbus_proxy_call (_proxy, "Sync", @@ -227,7 +240,9 @@ IndicatorObjectFactoryRemote::OnEntryActivated (const char *entry_id) entry->SetActive (g_strcmp0 (entry_id, entry->GetId ()) == 0); } - } + } + + IndicatorObjectFactory::OnEntryActivated.emit (entry_id); } void @@ -471,6 +486,24 @@ on_proxy_signal_received (GDBusProxy *proxy, } static void +on_proxy_name_owner_changed (GDBusProxy *proxy, + GParamSpec *pspec, + IndicatorObjectFactoryRemote *remote) +{ + char *name_owner; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + + if (name_owner == NULL) + { + // The panel service has stopped for some reason. Restart it. + remote->Reconnect (); + } + + g_free (name_owner); +} + +static void on_sync_ready_cb (GObject *source, GAsyncResult *res, gpointer data) diff --git a/src/IndicatorObjectFactoryRemote.h b/src/IndicatorObjectFactoryRemote.h index f32bc3fe5..5f9b00611 100644 --- a/src/IndicatorObjectFactoryRemote.h +++ b/src/IndicatorObjectFactoryRemote.h @@ -43,6 +43,7 @@ public: void OnShowMenuRequestReceived (const char *id, int x, int y, guint timestamp, guint32 button); void Sync (GVariant *args); void OnEntryActivateRequestReceived (const char *entry_id); + void Reconnect (); void AddProperties (GVariantBuilder *builder); diff --git a/src/Launcher.cpp b/src/Launcher.cpp index e0058c602..6d8e3fe5a 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -35,6 +35,7 @@ #include "Launcher.h" #include "LauncherIcon.h" #include "LauncherModel.h" +#include "QuicklistManager.h" #include "QuicklistView.h" #define ANIM_DURATION_SHORT 125 @@ -182,13 +183,26 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION); - OnMouseDown.connect(sigc::mem_fun(this, &Launcher::RecvMouseDown)); - OnMouseUp.connect(sigc::mem_fun(this, &Launcher::RecvMouseUp)); - OnMouseDrag.connect(sigc::mem_fun(this, &Launcher::RecvMouseDrag)); - OnMouseEnter.connect(sigc::mem_fun(this, &Launcher::RecvMouseEnter)); - OnMouseLeave.connect(sigc::mem_fun(this, &Launcher::RecvMouseLeave)); - OnMouseMove.connect(sigc::mem_fun(this, &Launcher::RecvMouseMove)); - OnMouseWheel.connect(sigc::mem_fun(this, &Launcher::RecvMouseWheel)); + OnMouseDown.connect (sigc::mem_fun (this, &Launcher::RecvMouseDown)); + OnMouseUp.connect (sigc::mem_fun (this, &Launcher::RecvMouseUp)); + OnMouseDrag.connect (sigc::mem_fun (this, &Launcher::RecvMouseDrag)); + OnMouseEnter.connect (sigc::mem_fun (this, &Launcher::RecvMouseEnter)); + OnMouseLeave.connect (sigc::mem_fun (this, &Launcher::RecvMouseLeave)); + OnMouseMove.connect (sigc::mem_fun (this, &Launcher::RecvMouseMove)); + OnMouseWheel.connect (sigc::mem_fun (this, &Launcher::RecvMouseWheel)); + + QuicklistManager::Default ()->quicklist_opened.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistOpened)); + QuicklistManager::Default ()->quicklist_closed.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); + + PluginAdapter::Default ()->window_maximized.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_restored.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_unminimized.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_mapped.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_unmapped.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_shown.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_hidden.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_resized.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); + PluginAdapter::Default ()->window_moved.connect (sigc::mem_fun (this, &Launcher::OnWindowMaybeIntellihide)); m_ActiveTooltipIcon = NULL; m_ActiveMenuIcon = NULL; @@ -230,6 +244,7 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _launcher_action_state = ACTION_NONE; _icon_under_mouse = NULL; _icon_mouse_down = NULL; + _drag_icon = NULL; _icon_image_size = 48; _icon_glow_size = 62; _icon_image_size_delta = 6; @@ -239,14 +254,14 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _icon_outline_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_outline_54x54.png"); _icon_shine_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_shine_54x54.png"); _icon_glow_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_glow_62x62.png"); - _icon_2indicator = nux::CreateTextureFromFile (PKGDATADIR"/2indicate_54x54.png"); - _icon_3indicator = nux::CreateTextureFromFile (PKGDATADIR"/3indicate_54x54.png"); - _icon_4indicator = nux::CreateTextureFromFile (PKGDATADIR"/4indicate_54x54.png"); + _progress_bar_trough = nux::CreateTextureFromFile (PKGDATADIR"/progress_bar_trough.png"); + _progress_bar_fill = nux::CreateTextureFromFile (PKGDATADIR"/progress_bar_fill.png"); _enter_y = 0; _dnd_security = 15; - _dnd_delta = 0; - _anim_handle = 0; + _launcher_drag_delta = 0; + _dnd_delta_y = 0; + _dnd_delta_x = 0; _autohide_handle = 0; _floating = false; _hovered = false; @@ -255,6 +270,7 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _mouse_inside_launcher = false; _mouse_inside_trigger = false; _window_over_launcher = false; + _render_drag_window = false; // 0 out timers to avoid wonky startups _enter_time.tv_sec = 0; @@ -263,8 +279,16 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _exit_time.tv_nsec = 0; _drag_end_time.tv_sec = 0; _drag_end_time.tv_nsec = 0; + _drag_start_time.tv_sec = 0; + _drag_start_time.tv_nsec = 0; + _drag_threshold_time.tv_sec = 0; + _drag_threshold_time.tv_nsec = 0; _autohide_time.tv_sec = 0; _autohide_time.tv_nsec = 0; + + _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); } Launcher::~Launcher() @@ -289,7 +313,7 @@ Launcher::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "dnd-exit-progress", g_variant_new_double ((double) DnDExitProgress (current))); g_variant_builder_add (builder, "{sv}", "autohide-progress", g_variant_new_double ((double) AutohideProgress (current))); - g_variant_builder_add (builder, "{sv}", "dnd-delta", g_variant_new_int32 (_dnd_delta)); + g_variant_builder_add (builder, "{sv}", "dnd-delta", g_variant_new_int32 (_dnd_delta_y)); g_variant_builder_add (builder, "{sv}", "floating", g_variant_new_boolean (_floating)); g_variant_builder_add (builder, "{sv}", "hovered", g_variant_new_boolean (_hovered)); g_variant_builder_add (builder, "{sv}", "autohide", g_variant_new_boolean (_autohide)); @@ -298,8 +322,23 @@ Launcher::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "mouse-inside-launcher", g_variant_new_boolean (_mouse_inside_launcher)); } -/* Render Layout Logic */ +void Launcher::SetMousePosition (int x, int y) +{ + bool beyond_drag_threshold = MouseBeyondDragThreshold (); + _mouse_position = nux::Point2 (x, y); + + if (beyond_drag_threshold != MouseBeyondDragThreshold ()) + SetTimeStruct (&_drag_threshold_time, &_drag_threshold_time, ANIM_DURATION_SHORT); +} +bool Launcher::MouseBeyondDragThreshold () +{ + if (_launcher_action_state != ACTION_DRAG_ICON) + return false; + return _mouse_position.x > GetGeometry ().width + _icon_size / 2; +} + +/* Render Layout Logic */ float Launcher::GetHoverProgress (struct timespec const ¤t) { if (_hovered) @@ -313,6 +352,11 @@ float Launcher::DnDExitProgress (struct timespec const ¤t) return 1.0f - CLAMP ((float) (TimeDelta (¤t, &_drag_end_time)) / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); } +float Launcher::DnDStartProgress (struct timespec const ¤t) +{ + return CLAMP ((float) (TimeDelta (¤t, &_drag_start_time)) / (float) ANIM_DURATION, 0.0f, 1.0f); +} + float Launcher::AutohideProgress (struct timespec const ¤t) { if (!_autohide) @@ -324,29 +368,24 @@ float Launcher::AutohideProgress (struct timespec const ¤t) return 1.0f - CLAMP ((float) (TimeDelta (¤t, &_autohide_time)) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); } +float Launcher::DragThresholdProgress (struct timespec const ¤t) +{ + if (MouseBeyondDragThreshold ()) + return 1.0f - CLAMP ((float) (TimeDelta (¤t, &_drag_threshold_time)) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); + else + return CLAMP ((float) (TimeDelta (¤t, &_drag_threshold_time)) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); +} + gboolean Launcher::AnimationTimeout (gpointer data) { Launcher *self = (Launcher*) data; - self->NeedRedraw (); - - if (self->AnimationInProgress ()) - return true; - - // zero out handle so we know we are done - self->_anim_handle = 0; return false; } void Launcher::EnsureAnimation () { - if (_anim_handle) - return; - NeedRedraw (); - - if (AnimationInProgress ()) - _anim_handle = g_timeout_add (1000 / 60 - 1, &Launcher::AnimationTimeout, this); } bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const ¤t) @@ -375,6 +414,14 @@ bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const &cu if (TimeDelta (¤t, &time) < ANIM_DURATION_LONG) return true; + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + if (TimeDelta (¤t, &time) < ANIM_DURATION) + return true; + + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PROGRESS); + if (TimeDelta (¤t, &time) < ANIM_DURATION) + return true; + return false; } @@ -394,13 +441,20 @@ bool Launcher::AnimationInProgress () // hover out animation if (TimeDelta (¤t, &_exit_time) < ANIM_DURATION) return true; - + + // drag start animation + if (TimeDelta (¤t, &_drag_start_time) < ANIM_DURATION) + return true; + // drag end animation if (TimeDelta (¤t, &_drag_end_time) < ANIM_DURATION_LONG) return true; if (TimeDelta (¤t, &_autohide_time) < ANIM_DURATION_SHORT) return true; + + if (TimeDelta (¤t, &_drag_threshold_time) < ANIM_DURATION_SHORT) + return true; // animations happening on specific icons LauncherModel::iterator it; @@ -469,10 +523,10 @@ void Launcher::SetDndDelta (float x, float y, nux::Geometry geo, struct timespec if (*it == anchor) { position += _icon_size / 2; - _dnd_delta = _enter_y - position; + _launcher_drag_delta = _enter_y - position; - if (position + _icon_size / 2 + _dnd_delta > geo.height) - _dnd_delta -= (position + _icon_size / 2 + _dnd_delta) - geo.height; + if (position + _icon_size / 2 + _launcher_drag_delta > geo.height) + _launcher_drag_delta -= (position + _icon_size / 2 + _launcher_drag_delta) - geo.height; break; } @@ -512,6 +566,13 @@ float Launcher::IconShimmerProgress (LauncherIcon *icon, struct timespec const & return CLAMP ((float) shimmer_ms / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); } +float Launcher::IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t) +{ + struct timespec save_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + int save_ms = TimeDelta (¤t, &save_time); + return CLAMP ((float) save_ms / (float) ANIM_DURATION, 0.0f, 1.0f); +} + float Launcher::IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t) { if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) @@ -527,6 +588,12 @@ float Launcher::IconStartingPulseValue (LauncherIcon *icon, struct timespec cons int starting_ms = TimeDelta (¤t, &starting_time); double starting_progress = (double) CLAMP ((float) starting_ms / (float) (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2), 0.0f, 1.0f); + if (starting_progress == 1.0f && !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + { + icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); + icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + } + return 1.0f - (0.5f + (float) (std::cos (M_PI * (float) (MAX_STARTING_BLINKS * 2) * starting_progress)) * 0.5f); } @@ -538,8 +605,11 @@ float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec con float running_progress = CLAMP ((float) running_ms / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); // After we finish a fade in from running, we can reset the quirk - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING) && running_progress == 1.0f) - icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + if (running_progress == 1.0f && icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + { + icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); + icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + } result = IconStartingPulseValue (icon, current) * BACKLIGHT_STRENGTH; @@ -561,6 +631,18 @@ float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec con return result; } +float Launcher::IconProgressBias (LauncherIcon *icon, struct timespec const ¤t) +{ + struct timespec icon_progress_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PROGRESS); + int ms = TimeDelta (¤t, &icon_progress_time); + float result = CLAMP ((float) ms / (float) ANIM_DURATION, 0.0f, 1.0f); + + if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_PROGRESS)) + return -1.0f + result; + else + return result; +} + void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec const ¤t, RenderArg &arg) { arg.icon = icon; @@ -569,9 +651,13 @@ void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec const ¤ arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE); arg.running_colored = icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT); arg.active_colored = false; - arg.folding_rads = 0.0f; + arg.x_rotation = 0.0f; + arg.y_rotation = 0.0f; + arg.z_rotation = 0.0f; arg.skip = false; - + arg.stick_thingy = false; + arg.progress_bias = IconProgressBias (icon, current); + arg.progress = CLAMP (icon->GetProgress (), 0.0f, 1.0f); // we dont need to show strays if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) @@ -583,10 +669,88 @@ void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec const ¤ arg.shimmer_progress = IconShimmerProgress (icon, current); float urgent_progress = IconUrgentProgress (icon, current); - urgent_progress = CLAMP (urgent_progress * 3, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle + + if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) + urgent_progress = CLAMP (urgent_progress * 3.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle + else + urgent_progress = CLAMP (urgent_progress * 3.0f - 2.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle arg.glow_intensity = urgent_progress; } +void Launcher::FillRenderArg (LauncherIcon *icon, + RenderArg &arg, + nux::Point3 ¢er, + float folding_threshold, + float folded_size, + float folded_spacing, + float autohide_offset, + float folded_z_distance, + float animation_neg_rads, + struct timespec const ¤t) +{ + SetupRenderArg (icon, current, arg); + + // reset z + center.z = 0; + + float size_modifier = IconVisibleProgress (icon, current); + if (size_modifier < 1.0f) + { + arg.alpha = size_modifier; + center.z = 300.0f * (1.0f - size_modifier); + } + + if (icon == _drag_icon) + { + if (MouseBeyondDragThreshold ()) + arg.stick_thingy = true; + + if (_launcher_action_state == ACTION_DRAG_ICON || (_drag_window && _drag_window->Animating ())) + arg.skip = true; + size_modifier *= DragThresholdProgress (current); + } + + if (size_modifier <= 0.0f) + arg.skip = true; + + // goes for 0.0f when fully unfolded, to 1.0f folded + float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); + float present_progress = IconPresentProgress (icon, current); + + folding_progress *= 1.0f - present_progress; + + float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); + float icon_hide_offset = autohide_offset; + + icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency ()); + + // icon is crossing threshold, start folding + center.z += folded_z_distance * folding_progress; + arg.x_rotation = animation_neg_rads * folding_progress; + + float spacing_overlap = CLAMP ((float) (center.y + (2.0f * half_size * size_modifier) + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); + float spacing = (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; + + nux::Point3 centerOffset; + float center_transit_progress = IconCenterTransitionProgress (icon, current); + if (center_transit_progress <= 1.0f) + { + centerOffset.y = (icon->_saved_center.y - (center.y + (half_size * size_modifier))) * (1.0f - center_transit_progress); + } + + center.y += half_size * size_modifier; // move to center + + arg.render_center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y + centerOffset.y), roundf (center.z)); + arg.logical_center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y), roundf (center.z)); + + icon->SetCenter (nux::Point3 (roundf (center.x), roundf (center.y), roundf (center.z))); + + if (icon == _drag_icon && _drag_window && _drag_window->Animating ()) + _drag_window->SetAnimationTarget ((int) center.x, (int) center.y + _parent->GetGeometry ().y); + + center.y += (half_size * size_modifier) + spacing; // move to end +} + float Launcher::DragLimiter (float x) { float result = (1 - std::pow (159.0 / 160, std::abs (x))) * 160; @@ -608,7 +772,6 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, float hover_progress = GetHoverProgress (current); float folded_z_distance = _folded_z_distance * (1.0f - hover_progress); float animation_neg_rads = _neg_folded_angle * (1.0f - hover_progress); - int vertical_offset = _parent->GetGeometry ().y; float folding_constant = 0.25f; float folding_not_constant = folding_constant + ((1.0f - folding_constant) * hover_progress); @@ -643,31 +806,31 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, _enter_y = 0; - if (hover_progress > 0.0f && _dnd_delta != 0) + if (hover_progress > 0.0f && _launcher_drag_delta != 0) { - float delta_y = _dnd_delta; + float delta_y = _launcher_drag_delta; // logically dnd exit only restores to the clamped ranges // hover_progress restores to 0 float max = 0.0f; float min = MIN (0.0f, launcher_height - sum); - if (_dnd_delta > max) + if (_launcher_drag_delta > max) delta_y = max + DragLimiter (delta_y - max); - else if (_dnd_delta < min) + else if (_launcher_drag_delta < min) delta_y = min + DragLimiter (delta_y - min); if (_launcher_action_state != ACTION_DRAG_LAUNCHER) { float dnd_progress = DnDExitProgress (current); - if (_dnd_delta > max) + if (_launcher_drag_delta > max) delta_y = max + (delta_y - max) * dnd_progress; - else if (_dnd_delta < min) + else if (_launcher_drag_delta < min) delta_y = min + (delta_y - min) * dnd_progress; if (dnd_progress == 0.0f) - _dnd_delta = (int) delta_y; + _launcher_drag_delta = (int) delta_y; } delta_y *= hover_progress; @@ -676,7 +839,7 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, } else { - _dnd_delta = 0; + _launcher_drag_delta = 0; } float autohide_progress = AutohideProgress (current); @@ -702,48 +865,8 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, RenderArg arg; LauncherIcon *icon = *it; - SetupRenderArg (icon, current, arg); - - // reset z - center.z = 0; - - float size_modifier = IconVisibleProgress (icon, current); - if (size_modifier < 1.0f) - { - arg.alpha = size_modifier; - center.z = 300.0f * (1.0f - size_modifier); - } - - if (size_modifier <= 0.0f) - { - arg.skip = true; - continue; - } - - // goes for 0.0f when fully unfolded, to 1.0f folded - float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - float present_progress = IconPresentProgress (icon, current); - - folding_progress *= 1.0f - present_progress; - - float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); - - float icon_hide_offset = autohide_offset; - - icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency ()); - - // icon is crossing threshold, start folding - center.z += folded_z_distance * folding_progress; - arg.folding_rads = animation_neg_rads * folding_progress; - - center.y += half_size * size_modifier; // move to center - arg.center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y), roundf (center.z)); // copy center - icon->SetCenter (nux::Point3 (roundf (center.x), roundf (center.y + vertical_offset), roundf (center.z))); - center.y += half_size * size_modifier; // move to end - - float spacing_overlap = CLAMP ((float) (center.y + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - //add spacing - center.y += (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; + FillRenderArg (icon, arg, center, folding_threshold, folded_size, folded_spacing, + autohide_offset, folded_z_distance, animation_neg_rads, current); launcher_args.push_back (arg); } @@ -768,50 +891,10 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, { RenderArg arg; LauncherIcon *icon = *it; - - SetupRenderArg (icon, current, arg); - - // reset z - center.z = 0; - - float size_modifier = IconVisibleProgress (icon, current); - if (size_modifier < 1.0f) - { - arg.alpha = size_modifier; - center.z = 300.0f * (1.0f - size_modifier); - } - - if (size_modifier <= 0.0f) - { - arg.skip = true; - continue; - } - - // goes for 0.0f when fully unfolded, to 1.0f folded - float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - float present_progress = IconPresentProgress (icon, current); - - folding_progress *= 1.0f - present_progress; - - float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); - - float icon_hide_offset = autohide_offset; - - icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency ()); - - // icon is crossing threshold, start folding - center.z += folded_z_distance * folding_progress; - arg.folding_rads = animation_neg_rads * folding_progress; - - center.y += half_size * size_modifier; // move to center - arg.center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y), roundf (center.z)); // copy center - icon->SetCenter (nux::Point3 (roundf (center.x), roundf (center.y + vertical_offset), roundf (center.z))); - center.y += half_size * size_modifier; // move to end - - float spacing_overlap = CLAMP ((float) (center.y + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - //add spacing - center.y += (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; - + + FillRenderArg (icon, arg, center, folding_threshold, folded_size, folded_spacing, + autohide_offset, folded_z_distance, animation_neg_rads, current); + launcher_args.push_back (arg); } } @@ -843,7 +926,11 @@ gboolean Launcher::OnAutohideTimeout (gpointer data) void Launcher::EnsureHiddenState () { - if (!_mouse_inside_trigger && !_mouse_inside_launcher && _window_over_launcher) + if (!_mouse_inside_trigger && + !_mouse_inside_launcher && + _launcher_action_state == ACTION_NONE && + !QuicklistManager::Default ()->Current() && + _window_over_launcher) SetHidden (true); else SetHidden (false); @@ -860,7 +947,7 @@ Launcher::CheckWindowOverLauncher () { CompWindow *window = *it; - if (window->type () != CompWindowTypeNormalMask || window->invisible ()) + if (window->type () != CompWindowTypeNormalMask || !window->isMapped () || !window->isViewable ()) continue; if (CompRegion (window->inputRect ()).intersects (CompRect (geo.x, geo.y, geo.width, geo.height))) @@ -876,27 +963,7 @@ Launcher::CheckWindowOverLauncher () } void -Launcher::OnWindowMoved (CompWindow *window) -{ - if (_autohide) - CheckWindowOverLauncher (); -} - -void -Launcher::OnWindowResized (CompWindow *window) -{ - if (_autohide) - CheckWindowOverLauncher (); -} - -void -Launcher::OnWindowAppear (CompWindow *window) -{ - if (_autohide) - CheckWindowOverLauncher (); -} -void -Launcher::OnWindowDisappear (CompWindow *window) +Launcher::OnWindowMaybeIntellihide (CompWindow *window) { if (_autohide) CheckWindowOverLauncher (); @@ -970,6 +1037,19 @@ void Launcher::SetFloating (bool floating) EnsureAnimation (); } +void +Launcher::EnsureHoverState () +{ + if (_mouse_inside_launcher || QuicklistManager::Default ()->Current() || _launcher_action_state != ACTION_NONE) + { + SetHover (); + } + else + { + UnsetHover (); + } +} + void Launcher::SetHover () { if (_hovered) @@ -1004,17 +1084,16 @@ void Launcher::SetIconSize(int tile_size, int icon_size) _parent->SetGeometry (nux::Geometry (geo.x, geo.y, tile_size + 12, geo.height)); } -void Launcher::OnIconAdded (void *icon_pointer) +void Launcher::OnIconAdded (LauncherIcon *icon) { - LauncherIcon *icon = (LauncherIcon *) icon_pointer; icon->Reference (); EnsureAnimation(); // How to free these properly? - icon->_xform_coords["HitArea"] = new nux::Vector4[4]; - icon->_xform_coords["Image"] = new nux::Vector4[4]; - icon->_xform_coords["Tile"] = new nux::Vector4[4]; - icon->_xform_coords["Glow"] = new nux::Vector4[4]; + icon->_xform_coords["HitArea"] = new nux::Vector4[4]; + icon->_xform_coords["Image"] = new nux::Vector4[4]; + icon->_xform_coords["Tile"] = new nux::Vector4[4]; + icon->_xform_coords["Glow"] = new nux::Vector4[4]; // needs to be disconnected icon->needs_redraw.connect (sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw)); @@ -1022,13 +1101,10 @@ void Launcher::OnIconAdded (void *icon_pointer) AddChild (icon); } -void Launcher::OnIconRemoved (void *icon_pointer) +void Launcher::OnIconRemoved (LauncherIcon *icon) { - LauncherIcon *icon = (LauncherIcon *) icon_pointer; icon->UnReference (); - EnsureAnimation(); - RemoveChild (icon); } @@ -1045,7 +1121,7 @@ void Launcher::SetModel (LauncherModel *model) _model->order_changed.connect (sigc::mem_fun (this, &Launcher::OnOrderChanged)); } -void Launcher::OnIconNeedsRedraw (void *icon) +void Launcher::OnIconNeedsRedraw (LauncherIcon *icon) { EnsureAnimation(); } @@ -1068,7 +1144,7 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, int active, nux::Geometry geo) { - int markerCenter = (int) arg.center.y; + int markerCenter = (int) arg.render_center.y; if (running > 0) { @@ -1139,13 +1215,12 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, RenderArg const &arg, - nux::BaseTexture *icon, + nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon, nux::Color bkg_color, float alpha, - nux::Vector4 xform_coords[], - nux::Geometry geo) + nux::Vector4 xform_coords[]) { - if (icon == NULL || icon->IsNull ()) + if (icon == NULL) return; nux::Matrix4 ObjectMatrix; @@ -1153,10 +1228,10 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, nux::Matrix4 ProjectionMatrix; nux::Matrix4 ViewProjectionMatrix; - if(nux::Abs (arg.folding_rads) < 0.01f) - icon->GetDeviceTexture()->SetFiltering(GL_NEAREST, GL_NEAREST); + if(nux::Abs (arg.x_rotation) < 0.01f) + icon->SetFiltering(GL_NEAREST, GL_NEAREST); else - icon->GetDeviceTexture()->SetFiltering(GL_LINEAR, GL_LINEAR); + icon->SetFiltering(GL_LINEAR, GL_LINEAR); nux::Vector4 v0; nux::Vector4 v1; @@ -1183,7 +1258,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, float s0, t0, s1, t1, s2, t2, s3, t3; nux::Color color = nux::Color::White; - if (icon->Type ().IsDerivedFromType(nux::TextureRectangle::StaticObjectType)) + if (icon->GetResourceType () == nux::RTTEXTURERECTANGLE) { s0 = 0.0f; t0 = 0.0f; s1 = 0.0f; t1 = icon->GetHeight(); @@ -1305,27 +1380,27 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const & GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); + /* draw tile */ if (arg.backlight_intensity < 1.0f) { RenderIcon(GfxContext, arg, - _icon_outline_texture, + _icon_outline_texture->GetDeviceTexture (), nux::Color(0xAAFFFFFF), 1.0f - arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], - geo); + arg.icon->_xform_coords["Tile"]); } if (arg.backlight_intensity > 0.0f) { RenderIcon(GfxContext, arg, - _icon_bkg_texture, + _icon_bkg_texture->GetDeviceTexture (), arg.icon->BackgroundColor (), arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], - geo); + arg.icon->_xform_coords["Tile"]); } + /* end tile draw */ GfxContext.GetRenderStates ().SetSeparateBlend (true, GL_SRC_ALPHA, @@ -1334,70 +1409,37 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const & GL_ONE); GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); + /* draw icon */ RenderIcon (GfxContext, arg, - arg.icon->TextureForSize (_icon_image_size), + arg.icon->TextureForSize (_icon_image_size)->GetDeviceTexture (), nux::Color::White, arg.alpha, - arg.icon->_xform_coords["Image"], - geo); + arg.icon->_xform_coords["Image"]); + /* draw overlay shine */ if (arg.backlight_intensity > 0.0f) { RenderIcon(GfxContext, arg, - _icon_shine_texture, + _icon_shine_texture->GetDeviceTexture (), nux::Color::White, arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], - geo); - } - - if (false) - { - switch (arg.window_indicators) - { - case 2: - RenderIcon(GfxContext, - arg, - _icon_2indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], - geo); - break; - case 3: - RenderIcon(GfxContext, - arg, - _icon_3indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], - geo); - break; - case 4: - RenderIcon(GfxContext, - arg, - _icon_4indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], - geo); - break; - } + arg.icon->_xform_coords["Tile"]); } + /* draw glow */ if (arg.glow_intensity > 0.0f) { RenderIcon(GfxContext, arg, - _icon_glow_texture, + _icon_glow_texture->GetDeviceTexture (), arg.icon->GlowColor (), arg.glow_intensity, - arg.icon->_xform_coords["Glow"], - geo); + arg.icon->_xform_coords["Glow"]); } - + + /* draw shimmer */ if (arg.shimmer_progress > 0.0f && arg.shimmer_progress < 1.0f) { nux::Geometry base = GetGeometry (); @@ -1412,15 +1454,30 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const & RenderIcon(GfxContext, arg, - _icon_glow_texture, + _icon_glow_texture->GetDeviceTexture (), arg.icon->GlowColor (), fade_out, - arg.icon->_xform_coords["Glow"], - geo); + arg.icon->_xform_coords["Glow"]); GfxContext.PopClippingRectangle(); } + + /* draw progress bar */ + if (arg.progress_bias > -1.0f && arg.progress_bias < 1.0f) + { + if (_offscreen_progress_texture->GetWidth () != _icon_size || _offscreen_progress_texture->GetHeight () != _icon_size) + _offscreen_progress_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (_icon_size, _icon_size, 1, nux::BITFMT_R8G8B8A8); + RenderProgressToTexture (GfxContext, _offscreen_progress_texture, arg.progress, arg.progress_bias); + + RenderIcon(GfxContext, + arg, + _offscreen_progress_texture, + nux::Color::White, + 1.0f, + arg.icon->_xform_coords["Tile"]); + } + /* draw indicators */ RenderIndicators (GfxContext, arg, arg.running_arrow ? arg.window_indicators : 0, @@ -1431,12 +1488,15 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const & void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { nux::Geometry base = GetGeometry(); - GfxContext.PushClippingRectangle(base); nux::Geometry bkg_box; std::list<Launcher::RenderArg> args; std::list<Launcher::RenderArg>::reverse_iterator rev_it; std::list<Launcher::RenderArg>::iterator it; + // rely on the compiz event loop to come back to us in a nice throttling + if (AnimationInProgress ()) + g_timeout_add (0, &Launcher::AnimationTimeout, this); + nux::ROPConfig ROP; ROP.Blend = false; ROP.SrcBlend = GL_SRC_ALPHA; @@ -1444,7 +1504,18 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) RenderArgs (args, bkg_box); + if (_drag_icon && _render_drag_window) + { + RenderIconToTexture (GfxContext, _drag_icon, _offscreen_drag_texture); + _drag_window->ShowWindow (true); + nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_drag_window); + + _render_drag_window = false; + } + + // clear region + GfxContext.PushClippingRectangle(base); gPainter.PushDrawColorLayer(GfxContext, base, nux::Color(0x00000000), true, ROP); // clip vertically but not horizontally @@ -1463,7 +1534,12 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) /* draw launcher */ for (rev_it = args.rbegin (); rev_it != args.rend (); rev_it++) { - if ((*rev_it).folding_rads >= 0.0f || (*rev_it).skip) + if ((*rev_it).stick_thingy) + gPainter.Paint2DQuadColor (GfxContext, + nux::Geometry (bkg_box.x, (*rev_it).render_center.y - 3, bkg_box.width, 2), + nux::Color(0xAAFFFFFF)); + + if ((*rev_it).x_rotation >= 0.0f || (*rev_it).skip) continue; DrawRenderArg (GfxContext, *rev_it, bkg_box); @@ -1471,7 +1547,12 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) for (it = args.begin(); it != args.end(); it++) { - if ((*it).folding_rads < 0.0f || (*it).skip) + if ((*it).stick_thingy) + gPainter.Paint2DQuadColor (GfxContext, + nux::Geometry (bkg_box.x, (*it).render_center.y - 3, bkg_box.width, 2), + nux::Color(0xAAFFFFFF)); + + if ((*it).x_rotation < 0.0f || (*it).skip) continue; DrawRenderArg (GfxContext, *it, bkg_box); @@ -1509,7 +1590,7 @@ long Launcher::PostLayoutManagement(long LayoutResult) { View::PostLayoutManagement(LayoutResult); - _mouse_position = nux::Point2 (0, 0); + SetMousePosition (0, 0); return nux::eCompliantHeight | nux::eCompliantWidth; } @@ -1518,27 +1599,76 @@ void Launcher::PositionChildLayout(float offsetX, float offsetY) { } -bool Launcher::TooltipNotify(LauncherIcon* Icon) +void Launcher::OnDragWindowAnimCompleted () { - if(GetActiveMenuIcon()) - return false; - return true; + if (_drag_window) + _drag_window->ShowWindow (false); + + EnsureAnimation (); } -bool Launcher::MenuNotify(LauncherIcon* Icon) +void Launcher::StartIconDrag (LauncherIcon *icon) { + if (!icon) + return; + + _drag_icon = icon; + if (_drag_window) + { + _drag_window->ShowWindow (false); + _drag_window->UnReference (); + _drag_window = NULL; + } + + _offscreen_drag_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (_icon_size, _icon_size, 1, nux::BITFMT_R8G8B8A8); + _drag_window = new LauncherDragWindow (_offscreen_drag_texture); + _drag_window->SinkReference (); + + _render_drag_window = true; +} - return true; +void Launcher::EndIconDrag () +{ + if (_drag_window) + { + _drag_window->SetAnimationTarget ((int) (_drag_icon->GetCenter ().x), (int) (_drag_icon->GetCenter ().y)); + _drag_window->StartAnimation (); + _drag_window->anim_completed.connect (sigc::mem_fun (this, &Launcher::OnDragWindowAnimCompleted)); + } + + if (MouseBeyondDragThreshold ()) + SetTimeStruct (&_drag_threshold_time, &_drag_threshold_time, ANIM_DURATION_SHORT); + + _render_drag_window = false; } -void Launcher::NotifyMenuTermination(LauncherIcon* Icon) +void Launcher::UpdateDragWindowPosition (int x, int y) { + if (_drag_window) + { + nux::Geometry geo = _drag_window->GetGeometry (); + _drag_window->SetBaseXY (x - geo.width / 2 + _parent->GetGeometry ().x, y - geo.height / 2 + _parent->GetGeometry ().y); + + LauncherIcon *hovered_icon = MouseIconIntersection ((int) (GetGeometry ().x / 2.0f), y); + + struct timespec current; + clock_gettime (CLOCK_MONOTONIC, ¤t); + if (_drag_icon && hovered_icon && _drag_icon != hovered_icon) + { + float progress = DragThresholdProgress (current); + + if (progress >= 1.0f) + request_reorder_smart.emit (_drag_icon, hovered_icon, true); + else if (progress == 0.0f) + request_reorder_before.emit (_drag_icon, hovered_icon, false); + } + } } void Launcher::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); + SetMousePosition (x, y); MouseDownLogic (x, y, button_flags, key_flags); EnsureAnimation (); @@ -1546,27 +1676,37 @@ void Launcher::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned void Launcher::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); + SetMousePosition (x, y); nux::Geometry geo = GetGeometry (); - if (_launcher_action_state == ACTION_DRAG_LAUNCHER && !geo.IsInside(nux::Point(x, y))) + if (_launcher_action_state != ACTION_NONE && !geo.IsInside(nux::Point(x, y))) { // we are no longer hovered - UnsetHover (); + EnsureHoverState (); } - + MouseUpLogic (x, y, button_flags, key_flags); + + if (_launcher_action_state == ACTION_DRAG_ICON) + EndIconDrag (); + _launcher_action_state = ACTION_NONE; + _dnd_delta_x = 0; + _dnd_delta_y = 0; + EnsureHoverState (); EnsureAnimation (); } void Launcher::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); - - _dnd_delta += dy; + SetMousePosition (x, y); - if (nux::Abs (_dnd_delta) < 15 && _launcher_action_state != ACTION_DRAG_LAUNCHER) + _dnd_delta_y += dy; + _dnd_delta_x += dx; + + if (nux::Abs (_dnd_delta_y) < 15 && + nux::Abs (_dnd_delta_x) < 15 && + _launcher_action_state == ACTION_NONE) return; if (_icon_under_mouse) @@ -1576,16 +1716,46 @@ void Launcher::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_ _icon_under_mouse = 0; } - _launcher_action_state = ACTION_DRAG_LAUNCHER; + if (_launcher_action_state == ACTION_NONE) + { + SetTimeStruct (&_drag_start_time); + + if (nux::Abs (_dnd_delta_y) >= nux::Abs (_dnd_delta_x)) + { + _launcher_drag_delta += _dnd_delta_y; + _launcher_action_state = ACTION_DRAG_LAUNCHER; + } + else + { + LauncherIcon *drag_icon = MouseIconIntersection ((int) (GetGeometry ().x / 2.0f), y); + + if (drag_icon) + { + StartIconDrag (drag_icon); + _launcher_action_state = ACTION_DRAG_ICON; + UpdateDragWindowPosition (x, y); + } + + } + } + else if (_launcher_action_state == ACTION_DRAG_LAUNCHER) + { + _launcher_drag_delta += dy; + } + else if (_launcher_action_state == ACTION_DRAG_ICON) + { + UpdateDragWindowPosition (x, y); + } + EnsureAnimation (); } void Launcher::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); + SetMousePosition (x, y); _mouse_inside_launcher = true; - SetHover (); + EnsureHoverState (); EventLogic (); EnsureAnimation (); @@ -1593,11 +1763,11 @@ void Launcher::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); + SetMousePosition (x, y); _mouse_inside_launcher = false; - if (_launcher_action_state != ACTION_DRAG_LAUNCHER) - UnsetHover (); + if (_launcher_action_state == ACTION_NONE) + EnsureHoverState (); EventLogic (); EnsureAnimation (); @@ -1605,7 +1775,7 @@ void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned void Launcher::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) { - _mouse_position = nux::Point2 (x, y); + SetMousePosition (x, y); // Every time the mouse moves, we check if it is inside an icon... EventLogic (); @@ -1613,11 +1783,42 @@ void Launcher::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_ void Launcher::RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags) { + if (!_hovered) + return; + + if (wheel_delta < 0) + { + // scroll up + _launcher_drag_delta += 10; + } + else + { + // scroll down + _launcher_drag_delta -= 10; + } + + EnsureAnimation (); +} + +void Launcher::RecvQuicklistOpened (QuicklistView *quicklist) +{ + EventLogic (); + EnsureHoverState (); + EnsureAnimation (); +} + +void Launcher::RecvQuicklistClosed (QuicklistView *quicklist) +{ + SetupAutohideTimer (); + + EventLogic (); + EnsureHoverState (); + EnsureAnimation (); } void Launcher::EventLogic () { - if (_launcher_action_state == ACTION_DRAG_LAUNCHER) + if (_launcher_action_state != ACTION_NONE) return; LauncherIcon* launcher_icon = 0; @@ -1661,7 +1862,7 @@ void Launcher::MouseUpLogic (int x, int y, unsigned long button_flags, unsigned { _icon_mouse_down->MouseUp.emit (nux::GetEventButton (button_flags)); - if (_launcher_action_state != ACTION_DRAG_LAUNCHER) + if (_launcher_action_state == ACTION_NONE) _icon_mouse_down->MouseClick.emit (nux::GetEventButton (button_flags)); } @@ -1785,22 +1986,30 @@ void Launcher::UpdateIconXForm (std::list<Launcher::RenderArg> &args) std::list<Launcher::RenderArg>::iterator it; for(it = args.begin(); it != args.end(); it++) { - if ((*it).skip) - continue; LauncherIcon* launcher_icon = (*it).icon; // We to store the icon angle in the icons itself. Makes one thing easier afterward. - launcher_icon->_folding_angle = (*it).folding_rads; + launcher_icon->_folding_angle = (*it).x_rotation; float w = _icon_size; float h = _icon_size; - float x = (*it).center.x - w/2.0f; // x: top left corner - float y = (*it).center.y - h/2.0f; // y: top left corner - float z = (*it).center.z; + float x = (*it).render_center.x - w/2.0f; // x: top left corner + float y = (*it).render_center.y - h/2.0f; // y: top left corner + float z = (*it).render_center.z; + if ((*it).skip) + { + w = 1; + h = 1; + x = -100; + y = -100; + } + ObjectMatrix = nux::Matrix4::TRANSLATE(geo.width/2.0f, geo.height/2.0f, z) * // Translate the icon to the center of the viewport - nux::Matrix4::ROTATEX((*it).folding_rads) * // rotate the icon + nux::Matrix4::ROTATEX((*it).x_rotation) * // rotate the icon + nux::Matrix4::ROTATEY((*it).y_rotation) * + nux::Matrix4::ROTATEZ((*it).z_rotation) * nux::Matrix4::TRANSLATE(-x - w/2.0f, -y - h/2.0f, -z); // Put the center the icon to (0, 0) ViewProjectionMatrix = ProjectionMatrix*ViewMatrix*ObjectMatrix; @@ -1809,25 +2018,25 @@ void Launcher::UpdateIconXForm (std::list<Launcher::RenderArg> &args) w = _icon_image_size; h = _icon_image_size; - x = (*it).center.x - _icon_size/2.0f + _icon_image_size_delta/2.0f; - y = (*it).center.y - _icon_size/2.0f + _icon_image_size_delta/2.0f; - z = (*it).center.z; + x = (*it).render_center.x - _icon_size/2.0f + _icon_image_size_delta/2.0f; + y = (*it).render_center.y - _icon_size/2.0f + _icon_image_size_delta/2.0f; + z = (*it).render_center.z; SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "Image"); w = _icon_glow_size; h = _icon_glow_size; - x = (*it).center.x - _icon_glow_size/2.0f; - y = (*it).center.y - _icon_glow_size/2.0f; - z = (*it).center.z; + x = (*it).render_center.x - _icon_glow_size/2.0f; + y = (*it).render_center.y - _icon_glow_size/2.0f; + z = (*it).render_center.z; SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "Glow"); w = geo.width + 2; h = _icon_size + _space_between_icons; - x = (*it).center.x - w/2.0f; - y = (*it).center.y - h/2.0f; - z = (*it).center.z; + x = (*it).logical_center.x - w/2.0f; + y = (*it).logical_center.y - h/2.0f; + z = (*it).logical_center.z; SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "HitArea"); } @@ -1909,65 +2118,128 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P float AspectRatio = (float)ViewportWidth/(float)ViewportHeight; float CameraToScreenDistance = -1.0f; - float y_cs = -CameraToScreenDistance*tanf(0.5f*Fovy/* *3.1415926/180.0f*/); + float y_cs = -CameraToScreenDistance*tanf(0.5f*Fovy/* *M_PI/180.0f*/); float x_cs = y_cs*AspectRatio; - //float CameraToScreenDistance = -y_cs*1.0f/(tanf(0.5f*Fovy/* *3.1415926/180.0f*/)); ViewMatrix = nux::Matrix4::TRANSLATE(-x_cs, y_cs, CameraToScreenDistance) * nux::Matrix4::SCALE(2.0f*x_cs/ViewportWidth, -2.0f*y_cs/ViewportHeight, -2.0f * 3 * y_cs/ViewportHeight /* or -2.0f * x_cs/ViewportWidth*/ ); PerspectiveMatrix.Perspective(Fovy, AspectRatio, NearClipPlane, FarClipPlane); +} -// // Example usage with the matrices above: -// float W = 300; -// float H = 300; -// // centered quad -// float X = (ViewportWidth - W)/2.0; -// float Y = (ViewportHeight - H)/2.0; -// float Z = 0.0f; -// -// { -// glPushMatrix(); -// // Local Transformation of the object -// glTranslatef(0.0f, 0.0f, ObjectDistanceToCamera); -// glTranslatef(X + W/2.0f, Y + H/2.0f, 0.0f); -// glRotatef(cameraAngleY, 1, 0, 0); -// glRotatef(cameraAngleX, 0, 1, 0); -// glTranslatef(-X - W/2.0f, -Y - H/2.0f, 0.0f); -// -// glBegin(GL_QUADS); -// { -// glNormal3f(0.0f, 0.0f, 1.0f); -// -// glColor4f(1.0f, 0.0f, 0.0f, 1.0f); -// glVertex4f(X, Y, Z, 1.0f); -// -// glColor4f(0.0f, 1.0f, 0.0f, 1.0f); -// glVertex4f(X, Y+H, Z, 1.0f); -// -// glColor4f(0.0f, 0.0f, 1.0f, 1.0f); -// glVertex4f(X+W, Y+H, Z, 1.0f); -// -// glColor4f(0.0f, 1.0f, 1.0f, 1.0f); -// glVertex4f(X+W, Y, Z, 1.0f); -// } -// glEnd(); -} - -void Launcher::SetActiveQuicklist (QuicklistView *quicklist) -{ - // Assert: _active_quicklist should be 0 - _active_quicklist = quicklist; -} - -QuicklistView *Launcher::GetActiveQuicklist () -{ - return _active_quicklist; -} - -void Launcher::CancelActiveQuicklist (QuicklistView *quicklist) -{ - if (_active_quicklist == quicklist) - _active_quicklist = 0; +void +Launcher::RenderIconToTexture (nux::GraphicsEngine& GfxContext, LauncherIcon *icon, nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture) +{ + RenderArg arg; + struct timespec current; + clock_gettime (CLOCK_MONOTONIC, ¤t); + + SetupRenderArg (icon, current, arg); + arg.render_center = nux::Point3 (_icon_size / 2.0f, _icon_size / 2.0f, 0.0f); + arg.logical_center = arg.render_center; + arg.x_rotation = 0.0f; + arg.running_arrow = false; + arg.active_arrow = false; + arg.skip = false; + arg.window_indicators = 0; + arg.alpha = 1.0f; + + std::list<Launcher::RenderArg> drag_args; + drag_args.push_front (arg); + UpdateIconXForm (drag_args); + + SetOffscreenRenderTarget (texture); + DrawRenderArg (nux::GetGraphicsEngine (), arg, nux::Geometry (0, 0, _icon_size, _icon_size)); + RestoreSystemRenderTarget (); } +void +Launcher::RenderProgressToTexture (nux::GraphicsEngine& GfxContext, nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture, float progress_fill, float bias) +{ + int width = texture->GetWidth (); + int height = texture->GetHeight (); + + int progress_width = _progress_bar_trough->GetWidth (); + int progress_height = _progress_bar_trough->GetHeight (); + + int fill_width = _progress_bar_fill->GetWidth (); + int fill_height = _progress_bar_fill->GetHeight (); + + int fill_offset = (progress_width - fill_width) / 2; + + /* We need to perform a barn doors effect to acheive the slide in and out */ + + int left_edge = width / 2 - progress_width / 2; + int right_edge = width / 2 + progress_width / 2; + + if (bias < 0.0f) + { + // pulls the right edge in + right_edge -= (int) (-bias * (float) progress_width); + } + else if (bias > 0.0f) + { + // pulls the left edge in + left_edge += (int) (bias * progress_width); + } + + int fill_y = (height - fill_height) / 2; + int progress_y = (height - progress_height) / 2; + int half_size = (right_edge - left_edge) / 2; + + SetOffscreenRenderTarget (texture); + + // FIXME + glClear (GL_COLOR_BUFFER_BIT); + nux::TexCoordXForm texxform; + + fill_width *= progress_fill; + + // left door + GfxContext.PushClippingRectangle(nux::Geometry (left_edge, 0, half_size, height)); + + GfxContext.QRP_GLSL_1Tex (left_edge, progress_y, progress_width, progress_height, + _progress_bar_trough->GetDeviceTexture (), texxform, nux::Color::White); + + GfxContext.QRP_GLSL_1Tex (left_edge + fill_offset, fill_y, fill_width, fill_height, + _progress_bar_fill->GetDeviceTexture (), texxform, nux::Color::White); + + GfxContext.PopClippingRectangle (); + + + // right door + GfxContext.PushClippingRectangle(nux::Geometry (left_edge + half_size, 0, half_size, height)); + + GfxContext.QRP_GLSL_1Tex (right_edge - progress_width, progress_y, progress_width, progress_height, + _progress_bar_trough->GetDeviceTexture (), texxform, nux::Color::White); + + GfxContext.QRP_GLSL_1Tex (right_edge - progress_width + fill_offset, fill_y, fill_width, fill_height, + _progress_bar_fill->GetDeviceTexture (), texxform, nux::Color::White); + + GfxContext.PopClippingRectangle (); + + + RestoreSystemRenderTarget (); +} + +void +Launcher::SetOffscreenRenderTarget (nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture) +{ + int width = texture->GetWidth (); + int height = texture->GetHeight (); + + nux::GetThreadGLDeviceFactory ()->FormatFrameBufferObject (width, height, nux::BITFMT_R8G8B8A8); + nux::GetThreadGLDeviceFactory ()->SetColorRenderTargetSurface (0, texture->GetSurfaceLevel (0)); + nux::GetThreadGLDeviceFactory ()->ActivateFrameBuffer (); + + nux::GetThreadGraphicsContext ()->SetContext (0, 0, width, height); + nux::GetThreadGraphicsContext ()->SetViewport (0, 0, width, height); + nux::GetThreadGraphicsContext ()->Push2DWindow (width, height); + nux::GetThreadGraphicsContext ()->EmptyClippingRegion(); +} + +void +Launcher::RestoreSystemRenderTarget () +{ + nux::GetWindowCompositor ().RestoreRenderingSurface (); +} diff --git a/src/Launcher.h b/src/Launcher.h index b55111c2d..b759683c5 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -27,8 +27,10 @@ #include <Nux/BaseWindow.h> #include "Introspectable.h" #include "LauncherIcon.h" +#include "LauncherDragWindow.h" #include "NuxGraphics/IOpenGLAsmShader.h" #include "Nux/TimerProc.h" +#include "PluginAdapter.h" class LauncherModel; class QuicklistView; @@ -36,54 +38,45 @@ class QuicklistView; class Launcher : public Introspectable, public nux::View { public: - Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_PROTO); - ~Launcher(); + Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_PROTO); + ~Launcher(); - 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 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); - LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;} - LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;} + LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;} + LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;} - bool TooltipNotify(LauncherIcon* Icon); - bool MenuNotify(LauncherIcon* Icon); + void SetIconSize(int tile_size, int icon_size); - void SetIconSize(int tile_size, int icon_size); - void NotifyMenuTermination(LauncherIcon* Icon); + void SetModel (LauncherModel *model); - void SetModel (LauncherModel *model); + void SetFloating (bool floating); - void SetFloating (bool floating); + void SetAutohide (bool autohide, nux::View *show_trigger); + bool AutohideEnabled (); + + nux::BaseWindow* GetParent () { return _parent; }; - void SetAutohide (bool autohide, nux::View *show_trigger); - bool AutohideEnabled (); + virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + virtual void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags); - void OnWindowMoved (CompWindow *window); - void OnWindowResized (CompWindow *window); - void OnWindowAppear (CompWindow *window); - void OnWindowDisappear (CompWindow *window); - - virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); - virtual void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags); - - //! Called by LauncherIcon to signal that a Quicklist is becoming active. - void SetActiveQuicklist (QuicklistView *quicklist); - //! Get the active qicklist - QuicklistView *GetActiveQuicklist (); - //! Called by LauncherIcon to signal that a Quicklist is becoming unactive. - void CancelActiveQuicklist (QuicklistView *quicklist); + virtual void RecvQuicklistOpened (QuicklistView *quicklist); + virtual void RecvQuicklistClosed (QuicklistView *quicklist); + sigc::signal<void, LauncherIcon *, LauncherIcon *, bool> request_reorder_smart; + sigc::signal<void, LauncherIcon *, LauncherIcon *, bool> request_reorder_before; protected: - // Introspectable methods - const gchar* GetName (); - void AddProperties (GVariantBuilder *builder); + // Introspectable methods + const gchar* GetName (); + void AddProperties (GVariantBuilder *builder); private: typedef enum @@ -102,24 +95,37 @@ private: typedef struct { LauncherIcon *icon; - nux::Point3 center; - float folding_rads; + nux::Point3 render_center; + nux::Point3 logical_center; + float x_rotation; + float y_rotation; + float z_rotation; float alpha; float backlight_intensity; float glow_intensity; float shimmer_progress; + float progress; + float progress_bias; bool running_arrow; bool running_colored; bool active_arrow; bool active_colored; bool skip; + bool stick_thingy; int window_indicators; } RenderArg; + void OnWindowMaybeIntellihide (CompWindow *window); + static gboolean AnimationTimeout (gpointer data); static gboolean OnAutohideTimeout (gpointer data); static gboolean StrutHack (gpointer data); + + void SetMousePosition (int x, int y); + + bool MouseBeyondDragThreshold (); + void OnDragWindowAnimCompleted (); void OnTriggerMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnTriggerMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); @@ -127,21 +133,26 @@ private: bool AnimationInProgress (); void SetTimeStruct (struct timespec *timer, struct timespec *sister = 0, int sister_relation = 0); + void EnsureHoverState (); void EnsureHiddenState (); void EnsureAnimation (); void SetupAutohideTimer (); void CheckWindowOverLauncher (); - float DnDExitProgress (struct timespec const ¤t); - float GetHoverProgress (struct timespec const ¤t); - float AutohideProgress (struct timespec const ¤t); + float DnDStartProgress (struct timespec const ¤t); + float DnDExitProgress (struct timespec const ¤t); + float GetHoverProgress (struct timespec const ¤t); + float AutohideProgress (struct timespec const ¤t); + float DragThresholdProgress (struct timespec const ¤t); float IconPresentProgress (LauncherIcon *icon, struct timespec const ¤t); float IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t); float IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t); float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t); float IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t); float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t); + float IconProgressBias (LauncherIcon *icon, struct timespec const ¤t); + float IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t); void SetHover (); void UnsetHover (); @@ -151,16 +162,27 @@ private: float DragLimiter (float x); void SetupRenderArg (LauncherIcon *icon, struct timespec const ¤t, RenderArg &arg); + void FillRenderArg (LauncherIcon *icon, + RenderArg &arg, + nux::Point3 ¢er, + float folding_threshold, + float folded_size, + float folded_spacing, + float autohide_offset, + float folded_z_distance, + float animation_neg_rads, + struct timespec const ¤t); + void RenderArgs (std::list<Launcher::RenderArg> &launcher_args, nux::Geometry &box_geo); void DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const &arg, nux::Geometry geo); - void OnIconAdded (void *icon_pointer); - void OnIconRemoved (void *icon_pointer); + void OnIconAdded (LauncherIcon *icon); + void OnIconRemoved (LauncherIcon *icon); void OnOrderChanged (); - void OnIconNeedsRedraw (void *icon); + void OnIconNeedsRedraw (LauncherIcon *icon); void RenderIndicators (nux::GraphicsEngine& GfxContext, RenderArg const &arg, @@ -170,11 +192,13 @@ private: void RenderIcon (nux::GraphicsEngine& GfxContext, RenderArg const &arg, - nux::BaseTexture *icon, + nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon, nux::Color bkg_color, float alpha, - nux::Vector4 xform_coords[], - nux::Geometry geo); + nux::Vector4 xform_coords[]); + + void RenderIconToTexture (nux::GraphicsEngine& GfxContext, LauncherIcon *icon, nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture); + void RenderProgressToTexture (nux::GraphicsEngine& GfxContext, nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture, float progress_fill, float bias); void SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry geo, float x, float y, float w, float h, float z, std::string name); @@ -184,11 +208,17 @@ private: void EventLogic (); void MouseDownLogic (int x, int y, unsigned long button_flags, unsigned long key_flags); void MouseUpLogic (int x, int y, unsigned long button_flags, unsigned long key_flags); + + void StartIconDrag (LauncherIcon *icon); + void EndIconDrag (); + void UpdateDragWindowPosition (int x, int y); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void PositionChildLayout(float offsetX, float offsetY); + void SetOffscreenRenderTarget (nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture); + void RestoreSystemRenderTarget (); nux::HLayout* m_Layout; int m_ContentOffsetY; @@ -206,6 +236,7 @@ private: bool _mouse_inside_launcher; bool _mouse_inside_trigger; bool _window_over_launcher; + bool _render_drag_window; float _folded_angle; float _neg_folded_angle; @@ -215,15 +246,19 @@ private: LauncherState _launcher_state; LauncherActionState _launcher_action_state; + LauncherIcon* _icon_under_mouse; LauncherIcon* _icon_mouse_down; + LauncherIcon* _drag_icon; int _space_between_icons; int _icon_size; int _icon_image_size; int _icon_image_size_delta; int _icon_glow_size; - int _dnd_delta; + int _dnd_delta_y; + int _dnd_delta_x; + int _launcher_drag_delta; int _dnd_security; int _enter_y; @@ -231,11 +266,12 @@ private: nux::BaseTexture* _icon_shine_texture; nux::BaseTexture* _icon_outline_texture; nux::BaseTexture* _icon_glow_texture; - nux::BaseTexture* _icon_2indicator; - nux::BaseTexture* _icon_3indicator; - nux::BaseTexture* _icon_4indicator; + nux::BaseTexture* _progress_bar_trough; + nux::BaseTexture* _progress_bar_fill; + + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_drag_texture; + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_progress_texture; - guint _anim_handle; guint _autohide_handle; nux::Matrix4 _view_matrix; @@ -249,6 +285,7 @@ private: nux::BaseWindow* _parent; nux::View* _autohide_trigger; LauncherModel* _model; + LauncherDragWindow* _drag_window; CompScreen* _screen; @@ -256,6 +293,8 @@ private: struct timespec _enter_time; struct timespec _exit_time; struct timespec _drag_end_time; + struct timespec _drag_start_time; + struct timespec _drag_threshold_time; struct timespec _autohide_time; }; diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp index 43d45675e..c295554c7 100644 --- a/src/LauncherController.cpp +++ b/src/LauncherController.cpp @@ -41,6 +41,9 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n g_timeout_add (5000, (GSourceFunc) &LauncherController::BamfTimerCallback, this); InsertExpoAction (); InsertTrash (); + + _launcher->request_reorder_smart.connect (sigc::mem_fun (this, &LauncherController::OnLauncherRequestReorderSmart)); + _launcher->request_reorder_before.connect (sigc::mem_fun (this, &LauncherController::OnLauncherRequestReorderBefore)); } LauncherController::~LauncherController() @@ -48,41 +51,130 @@ LauncherController::~LauncherController() _favorite_store->UnReference (); } -void -LauncherController::PresentIconOwningWindow (Window window) +void +LauncherController::SortAndSave () { LauncherModel::iterator it; - LauncherIcon *owner = 0; + _model->Sort (&LauncherController::CompareIcons); + std::list<const char*> desktop_paths; for (it = _model->begin (); it != _model->end (); it++) { - if ((*it)->IconOwnsWindow (window)) - { - owner = *it; - break; - } + BamfLauncherIcon *icon; + icon = dynamic_cast<BamfLauncherIcon*> (*it); + + if (!icon) + continue; + + if (!icon->IsSticky ()) + continue; + + const char* desktop_file = icon->DesktopFile (); + + if (desktop_file && strlen (desktop_file) > 0) + desktop_paths.push_back (desktop_file); } - for (it = _model->shelf_begin (); !owner && it != _model->shelf_end (); it++) + _favorite_store->SetFavorites (desktop_paths); +} + +void +LauncherController::OnLauncherRequestReorderBefore (LauncherIcon *icon, LauncherIcon *other, bool save) +{ + if (icon == other) + return; + + LauncherModel::iterator it; + + int i = 0; + int j = 0; + for (it = _model->begin (); it != _model->end (); it++) { - if ((*it)->IconOwnsWindow (window)) + if ((*it) == icon) + { + j++; + continue; + } + + if ((*it) == other) + { + icon->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + + (*it)->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + } + else { - owner = *it; - break; + (*it)->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; } + j++; } - if (owner) + SortAndSave (); +} + +void +LauncherController::OnLauncherRequestReorderSmart (LauncherIcon *icon, LauncherIcon *other, bool save) +{ + if (icon == other) + return; + + LauncherModel::iterator it; + + int i = 0; + int j = 0; + bool skipped = false; + for (it = _model->begin (); it != _model->end (); it++) { - owner->Present (0.5f, 600); - owner->UpdateQuirkTimeDelayed (300, LAUNCHER_ICON_QUIRK_SHIMMER); + if ((*it) == icon) + { + skipped = true; + j++; + continue; + } + + if ((*it) == other) + { + if (!skipped) + { + icon->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + } + + (*it)->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + + if (skipped) + { + icon->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + } + } + else + { + (*it)->SetSortPriority (i); + if (i != j && save) (*it)->SaveCenter (); + i++; + } + j++; } + + SortAndSave (); } void LauncherController::OnExpoClicked (int button) { - PluginAdapter::Default ()->InitiateExpo (); + if (button == 1) + PluginAdapter::Default ()->InitiateExpo (); } void @@ -135,12 +227,6 @@ LauncherController::RegisterIcon (LauncherIcon *icon) (*it)->SetSortPriority (i); i++; } - - for (it = _model->shelf_begin (); it != _model->shelf_end (); it++) - { - (*it)->SetSortPriority (i); - i++; - } } /* static private */ @@ -193,7 +279,8 @@ LauncherController::CreateFavorite (const char *file_path) bamf_view_set_sticky (BAMF_VIEW (app), true); icon = new BamfLauncherIcon (_launcher, app, _screen); - icon->SetIconType (LAUNCHER_ICON_TYPE_FAVORITE); + icon->SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); + icon->SetSortPriority (_sort_priority++); return icon; } diff --git a/src/LauncherController.h b/src/LauncherController.h index 8fffa56e1..a63afd150 100644 --- a/src/LauncherController.h +++ b/src/LauncherController.h @@ -43,8 +43,6 @@ public: LauncherController(Launcher* launcher, CompScreen *screen, nux::BaseWindow* window); ~LauncherController(); - void PresentIconOwningWindow (Window window); - private: BamfMatcher* _matcher; CompAction* _expo_action; @@ -55,6 +53,11 @@ private: FavoriteStore* _favorite_store; int _sort_priority; + void SortAndSave (); + + void OnLauncherRequestReorderSmart (LauncherIcon *icon, LauncherIcon *other, bool save); + void OnLauncherRequestReorderBefore (LauncherIcon *icon, LauncherIcon *before, bool save); + void InsertExpoAction (); void InsertTrash (); diff --git a/src/LauncherDragWindow.cpp b/src/LauncherDragWindow.cpp new file mode 100644 index 000000000..7fe189e63 --- /dev/null +++ b/src/LauncherDragWindow.cpp @@ -0,0 +1,117 @@ +/* +* 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: Jason Smith <jason.smith@canonical.com> +*/ + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "NuxGraphics/GraphicsEngine.h" +#include "Nux/TextureArea.h" + +#include "LauncherDragWindow.h" + +NUX_IMPLEMENT_OBJECT_TYPE (LauncherDragWindow); + +LauncherDragWindow::LauncherDragWindow (nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon) +: nux::BaseWindow ("") +{ + _icon = icon; + _anim_handle = 0; + SetBaseSize (_icon->GetWidth(), _icon->GetHeight()); +} + +LauncherDragWindow::~LauncherDragWindow () +{ + if (_anim_handle) + g_source_remove (_anim_handle); +} + +bool +LauncherDragWindow::Animating () +{ + return _anim_handle != 0; +} + +void +LauncherDragWindow::SetAnimationTarget (int x, int y) +{ + _animation_target = nux::Point2 (x, y); +} + +void +LauncherDragWindow::StartAnimation () +{ + if (_anim_handle) + return; + + _anim_handle = g_timeout_add (15, &LauncherDragWindow::OnAnimationTimeout, this); +} + +gboolean +LauncherDragWindow::OnAnimationTimeout (gpointer data) +{ + LauncherDragWindow *self = (LauncherDragWindow*) data; + nux::Geometry geo = self->GetGeometry (); + + int half_size = geo.width / 2; + + int target_x = (int) (self->_animation_target.x) - half_size; + int target_y = (int) (self->_animation_target.y) - half_size; + + int x_delta = (int) ((float) (target_x - geo.x) * .3f); + if (abs (x_delta) < 5) + x_delta = (x_delta >= 0) ? MIN (5, target_x - geo.x) : MAX (-5, target_x - geo.x); + + int y_delta = (int) ((float) (target_y - geo.y) * .3f); + if (abs (y_delta) < 5) + y_delta = (y_delta >= 0) ? MIN (5, target_y - geo.y) : MAX (-5, target_y - geo.y); + + self->SetBaseXY (geo.x + x_delta, geo.y + y_delta); + + geo = self->GetGeometry (); + + if (geo.x == target_x && geo.y == target_y) + { + self->anim_completed.emit (); + self->_anim_handle = 0; + return false; + } + + return true; +} + +void +LauncherDragWindow::DrawContent (nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry geo = GetGeometry (); + geo.SetX (0); + geo.SetY (0); + + GfxContext.PushClippingRectangle (geo); + + nux::TexCoordXForm texxform; + texxform.FlipVCoord (true); + + GfxContext.QRP_GLSL_1Tex (0, + 0, + _icon->GetWidth(), + _icon->GetHeight(), + _icon, + texxform, + nux::Color::White); + + GfxContext.PopClippingRectangle (); +} diff --git a/src/LauncherDragWindow.h b/src/LauncherDragWindow.h new file mode 100644 index 000000000..9e4853834 --- /dev/null +++ b/src/LauncherDragWindow.h @@ -0,0 +1,56 @@ +/* + * 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: Jason Smith <jason.smith@canonical.com> + */ + +#ifndef LAUNCHERDRAGWINDOW_H +#define LAUNCHERDRAGWINDOW_H + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "NuxGraphics/GraphicsEngine.h" + +#include "LauncherIcon.h" + +class LauncherDragWindow : public nux::BaseWindow +{ + NUX_DECLARE_OBJECT_TYPE (LauncherDragWindow, nux::BaseWindow); +public: + LauncherDragWindow (nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon); + + ~LauncherDragWindow (); + + void DrawContent (nux::GraphicsEngine& gfxContext, bool forceDraw); + + void SetAnimationTarget (int x, int y); + void StartAnimation (); + + bool Animating (); + + sigc::signal<void> anim_completed; + +private: + + static gboolean OnAnimationTimeout (gpointer data); + + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _icon; + nux::Point2 _animation_target; + guint32 _anim_handle; + +}; + +#endif // LAUNCHERDRAGWINDOW_H + diff --git a/src/LauncherIcon.cpp b/src/LauncherIcon.cpp index d78eace30..8471a3d2b 100644 --- a/src/LauncherIcon.cpp +++ b/src/LauncherIcon.cpp @@ -31,6 +31,7 @@ #include "LauncherIcon.h" #include "Launcher.h" +#include "QuicklistManager.h" #include "QuicklistMenuItem.h" #include "QuicklistMenuItemLabel.h" #include "QuicklistMenuItemSeparator.h" @@ -66,9 +67,9 @@ LauncherIcon::LauncherIcon(Launcher* launcher) _sort_priority = 0; _quicklist = new QuicklistView (); - _quicklist->sigVisible.connect (sigc::mem_fun (this, &LauncherIcon::RecvShowQuicklist)); - _quicklist->sigHidden.connect (sigc::mem_fun (this, &LauncherIcon::RecvHideQuicklist)); _quicklist_is_initialized = false; + + QuicklistManager::Default ()->RegisterQuicklist (_quicklist); // Add to introspection AddChild (_quicklist); @@ -292,14 +293,14 @@ nux::NString LauncherIcon::GetTooltipText() void LauncherIcon::RecvMouseEnter () { - if (_launcher->GetActiveQuicklist ()) + if (QuicklistManager::Default ()->Current ()) { // A quicklist is active return; } int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; _tooltip->ShowTooltipWithTipAt (tip_x, tip_y); @@ -318,26 +319,6 @@ void LauncherIcon::RecvMouseDown (int button) { if (button == 3) { - if (_launcher->GetActiveQuicklist () == _quicklist) - { - // this quicklist is already active - return; - } - - if (_launcher->GetActiveQuicklist ()) - { - // Hide the active quicklist. This will prevent it from Ungrabing the pointer in - // QuicklistView::RecvMouseDownOutsideOfQuicklist or void QuicklistView::RecvMouseClick. - // So the new quicklist that is about to be set as active will keep the grab of the pointer. - // Also disable theinput window. - _launcher->GetActiveQuicklist ()->EnableInputWindow (false); - _launcher->GetActiveQuicklist ()->CaptureMouseDownAnyWhereElse (false); - // This call must be last, because after, _launcher->GetActiveQuicklist () will return Null. - // the launcher listen to the sigHidden signal emitted by the BaseWindow when it becomes invisible - // and it set the active window to Null. - _launcher->GetActiveQuicklist ()->ShowWindow (false); - } - _tooltip->ShowWindow (false); _quicklist->RemoveAllMenuItem (); @@ -377,15 +358,9 @@ void LauncherIcon::RecvMouseDown (int button) } int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; - _quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); - - _quicklist->EnableInputWindow (true, 1); - _quicklist->GrabPointer (); - + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; + QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y); nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_quicklist); - - _quicklist->NeedRedraw (); } } @@ -398,16 +373,6 @@ void LauncherIcon::RecvMouseUp (int button) } } -void LauncherIcon::RecvShowQuicklist (nux::BaseWindow *quicklist) -{ - _launcher->SetActiveQuicklist (_quicklist); -} - -void LauncherIcon::RecvHideQuicklist (nux::BaseWindow *quicklist) -{ - _launcher->CancelActiveQuicklist (_quicklist); -} - void LauncherIcon::HideTooltip () { _tooltip->ShowWindow (false); @@ -434,10 +399,10 @@ LauncherIcon::SetCenter (nux::Point3 center) _center = center; int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; if (_quicklist->IsVisible ()) - _quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); + QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y); else if (_tooltip->IsVisible ()) _tooltip->ShowTooltipWithTipAt (tip_x, tip_y); @@ -453,6 +418,13 @@ LauncherIcon::GetCenter () return _center; } +void +LauncherIcon::SaveCenter () +{ + _saved_center = _center; + UpdateQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); +} + gboolean LauncherIcon::OnPresentTimeout (gpointer data) { @@ -608,6 +580,22 @@ LauncherIcon::RelatedWindows () return _related_windows; } +void +LauncherIcon::SetProgress (float progress) +{ + if (progress == _progress) + return; + + _progress = progress; + needs_redraw.emit (this); +} + +float +LauncherIcon::GetProgress () +{ + return _progress; +} + std::list<DbusmenuMenuitem *> LauncherIcon::Menus () { return GetMenus (); diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h index 145775dc5..1ba0821cb 100644 --- a/src/LauncherIcon.h +++ b/src/LauncherIcon.h @@ -61,6 +61,8 @@ typedef enum LAUNCHER_ICON_QUIRK_PRESENTED, LAUNCHER_ICON_QUIRK_STARTING, LAUNCHER_ICON_QUIRK_SHIMMER, + LAUNCHER_ICON_QUIRK_CENTER_SAVED, + LAUNCHER_ICON_QUIRK_PROGRESS, LAUNCHER_ICON_QUIRK_LAST, } LauncherIconQuirk; @@ -69,7 +71,7 @@ class LauncherIcon : public Introspectable, public nux::InitiallyUnownedObject, { public: LauncherIcon(Launcher* launcher); - ~LauncherIcon(); + virtual ~LauncherIcon(); void SetTooltipText (const TCHAR* text); @@ -80,19 +82,21 @@ public: void RecvMouseDown (int button); void RecvMouseUp (int button); - void RecvShowQuicklist (nux::BaseWindow *quicklist); - void RecvHideQuicklist (nux::BaseWindow *quicklist); - void HideTooltip (); void SetCenter (nux::Point3 center); nux::Point3 GetCenter (); + void SaveCenter (); + int SortPriority (); int RelatedWindows (); + float PresentUrgency (); + float GetProgress (); + bool GetQuirk (LauncherIconQuirk quirk); struct timespec GetQuirkTime (LauncherIconQuirk quirk); @@ -105,17 +109,16 @@ public: std::list<DbusmenuMenuitem *> Menus (); - sigc::signal<void, int> MouseDown; sigc::signal<void, int> MouseUp; sigc::signal<void> MouseEnter; sigc::signal<void> MouseLeave; sigc::signal<void, int> MouseClick; - sigc::signal<void, void *> show; - sigc::signal<void, void *> hide; - sigc::signal<void, void *> remove; - sigc::signal<void, void *> needs_redraw; + sigc::signal<void, LauncherIcon *> show; + sigc::signal<void, LauncherIcon *> hide; + sigc::signal<void, LauncherIcon *> remove; + sigc::signal<void, LauncherIcon *> needs_redraw; protected: const gchar * GetName (); void AddProperties (GVariantBuilder *builder); @@ -129,6 +132,7 @@ protected: void SetRelatedWindows (int windows); void Remove (); + void SetProgress (float progress); void Present (float urgency, int length); void Unpresent (); @@ -140,7 +144,6 @@ protected: virtual nux::BaseTexture * GetTextureForSize (int size) = 0; virtual void OnCenterStabilized (nux::Point3 center) {}; - virtual bool IconOwnsWindow (Window w) { return false; } nux::BaseTexture * TextureFromGtkTheme (const char *name, int size); nux::BaseTexture * TextureFromPath (const char *name, int size); @@ -184,12 +187,14 @@ private: int _sort_priority; int _related_windows; float _present_urgency; + float _progress; guint _present_time_handle; guint _center_stabilize_handle; bool _quicklist_is_initialized; nux::Point3 _center; nux::Point3 _last_stable; + nux::Point3 _saved_center; LauncherIconType _icon_type; bool _quirks[LAUNCHER_ICON_QUIRK_LAST]; diff --git a/src/LauncherModel.cpp b/src/LauncherModel.cpp index c109bd519..2ed6c3a7b 100644 --- a/src/LauncherModel.cpp +++ b/src/LauncherModel.cpp @@ -81,9 +81,10 @@ LauncherModel::RemoveIcon (LauncherIcon *icon) _inner.remove (icon); if (size != _inner.size ()) + { icon_removed.emit (icon); - - icon->UnReference (); + icon->UnReference (); + } } gboolean @@ -98,10 +99,10 @@ LauncherModel::RemoveCallback (gpointer data) } void -LauncherModel::OnIconRemove (void *icon_pointer) +LauncherModel::OnIconRemove (LauncherIcon *icon) { RemoveArg *arg = (RemoveArg*) g_malloc0 (sizeof (RemoveArg)); - arg->icon = (LauncherIcon*) icon_pointer; + arg->icon = icon; arg->self = this; g_timeout_add (1000, &LauncherModel::RemoveCallback, arg); @@ -114,6 +115,7 @@ LauncherModel::Sort (SortFunc func) _inner_main.sort (func); Populate (); + order_changed.emit (); } int diff --git a/src/LauncherModel.h b/src/LauncherModel.h index 6da1b3fda..2c5da9e2c 100644 --- a/src/LauncherModel.h +++ b/src/LauncherModel.h @@ -40,7 +40,7 @@ public: void Sort (SortFunc func); int Size (); - void OnIconRemove (void *icon); + void OnIconRemove (LauncherIcon *icon); iterator begin (); iterator end (); @@ -57,8 +57,8 @@ public: reverse_iterator shelf_rbegin (); reverse_iterator shelf_rend (); - sigc::signal<void, void *> icon_added; - sigc::signal<void, void *> icon_removed; + sigc::signal<void, LauncherIcon *> icon_added; + sigc::signal<void, LauncherIcon *> icon_removed; sigc::signal<void> order_changed; private: diff --git a/src/PanelHomeButton.cpp b/src/PanelHomeButton.cpp index 154a5972d..711a0d824 100644 --- a/src/PanelHomeButton.cpp +++ b/src/PanelHomeButton.cpp @@ -22,6 +22,9 @@ #include "NuxGraphics/GLThread.h" +#include "../libunity/ubus-server.h" +#include "UBusMessages.h" + #include "PanelHomeButton.h" #include <glib.h> @@ -74,17 +77,17 @@ PanelHomeButton::Refresh () cairo_destroy (cr); nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); - + // The Texture is created with a reference count of 1. nux::BaseTexture* texture2D = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture (); texture2D->Update(bitmap); delete bitmap; - + nux::TexCoordXForm texxform; texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); - - nux::ROPConfig rop; + + nux::ROPConfig rop; rop.Blend = true; // Enable the blending. By default rop.Blend is false. rop.SrcBlend = GL_ONE; // Set the source blend factor. rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; // Set the destination blend factor. @@ -98,12 +101,12 @@ PanelHomeButton::Refresh () SetPaintLayer(texture_layer); // We don't need the texture anymore. Since it hasn't been reference, it ref count should still be 1. - // UnReference it and it will be destroyed. + // UnReference it and it will be destroyed. texture2D->UnReference (); - + // The texture layer has been cloned by this object when calling SetPaintLayer. It is safe to delete it now. delete texture_layer; - + NeedRedraw (); } @@ -113,31 +116,10 @@ PanelHomeButton::RecvMouseClick (int x, unsigned long button_flags, unsigned long key_flags) { -#define APPS_URI "file:///usr/share/applications" - - /* FIXME: This is just for Alpha 1, so we have some feedback on clicking the - * PanelHomeButton, and especially because we don't have any other way of - * launching non-launcher apps right now - */ if (nux::GetEventButton (button_flags) == 1) { - GdkAppLaunchContext *context; - GError *error = NULL; - - context = gdk_app_launch_context_new (); - gdk_app_launch_context_set_screen (context, gdk_screen_get_default ()); - gdk_app_launch_context_set_timestamp (context, GDK_CURRENT_TIME); - - if (!g_app_info_launch_default_for_uri (APPS_URI, - (GAppLaunchContext *)context, - &error)) - { - g_warning ("Unable to launcher applications folder: %s", - error->message); - g_error_free (error); - } - - g_object_unref (context); + UBusServer *ubus = ubus_server_get_default (); + ubus_server_send_message (ubus, UBUS_HOME_BUTTON_ACTIVATED, NULL); } } diff --git a/src/PanelIndicatorObjectEntryView.cpp b/src/PanelIndicatorObjectEntryView.cpp index cd9a8ceee..a43f0dadd 100644 --- a/src/PanelIndicatorObjectEntryView.cpp +++ b/src/PanelIndicatorObjectEntryView.cpp @@ -31,9 +31,6 @@ #include <gtk/gtk.h> #include <time.h> -#define PANEL_HEIGHT 24 -#define PADDING 6 -#define SPACING 3 static void draw_menu_bg (cairo_t *cr, int width, int height); @@ -43,7 +40,8 @@ PanelIndicatorObjectEntryView::PanelIndicatorObjectEntryView (IndicatorObjectEnt _proxy (proxy), _util_cg (CAIRO_FORMAT_ARGB32, 1, 1) { - _proxy->Updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); + _proxy->active_changed.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnActiveChanged)); + _proxy->updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown)); @@ -55,6 +53,12 @@ PanelIndicatorObjectEntryView::~PanelIndicatorObjectEntryView () } void +PanelIndicatorObjectEntryView::OnActiveChanged (bool is_active) +{ + active_changed.emit (this, is_active); +} + +void PanelIndicatorObjectEntryView::OnMouseDown (int x, int y, long button_flags, long key_flags) { if (_proxy->GetActive ()) diff --git a/src/PanelIndicatorObjectEntryView.h b/src/PanelIndicatorObjectEntryView.h index 58c9c3606..2bc8971f8 100644 --- a/src/PanelIndicatorObjectEntryView.h +++ b/src/PanelIndicatorObjectEntryView.h @@ -28,6 +28,10 @@ #include "Introspectable.h" +#define PANEL_HEIGHT 24 +#define PADDING 6 +#define SPACING 3 + class PanelIndicatorObjectEntryView : public nux::TextureArea, public Introspectable { public: @@ -37,10 +41,13 @@ public: void Refresh (); void OnMouseDown (int x, int y, long button_flags, long key_flags); void Activate (); + void OnActiveChanged (bool is_active); const gchar * GetName (); void AddProperties (GVariantBuilder *builder); + sigc::signal<void, PanelIndicatorObjectEntryView *, bool> active_changed; + public: IndicatorObjectEntryProxy *_proxy; private: diff --git a/src/PanelIndicatorObjectView.cpp b/src/PanelIndicatorObjectView.cpp index 52936b710..a3a9f55cb 100644 --- a/src/PanelIndicatorObjectView.cpp +++ b/src/PanelIndicatorObjectView.cpp @@ -30,6 +30,13 @@ #include <glib.h> +PanelIndicatorObjectView::PanelIndicatorObjectView () +: View (NUX_TRACKER_LOCATION), + _proxy (NULL), + _entries () +{ +} + PanelIndicatorObjectView::PanelIndicatorObjectView (IndicatorObjectProxy *proxy) : View (NUX_TRACKER_LOCATION), _proxy (proxy), diff --git a/src/PanelIndicatorObjectView.h b/src/PanelIndicatorObjectView.h index cc23dbc73..0c5baf4a0 100644 --- a/src/PanelIndicatorObjectView.h +++ b/src/PanelIndicatorObjectView.h @@ -29,6 +29,7 @@ class PanelIndicatorObjectView : public nux::View, public Introspectable { public: + PanelIndicatorObjectView (); PanelIndicatorObjectView (IndicatorObjectProxy *proxy); ~PanelIndicatorObjectView (); @@ -47,7 +48,6 @@ protected: const gchar * GetChildsName (); void AddProperties (GVariantBuilder *builder); -private: IndicatorObjectProxy *_proxy; std::vector<PanelIndicatorObjectEntryView *> _entries; }; diff --git a/src/PanelMenuView.cpp b/src/PanelMenuView.cpp new file mode 100644 index 000000000..0199f1b1c --- /dev/null +++ b/src/PanelMenuView.cpp @@ -0,0 +1,671 @@ +/* + * 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 <glib.h> +#include <pango/pangocairo.h> +#include <gtk/gtk.h> + +#include "Nux/Nux.h" +#include "Nux/HLayout.h" +#include "Nux/VLayout.h" +#include <Nux/TextureArea.h> + +#include "NuxGraphics/GLThread.h" +#include "Nux/BaseWindow.h" +#include "Nux/WindowCompositor.h" + +#include "PanelMenuView.h" + +#include "WindowManager.h" + +#include "IndicatorObjectEntryProxy.h" + +#include <gio/gdesktopappinfo.h> + +#define BUTTONS_WIDTH 72 + +static void on_active_window_changed (BamfMatcher *matcher, + BamfView *old_view, + BamfView *new_view, + PanelMenuView *self); + + +PanelMenuView::PanelMenuView () +: _matcher (NULL), + _title_layer (NULL), + _util_cg (CAIRO_FORMAT_ARGB32, 1, 1), + _gradient_texture (NULL), + _title_tex (NULL), + _is_inside (false), + _is_maximized (false), + _last_active_view (NULL) +{ + WindowManager *win_manager; + + _matcher = bamf_matcher_get_default (); + g_signal_connect (_matcher, "active-window-changed", + G_CALLBACK (on_active_window_changed), this); + + _menu_layout = new nux::HLayout ("", NUX_TRACKER_LOCATION); + + /* This is for our parent and for PanelView to read indicator entries, we + * shouldn't touch this again + */ + _layout = _menu_layout; + + _window_buttons = new WindowButtons (); + _window_buttons->NeedRedraw (); + _window_buttons->close_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnCloseClicked)); + _window_buttons->minimize_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnMinimizeClicked)); + _window_buttons->restore_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnRestoreClicked)); + _window_buttons->redraw_signal.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowButtonsRedraw)); + + win_manager = WindowManager::Default (); + win_manager->window_maximized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMaximized)); + win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored)); + win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped)); + + Refresh (); +} + +PanelMenuView::~PanelMenuView () +{ + if (_title_layer) + delete _title_layer; + if (_title_tex) + _title_tex->UnReference (); + + _menu_layout->UnReference (); + _window_buttons->UnReference (); +} + +void +PanelMenuView::FullRedraw () +{ + _menu_layout->NeedRedraw (); + _window_buttons->NeedRedraw (); + NeedRedraw (); +} + +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)); + _proxy->OnEntryRemoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryRemoved)); +} + +long +PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) +{ + long ret = TraverseInfo; + nux::Geometry geo = GetGeometry (); + + if (geo.IsPointInside (ievent.e_x, ievent.e_y)) + { + if (_is_inside != true) + { + _is_inside = true; + FullRedraw (); + } + } + else + { + if (_is_inside != false) + { + _is_inside = false; + FullRedraw (); + } + } + + if (_is_maximized) + ret = _window_buttons->ProcessEvent (ievent, ret, ProcessEventInfo); + ret = _menu_layout->ProcessEvent (ievent, ret, ProcessEventInfo); + + return ret; +} + +long PanelMenuView::PostLayoutManagement (long LayoutResult) +{ + long res = View::PostLayoutManagement (LayoutResult); + int w = _window_buttons->GetContentWidth (); + + nux::Geometry geo = GetGeometry (); + + _window_buttons->SetGeometry (geo.x + PADDING, geo.y, w, geo.height); + _window_buttons->ComputeLayout2 (); + + /* Explicitly set the size and position of the widgets */ + geo.x += PADDING + w + PADDING; + geo.width -= PADDING + w + PADDING; + + _menu_layout->SetGeometry (geo.x, geo.y, geo.width, geo.height); + _menu_layout->ComputeLayout2(); + + Refresh (); + + return res; +} + +void +PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry geo = GetGeometry (); + int button_width = PADDING + _window_buttons->GetContentWidth () + PADDING; + float factor = 4; + button_width /= factor; + + GfxContext.PushClippingRectangle (geo); + + /* "Clear" out the background */ + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + nux::ColorLayer layer (nux::Color (0x00000000), true, rop); + gPainter.PushDrawLayer (GfxContext, GetGeometry (), &layer); + + if (_is_maximized) + { + if (!_is_inside) + gPainter.PushDrawLayer (GfxContext, GetGeometry (), _title_layer); + } + else + { + if (_is_inside || _last_active_view) + { + if (_gradient_texture == NULL) + { + nux::NTextureData texture_data (nux::BITFMT_R8G8B8A8, geo.width, 1, 1); + nux::ImageSurface surface = texture_data.GetSurface (0); + nux::SURFACE_LOCKED_RECT lockrect; + BYTE *dest; + int num_row; + + _gradient_texture = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableDeviceTexture (texture_data.GetWidth (), texture_data.GetHeight (), 1, texture_data.GetFormat ()); + + _gradient_texture->LockRect (0, &lockrect, 0); + + dest = (BYTE *) lockrect.pBits; + num_row = surface.GetBlockHeight (); + + for (int y = 0; y < num_row; y++) + { + for (int x = 0; x < geo.width; x++) + { + *(dest + y * lockrect.Pitch + 4*x + 0) = 223; //red + *(dest + y * lockrect.Pitch + 4*x + 1) = 219; //green + *(dest + y * lockrect.Pitch + 4*x + 2) = 210; //blue + + if (x < button_width * (factor - 1)) + { + *(dest + y * lockrect.Pitch + 4*x + 3) = 0xff; + } + else if (x < button_width * factor) + { + *(dest + y * lockrect.Pitch + 4*x + 3) = 255 - 255 * (((float)x-(button_width * (factor -1)))/(float)(button_width)); + } + else + { + *(dest + y * lockrect.Pitch + 4*x + 3) = 0x00; + } + } + } + _gradient_texture->UnlockRect (0); + } + GfxContext.GetRenderStates ().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + nux::TexCoordXForm texxform0; + nux::TexCoordXForm texxform1; + + // Modulate the checkboard and the gradient texture + GfxContext.QRP_2TexMod(geo.x, geo.y, + geo.width, geo.height, + _gradient_texture, texxform0, + nux::Color::White, + _title_tex->GetDeviceTexture (), + texxform1, + nux::Color::White); + + GfxContext.GetRenderStates ().SetBlend(false); + + // The previous blend is too aggressive on the texture and therefore there + // is a slight loss of clarity. This fixes that + geo.width = button_width * (factor - 1); + gPainter.PushDrawLayer (GfxContext, geo, _title_layer); + geo = GetGeometry (); + } + else + { + gPainter.PushDrawLayer (GfxContext, + geo, + _title_layer); + } + } + + gPainter.PopBackground (); + + GfxContext.PopClippingRectangle(); +} + +void +PanelMenuView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + nux::Geometry geo = GetGeometry (); + + GfxContext.PushClippingRectangle (geo); + + if (_is_inside || _last_active_view) + { + _layout->ProcessDraw (GfxContext, force_draw); + } + + if (_is_maximized) + { + _window_buttons->ProcessDraw (GfxContext, true); + } + + GfxContext.PopClippingRectangle(); +} + +gchar * +PanelMenuView::GetActiveViewName () +{ + gchar *label = NULL; + + if (_is_maximized) + { + BamfWindow *window = bamf_matcher_get_active_window (_matcher); + + if (BAMF_IS_WINDOW (window)) + label = g_strdup (bamf_view_get_name (BAMF_VIEW (window))); + } + + if (!label) + { + BamfApplication *app = bamf_matcher_get_active_application (_matcher); + if (BAMF_IS_APPLICATION (app)) + { + const gchar *filename; + + filename = bamf_application_get_desktop_file (app); + + if (filename && g_strcmp0 (filename, "") != 0) + { + GDesktopAppInfo *info; + + info = g_desktop_app_info_new_from_filename (bamf_application_get_desktop_file (app)); + + if (info) + { + label = g_strdup (g_app_info_get_display_name (G_APP_INFO (info))); + g_object_unref (info); + } + else + { + g_warning ("Unable to get GDesktopAppInfo for %s", + bamf_application_get_desktop_file (app)); + } + } + + if (label == NULL) + { + BamfView *active_view; + + active_view = (BamfView *)bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_VIEW (active_view)) + label = g_strdup (bamf_view_get_name (active_view)); + else + label = g_strdup (""); + } + } + else + { + label = g_strdup (" "); + } + } + + return label; +} + +void +PanelMenuView::Refresh () +{ + nux::Geometry geo = GetGeometry (); + char *label = GetActiveViewName (); + PangoLayout *layout = NULL; + PangoFontDescription *desc = NULL; + GtkSettings *settings = gtk_settings_get_default (); + cairo_t *cr; + char *font_description = NULL; + GdkScreen *screen = gdk_screen_get_default (); + int dpi = 0; + + int x = 0; + int y = 0; + int width = geo.width; + int height = geo.height; + int text_width = 0; + int text_height = 0; + + if (label) + { + PangoContext *cxt; + PangoRectangle log_rect; + + cr = _util_cg.GetContext (); + + g_object_get (settings, + "gtk-font-name", &font_description, + "gtk-xft-dpi", &dpi, + NULL); + desc = pango_font_description_from_string (font_description); + pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD); + + layout = pango_cairo_create_layout (cr); + pango_layout_set_font_description (layout, desc); + pango_layout_set_text (layout, label, -1); + + cxt = pango_layout_get_context (layout); + pango_cairo_context_set_font_options (cxt, gdk_screen_get_font_options (screen)); + pango_cairo_context_set_resolution (cxt, (float)dpi/(float)PANGO_SCALE); + pango_layout_context_changed (layout); + + pango_layout_get_extents (layout, NULL, &log_rect); + text_width = log_rect.width / PANGO_SCALE; + text_height = log_rect.height / PANGO_SCALE; + + pango_font_description_free (desc); + g_free (font_description); + cairo_destroy (cr); + } + + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); + cr = cairo_graphics.GetContext(); + cairo_set_line_width (cr, 1); + + x = PADDING; + y = 0; + + if (_is_maximized) + x += _window_buttons->GetContentWidth () + PADDING + PADDING; + + if (label) + { + pango_cairo_update_layout (cr, layout); + + // Once for the homies that couldn't be here + cairo_set_source_rgb (cr, 50/255.0f, 50/255.0f, 45/255.0f); + cairo_move_to (cr, x, ((height - text_height)/2)-1); + pango_cairo_show_layout (cr, layout); + cairo_stroke (cr); + + // Once again for the homies that could + cairo_set_source_rgba (cr, 223/255.0f, 219/255.0f, 210/255.0f, 1.0f); + cairo_move_to (cr, x, (height - text_height)/2); + pango_cairo_show_layout (cr, layout); + cairo_stroke (cr); + } + + cairo_destroy (cr); + if (layout) + g_object_unref (layout); + + nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); + + // The Texture is created with a reference count of 1. + nux::BaseTexture* texture2D = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture (); + texture2D->Update(bitmap); + delete bitmap; + + if (_title_layer) + delete _title_layer; + + nux::TexCoordXForm texxform; + texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); + texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + _title_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), + texxform, + nux::Color::White, + false, + rop); + + + if (_title_tex) + _title_tex->UnReference (); + + _title_tex = texture2D; + + g_free (label); +} + +void +PanelMenuView::OnActiveChanged (PanelIndicatorObjectEntryView *view, + bool is_active) +{ + if (is_active) + _last_active_view = view; + else + { + if (_last_active_view == view) + { + _last_active_view = NULL; + } + } + FullRedraw (); +} + +void +PanelMenuView::OnEntryAdded (IndicatorObjectEntryProxy *proxy) +{ + PanelIndicatorObjectEntryView *view = new PanelIndicatorObjectEntryView (proxy); + view->active_changed.connect (sigc::mem_fun (this, &PanelMenuView::OnActiveChanged)); + _menu_layout->AddView (view, 0, nux::eCenter, nux::eFull); + _menu_layout->SetContentDistribution (nux::eStackLeft); + + _entries.push_back (view); + + AddChild (view); + + this->ComputeChildLayout (); + NeedRedraw (); +} + +void +PanelMenuView::OnEntryMoved (IndicatorObjectEntryProxy *proxy) +{ + printf ("ERROR: Moving IndicatorObjectEntry not supported\n"); +} + +void +PanelMenuView::OnEntryRemoved(IndicatorObjectEntryProxy *proxy) +{ + std::vector<PanelIndicatorObjectEntryView *>::iterator it; + + for (it = _entries.begin(); it != _entries.end(); it++) + { + PanelIndicatorObjectEntryView *view = static_cast<PanelIndicatorObjectEntryView *> (*it); + if (view->_proxy == proxy) + { + RemoveChild (view); + _entries.erase (it); + _menu_layout->RemoveChildObject (view); + + break; + } + } + + this->ComputeChildLayout (); + NeedRedraw (); +} + +void +PanelMenuView::AllMenusClosed () +{ + _is_inside = false; + _last_active_view = false; + + 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); + _is_maximized = WindowManager::Default ()->IsWindowMaximized (bamf_window_get_xid (window)); + } + + Refresh (); + FullRedraw (); +} + +void +PanelMenuView::OnWindowUnmapped (guint32 xid) +{ + _decor_map.erase (xid); +} + +void +PanelMenuView::OnWindowMaximized (guint xid) +{ + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid) + { + // We could probably just check if a key is available, but who wants to do that + if (_decor_map.find (xid) == _decor_map.end ()) + _decor_map[xid] = WindowManager::Default ()->IsWindowDecorated (xid); + + if (_decor_map[xid]) + { + WindowManager::Default ()->Undecorate (xid); + } + + _is_maximized = true; + + Refresh (); + FullRedraw (); + } +} + +void +PanelMenuView::OnWindowRestored (guint xid) +{ + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid) + { + _is_maximized = false; + + if (_decor_map[xid]) + { + WindowManager::Default ()->Decorate (xid); + } + + Refresh (); + FullRedraw (); + } +} + +void +PanelMenuView::OnCloseClicked () +{ + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window)) + WindowManager::Default ()->Close (bamf_window_get_xid (window)); +} + +void +PanelMenuView::OnMinimizeClicked () +{ + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window)) + WindowManager::Default ()->Minimize (bamf_window_get_xid (window)); +} + +void +PanelMenuView::OnRestoreClicked () +{ + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window)) + WindowManager::Default ()->Restore (bamf_window_get_xid (window)); +} + +void +PanelMenuView::OnWindowButtonsRedraw () +{ + FullRedraw (); +} + +// Introspectable +const gchar * +PanelMenuView::GetName () +{ + return "MenuView"; +} + +const gchar * +PanelMenuView::GetChildsName () +{ + return "entries"; +} + +void +PanelMenuView::AddProperties (GVariantBuilder *builder) +{ + nux::Geometry geo = GetGeometry (); + + /* Now some props from ourselves */ + 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)); +} + +/* + * C code for callbacks + */ +static void +on_active_window_changed (BamfMatcher *matcher, + BamfView *old_view, + BamfView *new_view, + PanelMenuView *self) +{ + self->OnActiveWindowChanged (old_view, new_view); +} diff --git a/src/PanelMenuView.h b/src/PanelMenuView.h new file mode 100644 index 000000000..66f2f0f04 --- /dev/null +++ b/src/PanelMenuView.h @@ -0,0 +1,103 @@ +/* + * 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 PANEL_MENU_VIEW_H +#define PANEL_MENU_VIEW_H + +#include <Nux/View.h> +#include <map> + +#include "IndicatorObjectProxy.h" +#include "Introspectable.h" +#include "PanelIndicatorObjectView.h" +#include "StaticCairoText.h" +#include "WindowButtons.h" + +#include <libbamf/libbamf.h> + +class PanelMenuView : public PanelIndicatorObjectView +{ +public: + // This contains all the menubar logic for the Panel. Mainly it contains + // the following states: + // 1. Unmaximized window + no mouse hover + // 2. Unmaximized window + mouse hover + // 3. Unmaximized window + active menu (Alt+F/arrow key nav) + // 4. Maximized window + no mouse hover + // 5. Maximized window + mouse hover + // 6. Maximized window + active menu + // + // It also deals with undecorating maximized windows (and redecorating them + // on unmaximize) + + PanelMenuView (); + ~PanelMenuView (); + + void FullRedraw (); + + 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 long PostLayoutManagement (long LayoutResult); + + void SetProxy (IndicatorObjectProxy *proxy); + + void OnEntryAdded (IndicatorObjectEntryProxy *proxy); + void OnEntryMoved (IndicatorObjectEntryProxy *proxy); + void OnEntryRemoved (IndicatorObjectEntryProxy *proxy); + void OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active); + void OnActiveWindowChanged (BamfView *old_view, BamfView *new_view); + + void OnWindowUnmapped (guint xid); + void OnWindowMaximized (guint32 xid); + void OnWindowRestored (guint32 xid); + + void Refresh (); + void AllMenusClosed (); + + void OnCloseClicked (); + void OnMinimizeClicked (); + void OnRestoreClicked (); + void OnWindowButtonsRedraw (); + +protected: + const gchar * GetName (); + const gchar * GetChildsName (); + void AddProperties (GVariantBuilder *builder); + +private: + gchar * GetActiveViewName (); + +private: + BamfMatcher* _matcher; + + nux::AbstractPaintLayer *_title_layer; + nux::HLayout *_menu_layout; + nux::CairoGraphics _util_cg; + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _gradient_texture; + nux::BaseTexture *_title_tex; + + bool _is_inside; + bool _is_maximized; + PanelIndicatorObjectEntryView *_last_active_view; + + WindowButtons *_window_buttons; + + std::map<guint32, bool> _decor_map; +}; +#endif diff --git a/src/PanelView.cpp b/src/PanelView.cpp index 3809ec815..f938a45a9 100644 --- a/src/PanelView.cpp +++ b/src/PanelView.cpp @@ -46,13 +46,17 @@ PanelView::PanelView (NUX_FILE_LINE_DECL) // Home button _home_button = new PanelHomeButton (); _layout->AddView (_home_button, 0, nux::eCenter, nux::eFull); - AddChild (_home_button); + _menu_view = new PanelMenuView (); + _layout->AddView (_menu_view, 1, nux::eCenter, nux::eFull); + AddChild (_menu_view); + _remote = new IndicatorObjectFactoryRemote (); _remote->OnObjectAdded.connect (sigc::mem_fun (this, &PanelView::OnObjectAdded)); _remote->OnMenuPointerMoved.connect (sigc::mem_fun (this, &PanelView::OnMenuPointerMoved)); _remote->OnEntryActivateRequest.connect (sigc::mem_fun (this, &PanelView::OnEntryActivateRequest)); + _remote->IndicatorObjectFactory::OnEntryActivated.connect (sigc::mem_fun (this, &PanelView::OnEntryActivated)); } PanelView::~PanelView () @@ -204,7 +208,11 @@ PanelView::OnObjectAdded (IndicatorObjectProxy *proxy) // Appmenu is treated differently as it needs to expand // We could do this in a more special way, but who has the time for special? - _layout->AddView (view, (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL), nux::eCenter, nux::eFull); + if (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL) + _menu_view->SetProxy (proxy); + else + _layout->AddView (view, 0, nux::eCenter, nux::eFull); + _layout->SetContentDistribution (nux::eStackLeft); AddChild (view); @@ -224,40 +232,40 @@ PanelView::OnMenuPointerMoved (int x, int y) if (x >= geo.x && x <= (geo.x + geo.width) && y >= geo.y && y <= (geo.y + geo.height)) - { - std::list<Area *>::iterator it; + { + std::list<Area *>::iterator it; - std::list<Area *> my_children = _layout->GetChildren (); - for (it = my_children.begin(); it != my_children.end(); it++) + std::list<Area *> my_children = _layout->GetChildren (); + for (it = my_children.begin(); it != my_children.end(); it++) + { + PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); + + if (view->_layout == NULL) + continue; + + geo = view->GetGeometry (); + if (x >= geo.x && x <= (geo.x + geo.width) + && y >= geo.y && y <= (geo.y + geo.height)) { - PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); - - if (view->_layout == NULL) - continue; - - geo = view->GetGeometry (); - if (x >= geo.x && x <= (geo.x + geo.width) - && y >= geo.y && y <= (geo.y + geo.height)) + std::list<Area *>::iterator it2; + + std::list<Area *> its_children = view->_layout->GetChildren (); + for (it2 = its_children.begin(); it2 != its_children.end(); it2++) + { + PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); + + geo = entry->GetGeometry (); + if (x >= geo.x && x <= (geo.x + geo.width) + && y >= geo.y && y <= (geo.y + geo.height)) { - std::list<Area *>::iterator it2; - - std::list<Area *> its_children = view->_layout->GetChildren (); - for (it2 = its_children.begin(); it2 != its_children.end(); it2++) - { - PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); - - geo = entry->GetGeometry (); - if (x >= geo.x && x <= (geo.x + geo.width) - && y >= geo.y && y <= (geo.y + geo.height)) - { - entry->OnMouseDown (x, y, 0, 0); - break; - } - } + entry->OnMouseDown (x, y, 0, 0); break; } + } + break; } } + } } void @@ -281,10 +289,18 @@ PanelView::OnEntryActivateRequest (const char *entry_id) PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); if (g_strcmp0 (entry->GetName (), entry_id) == 0) - { - entry->Activate (); - break; - } + { + g_debug ("%s: Activating: %s", G_STRFUNC, entry_id); + entry->Activate (); + break; + } } } } + +void +PanelView::OnEntryActivated (const char *entry_id) +{ + if (g_strcmp0 (entry_id, "") == 0) + _menu_view->AllMenusClosed (); +} diff --git a/src/PanelView.h b/src/PanelView.h index f6afc4f95..e96bdf41a 100644 --- a/src/PanelView.h +++ b/src/PanelView.h @@ -24,6 +24,7 @@ #include <NuxGraphics/GraphicsEngine.h> #include "PanelHomeButton.h" +#include "PanelMenuView.h" #include "IndicatorObjectFactoryRemote.h" #include "Introspectable.h" @@ -43,6 +44,7 @@ public: void OnObjectAdded (IndicatorObjectProxy *proxy); void OnMenuPointerMoved (int x, int y); void OnEntryActivateRequest (const char *entry_id); + void OnEntryActivated (const char *entry_id); PanelHomeButton * HomeButton (); @@ -59,6 +61,7 @@ private: IndicatorObjectFactoryRemote *_remote; PanelHomeButton *_home_button; + PanelMenuView *_menu_view; nux::AbstractPaintLayer *_bg_layer; nux::HLayout *_layout; diff --git a/src/PlacesController.cpp b/src/PlacesController.cpp new file mode 100644 index 000000000..cb7d2e417 --- /dev/null +++ b/src/PlacesController.cpp @@ -0,0 +1,142 @@ +/* + * 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/HLayout.h" + +#include "NuxGraphics/GLThread.h" +#include <glib.h> +#include <pango/pangocairo.h> +#include <gtk/gtk.h> + +#include "../libunity/ubus-server.h" +#include "UBusMessages.h" + +#include "PlacesController.h" + +PlacesController::PlacesController () +{ + + // 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, + (UBusCallback)&PlacesController::ExternalActivation, + this); + + _Window = new PlacesView (); + _Window->Reference (); + _Window->SetConfigureNotifyCallback(&PlacesController::WindowConfigureCallback, this); + //_Window->SetBlurredBackground(true); + _Window->ShowWindow(false); + //_Window->EnableInputWindow(false); + //_Window->InputWindowEnableStruts(false); + + _Window->OnMouseDownOutsideArea.connect (sigc::mem_fun (this, &PlacesController::RecvMouseDownOutsideOfView)); + +} + +PlacesController::~PlacesController () +{ + _Window->UnReference (); +} + +void PlacesController::Show () +{ + // show called + _Window->Show (); +} + +void PlacesController::Hide () +{ + _Window->Hide (); +} + +void PlacesController::ToggleShowHide () +{ + if (_Window->IsVisible ()) + Hide (); + else + Show (); +} + +/* Configure callback for the window */ +void +PlacesController::WindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data) +{ + GdkScreen *screen = gdk_screen_get_default (); + int height = gdk_screen_get_height (screen) - 12; + geo = nux::Geometry(32, 12, 1024, height); +} + +void +PlacesController::ExternalActivation (GVariant *data, void *val) +{ + if (g_getenv ("UNITY_ENABLE_PLACES")) + { + PlacesController *self = (PlacesController*)val; + self->ToggleShowHide (); + } + else + { + // not removing the nautilus behaviour until we can launch applications in places :) + #define APPS_URI "file:///usr/share/applications" + + /* FIXME: This is just for Alpha 1, so we have some feedback on clicking the + * PanelHomeButton, and especially because we don't have any other way of + * launching non-launcher apps right now + */ + GdkAppLaunchContext *context; + GError *error = NULL; + + context = gdk_app_launch_context_new (); + gdk_app_launch_context_set_screen (context, gdk_screen_get_default ()); + gdk_app_launch_context_set_timestamp (context, GDK_CURRENT_TIME); + + if (!g_app_info_launch_default_for_uri (APPS_URI, + (GAppLaunchContext *)context, + &error)) + { + g_warning ("Unable to launcher applications folder: %s", + error->message); + g_error_free (error); + } + + g_object_unref (context); + } +} + +void +PlacesController::RecvMouseDownOutsideOfView (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + Hide (); +} + +/* Introspection */ +const gchar * +PlacesController::GetName () +{ + return "PlacesController"; +} + +void +PlacesController::AddProperties (GVariantBuilder *builder) +{ +} + diff --git a/src/PlacesController.h b/src/PlacesController.h new file mode 100644 index 000000000..0b5dbd841 --- /dev/null +++ b/src/PlacesController.h @@ -0,0 +1,56 @@ +/* + * 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> + */ + +#ifndef PLACES_CONTROLLER_H +#define PLACES_CONTROLLER_H + +#include <Nux/TextureArea.h> +#include <Nux/View.h> +#include "Nux/Layout.h" +#include <NuxImage/CairoGraphics.h> +#include <NuxGraphics/GraphicsEngine.h> + +#include "PlacesView.h" +#include "Introspectable.h" + +class PlacesController : public Introspectable +{ +public: + PlacesController (); + ~PlacesController (); + + void Show (); + void Hide (); + void ToggleShowHide (); + + PlacesView *_Window; +protected: + const gchar* GetName (); + void AddProperties (GVariantBuilder *builder); + + static void ExternalActivation (GVariant *data, void *val); + static void WindowConfigureCallback(int WindowWidth, int WindowHeight, + nux::Geometry& geo, void *user_data); + + void RecvMouseDownOutsideOfView (int x, int y, unsigned long button_flags, unsigned long key_flags); + + + nux::Layout *_Layout; +}; + +#endif // PLACES_CONTROLLER_H diff --git a/src/PlacesView.cpp b/src/PlacesView.cpp new file mode 100644 index 000000000..a4cc66e73 --- /dev/null +++ b/src/PlacesView.cpp @@ -0,0 +1,131 @@ +/* + * 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 "NuxGraphics/GLThread.h" +#include "UBusMessages.h" + +#include "PlacesView.h" + +NUX_IMPLEMENT_OBJECT_TYPE (PlacesView); + +PlacesView::PlacesView (NUX_FILE_LINE_DECL) +: nux::BaseWindow("", NUX_FILE_LINE_PARAM) +{ + Hide (); +} + +PlacesView::~PlacesView () +{ + +} + +long PlacesView::ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) +{ + long ret = TraverseInfo; + long ProcEvInfo = 0; + + 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) + { + if (!(GetGeometry ().IsPointInside (ievent.e_x, ievent.e_y))) + { + Hide (); + return nux::eMouseEventSolved; + } + } + + return ret; +} + +void PlacesView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Color *color = new nux::Color (0.9, 0.3, 0.1, 1.0); + nux::GetPainter ().Paint2DQuadColor (GfxContext, GetGeometry (), *color); +} + + +void PlacesView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + +} + +void PlacesView::PostDraw (nux::GraphicsEngine &GfxContext, bool force_draw) +{ + +} + +void PlacesView::ShowWindow (bool b, bool start_modal) +{ + nux::BaseWindow::ShowWindow (b, start_modal); +} + +void PlacesView::Show () +{ + if (IsVisible ()) + return; + + // FIXME: ShowWindow shouldn't need to be called first + ShowWindow (true, false); + EnableInputWindow (true, 1); + GrabPointer (); + NeedRedraw (); +} + +void PlacesView::Hide () +{ + if (!IsVisible ()) + return; + + CaptureMouseDownAnyWhereElse (false); + ForceStopFocus (1, 1); + UnGrabPointer (); + EnableInputWindow (false); + ShowWindow (false, false); +} + + +/* Introspection */ +const gchar * +PlacesView::GetName () +{ + return "PlacesView"; +} + +void +PlacesView::AddProperties (GVariantBuilder *builder) +{ +} diff --git a/src/PlacesView.h b/src/PlacesView.h new file mode 100644 index 000000000..43271f503 --- /dev/null +++ b/src/PlacesView.h @@ -0,0 +1,54 @@ +/* + * 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> + */ + +#ifndef PLACES_VIEW_H +#define PLACES_VIEW_H + +#include <Nux/Nux.h> +#include <Nux/View.h> +#include <NuxImage/CairoGraphics.h> +#include "NuxGraphics/GraphicsEngine.h" +#include "Nux/AbstractPaintLayer.h" +#include <Nux/BaseWindow.h> + +#include "Introspectable.h" + +class PlacesView : public nux::BaseWindow, public Introspectable +{ + NUX_DECLARE_OBJECT_TYPE (PlacesView, nux::BaseWindow); +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 void ShowWindow (bool b, bool start_modal = false); + + void Show (); + void Hide (); + +protected: + + const gchar* GetName (); + void AddProperties (GVariantBuilder *builder); +}; + +#endif // PANEL_HOME_BUTTON_H + diff --git a/src/PluginAdapter.cpp b/src/PluginAdapter.cpp index 535793724..9d5caf14d 100644 --- a/src/PluginAdapter.cpp +++ b/src/PluginAdapter.cpp @@ -17,6 +17,7 @@ */ #include <glib.h> +#include <scale/scale.h> #include "PluginAdapter.h" PluginAdapter * PluginAdapter::_default = 0; @@ -25,28 +26,90 @@ PluginAdapter * PluginAdapter::_default = 0; PluginAdapter * PluginAdapter::Default () { - if (!_default) - return 0; - return _default; + if (!_default) + return 0; + return _default; } /* static */ void PluginAdapter::Initialize (CompScreen *screen) { - _default = new PluginAdapter (screen); + _default = new PluginAdapter (screen); } PluginAdapter::PluginAdapter(CompScreen *screen) { - m_Screen = screen; - m_ExpoAction = 0; - m_ScaleAction = 0; + m_Screen = screen; + m_ExpoAction = 0; + m_ScaleAction = 0; } PluginAdapter::~PluginAdapter() { +} + +void +PluginAdapter::NotifyResized (CompWindow *window, int x, int y, int w, int h) +{ + window_resized.emit (window); +} + +void +PluginAdapter::NotifyMoved (CompWindow *window, int x, int y) +{ + window_moved.emit (window); +} + +void +PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state) +{ + if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE)) + { + PluginAdapter::window_maximized.emit (window); + WindowManager::window_maximized.emit (window->id ()); + } + else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE)) + { + PluginAdapter::window_restored.emit (window); + WindowManager::window_restored.emit (window->id ()); + } +} +void +PluginAdapter::Notify (CompWindow *window, CompWindowNotify notify) +{ + switch (notify) + { + case CompWindowNotifyMinimize: + window_minimized.emit (window); + break; + case CompWindowNotifyUnminimize: + window_unminimized.emit (window); + break; + case CompWindowNotifyShade: + window_shaded.emit (window); + break; + case CompWindowNotifyUnshade: + window_unshaded.emit (window); + break; + case CompWindowNotifyHide: + window_hidden.emit (window); + break; + case CompWindowNotifyShow: + window_shown.emit (window); + break; + case CompWindowNotifyMap: + PluginAdapter::window_mapped.emit (window); + WindowManager::window_mapped.emit (window->id ()); + break; + case CompWindowNotifyUnmap: + PluginAdapter::window_unmapped.emit (window); + WindowManager::window_unmapped.emit (window->id ()); + break; + default: + break; + } } void @@ -111,6 +174,35 @@ PluginAdapter::InitiateScale (std::string *match) m_ScaleAction->initiate () (m_ScaleAction, 0, argument); } +bool +PluginAdapter::IsScaleActive () +{ + SCALE_SCREEN(m_Screen); + return (m_ScaleAction && ss && ss->hasGrab ()); +} + +void +PluginAdapter::TerminateScale () +{ + if (!IsScaleActive ()) + return; + + CompOption::Value value; + CompOption::Type type; + CompOption::Vector argument; + char *name; + + name = (char *) "root"; + type = CompOption::TypeInt; + value.set ((int) m_Screen->root ()); + + CompOption arg = CompOption (name, type); + arg.set (value); + argument.push_back (arg); + + m_ScaleAction->terminate () (m_ScaleAction, 0, argument); +} + void PluginAdapter::InitiateExpo () { @@ -132,3 +224,68 @@ PluginAdapter::InitiateExpo () m_ExpoAction->initiate () (m_ExpoAction, 0, argument); } + +// WindowManager implementation +bool +PluginAdapter::IsWindowMaximized (guint xid) +{ + Window win = (Window)xid; + CompWindow *window; + + window = m_Screen->findWindow (win); + if (window) + { + return window->state () & MAXIMIZE_STATE; + } + + return false; +} + +bool +PluginAdapter::IsWindowDecorated (guint32 xid) +{ + Window win = (Window)xid; + CompWindow *window; + + window = m_Screen->findWindow (win); + if (window) + { + unsigned int decor = window->mwmDecor (); + + return decor & (MwmDecorAll | MwmDecorTitle); + } + return true; +} + +void +PluginAdapter::Restore (guint32 xid) +{ + Window win = (Window)xid; + CompWindow *window; + + window = m_Screen->findWindow (win); + if (window) + window->maximize (0); +} + +void +PluginAdapter::Minimize (guint32 xid) +{ + Window win = (Window)xid; + CompWindow *window; + + window = m_Screen->findWindow (win); + if (window) + window->minimize (); +} + +void +PluginAdapter::Close (guint32 xid) +{ + Window win = (Window)xid; + CompWindow *window; + + window = m_Screen->findWindow (win); + if (window) + window->close (CurrentTime); +} diff --git a/src/PluginAdapter.h b/src/PluginAdapter.h index e268c3848..b1764124b 100644 --- a/src/PluginAdapter.h +++ b/src/PluginAdapter.h @@ -24,7 +24,9 @@ #include <sigc++/sigc++.h> -class PluginAdapter : public sigc::trackable +#include "WindowManager.h" + +class PluginAdapter : public sigc::trackable, public WindowManager { public: static PluginAdapter * Default (); @@ -40,9 +42,38 @@ public: void SetExpoAction (CompAction *expo); void InitiateScale (std::string *match); + + bool IsScaleActive (); + + void TerminateScale (); void InitiateExpo (); + void Notify (CompWindow *window, CompWindowNotify notify); + void NotifyMoved (CompWindow *window, int x, int y); + void NotifyResized (CompWindow *window, int x, int y, int w, int h); + void NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state); + + // WindowManager implementation + bool IsWindowMaximized (guint xid); + bool IsWindowDecorated (guint xid); + void Restore (guint32 xid); + void Minimize (guint32 xid); + void Close (guint32 xid); + + sigc::signal<void, CompWindow *> window_maximized; + sigc::signal<void, CompWindow *> window_restored; + sigc::signal<void, CompWindow *> window_minimized; + sigc::signal<void, CompWindow *> window_unminimized; + sigc::signal<void, CompWindow *> window_shaded; + sigc::signal<void, CompWindow *> window_unshaded; + sigc::signal<void, CompWindow *> window_mapped; + sigc::signal<void, CompWindow *> window_unmapped; + sigc::signal<void, CompWindow *> window_shown; + sigc::signal<void, CompWindow *> window_hidden; + sigc::signal<void, CompWindow *> window_resized; + sigc::signal<void, CompWindow *> window_moved; + protected: PluginAdapter(CompScreen *screen); diff --git a/src/QuicklistManager.cpp b/src/QuicklistManager.cpp new file mode 100644 index 000000000..940378953 --- /dev/null +++ b/src/QuicklistManager.cpp @@ -0,0 +1,109 @@ +/* + * 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: Jamal Fanaian <j@jamalfanaian.com> + */ + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "Nux/VLayout.h" +#include "Nux/WindowCompositor.h" +#include "QuicklistView.h" +#include "QuicklistManager.h" + +QuicklistManager * QuicklistManager::_default = 0; + +/* static */ +QuicklistManager *QuicklistManager::Default () +{ + if (!_default) + _default = new QuicklistManager (); + return _default; +} + +QuicklistManager::QuicklistManager () +{ + _current_quicklist = 0; +} + +QuicklistManager::~QuicklistManager () +{ +} + +QuicklistView *QuicklistManager::Current () +{ + return _current_quicklist; +} + +void QuicklistManager::RegisterQuicklist (QuicklistView *quicklist) +{ + std::list<QuicklistView*>::iterator it; + + if (std::find (_quicklist_list.begin(), _quicklist_list.end(), quicklist) != _quicklist_list.end()) { + // quicklist has already been registered + g_warning ("Attempted to register a quicklist that was previously registered"); + return; + } + + _quicklist_list.push_back (quicklist); + + quicklist->sigVisible.connect (sigc::mem_fun (this, &QuicklistManager::RecvShowQuicklist)); + quicklist->sigHidden.connect (sigc::mem_fun (this, &QuicklistManager::RecvHideQuicklist)); +} + +void QuicklistManager::ShowQuicklist (QuicklistView *quicklist, int tip_x, + int tip_y, bool hide_existing_if_open) +{ + if (_current_quicklist == quicklist) + { + // this quicklist is already active + // do we want to still redraw in case the position has changed? + return; + } + + if (hide_existing_if_open && _current_quicklist) + { + HideQuicklist (_current_quicklist); + } + + quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); +} + +void QuicklistManager::HideQuicklist (QuicklistView *quicklist) +{ + quicklist->Hide(); +} + +void QuicklistManager::RecvShowQuicklist (nux::BaseWindow *window) +{ + QuicklistView *quicklist = (QuicklistView*) window; + + _current_quicklist = quicklist; + + quicklist_opened.emit (quicklist); +} + +void QuicklistManager::RecvHideQuicklist (nux::BaseWindow *window) +{ + QuicklistView *quicklist = (QuicklistView*) window; + + if (_current_quicklist == quicklist) + { + _current_quicklist = 0; + } + + quicklist_closed.emit (quicklist); +} + diff --git a/src/QuicklistManager.h b/src/QuicklistManager.h new file mode 100644 index 000000000..63a271212 --- /dev/null +++ b/src/QuicklistManager.h @@ -0,0 +1,52 @@ +/* + * 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: Jamal Fanaian <j@jamalfanaian.com> + */ + +#ifndef QUICKLISTMANAGER_H +#define QUICKLISTMANAGER_H + +class QuicklistManager : public sigc::trackable +{ +public: + static QuicklistManager *Default (); + + QuicklistManager (); + + ~QuicklistManager (); + + QuicklistView *Current (); + + void RegisterQuicklist (QuicklistView *quicklist); + void ShowQuicklist (QuicklistView *quicklist, int tip_x, int tip_y, bool hide_existing_if_open = true); + void HideQuicklist (QuicklistView *quicklist); + + void RecvShowQuicklist (nux::BaseWindow *window); + void RecvHideQuicklist (nux::BaseWindow *window); + + sigc::signal<void, QuicklistView*> quicklist_opened; + sigc::signal<void, QuicklistView*> quicklist_closed; + +private: + static QuicklistManager *_default; + + std::list<QuicklistView*> _quicklist_list; + QuicklistView *_current_quicklist; + +}; + +#endif + diff --git a/src/QuicklistView.cpp b/src/QuicklistView.cpp index b1cf1ff01..f389ab15d 100644 --- a/src/QuicklistView.cpp +++ b/src/QuicklistView.cpp @@ -151,7 +151,7 @@ void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y) SetBaseX (x); SetBaseY (y); - ShowWindow (true); + Show (); } void QuicklistView::ShowWindow (bool b, bool start_modal) @@ -159,6 +159,31 @@ void QuicklistView::ShowWindow (bool b, bool start_modal) BaseWindow::ShowWindow (b, start_modal); } +void QuicklistView::Show () +{ + if (!IsVisible()) + { + // FIXME: ShowWindow shouldn't need to be called first + ShowWindow (true); + EnableInputWindow (true, 1); + GrabPointer (); + NeedRedraw (); + } +} + +void QuicklistView::Hide () +{ + if (IsVisible() && !_enable_quicklist_for_testing) + { + CancelItemsPrelightStatus (); + CaptureMouseDownAnyWhereElse (false); + ForceStopFocus (1, 1); + UnGrabPointer (); + EnableInputWindow (false); + ShowWindow (false); + } +} + long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long ProcessEventInfo) { long ret = TraverseInfo; @@ -198,36 +223,14 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P else { _mouse_down = false; - if (IsVisible ()) - { - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } - } + Hide (); return nux::eMouseEventSolved; } } else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down) { _mouse_down = false; - if (IsVisible ()) - { - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } - } + Hide (); return nux::eMouseEventSolved; } @@ -418,15 +421,7 @@ void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item, int x, int y) // Check if the mouse was released over an item and emit the signal CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } + Hide (); } } @@ -474,17 +469,9 @@ void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item, int x, int y) { // Check if the mouse was released over an item and emit the signal CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); - - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } - } + + Hide (); + } } void QuicklistView::CancelItemsPrelightStatus () @@ -570,15 +557,7 @@ void QuicklistView::RecvMouseClick (int x, int y, unsigned long button_flags, un { if (IsVisible ()) { - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } + Hide (); } } @@ -594,18 +573,7 @@ void QuicklistView::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long b void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags) { - if (IsVisible ()) - { - if (!_enable_quicklist_for_testing) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } - } + Hide (); } void QuicklistView::RemoveAllMenuItem () diff --git a/src/QuicklistView.h b/src/QuicklistView.h index ada4d9706..26974e908 100644 --- a/src/QuicklistView.h +++ b/src/QuicklistView.h @@ -80,6 +80,9 @@ public: void ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y); virtual void ShowWindow (bool b, bool StartModal = false); + + void Show (); + void Hide (); int GetNumItems (); QuicklistMenuItem* GetNthItems (int index); diff --git a/src/SimpleLauncherIcon.cpp b/src/SimpleLauncherIcon.cpp index c61d78956..732710c67 100644 --- a/src/SimpleLauncherIcon.cpp +++ b/src/SimpleLauncherIcon.cpp @@ -21,6 +21,7 @@ #include "SimpleLauncherIcon.h" #include "Launcher.h" +#include "PluginAdapter.h" SimpleLauncherIcon::SimpleLauncherIcon (Launcher* IconManager) : LauncherIcon(IconManager) @@ -54,6 +55,8 @@ SimpleLauncherIcon::OnMouseUp (int button) void SimpleLauncherIcon::OnMouseClick (int button) { + if (button == 1) + PluginAdapter::Default ()->TerminateScale (); } void diff --git a/src/SimpleLauncherIcon.h b/src/SimpleLauncherIcon.h index 7c3cdf7cb..b4359e26f 100644 --- a/src/SimpleLauncherIcon.h +++ b/src/SimpleLauncherIcon.h @@ -27,7 +27,7 @@ class SimpleLauncherIcon : public LauncherIcon { public: SimpleLauncherIcon(Launcher* IconManager); - ~SimpleLauncherIcon(); + virtual ~SimpleLauncherIcon(); /* override */ nux::BaseTexture * GetTextureForSize (int size); diff --git a/src/TrashLauncherIcon.cpp b/src/TrashLauncherIcon.cpp index 24c24ba9b..85ff22d01 100644 --- a/src/TrashLauncherIcon.cpp +++ b/src/TrashLauncherIcon.cpp @@ -50,6 +50,8 @@ TrashLauncherIcon::~TrashLauncherIcon() void TrashLauncherIcon::OnMouseClick (int button) { + SimpleLauncherIcon::OnMouseClick (button); + if (button == 1) { GError *error = NULL; diff --git a/vala_tests/unit/test-places-place-file-model.vala b/src/UBusMessages.h index 99c30e624..a4b94ff34 100644 --- a/vala_tests/unit/test-places-place-file-model.vala +++ b/src/UBusMessages.h @@ -13,31 +13,15 @@ * 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> - * + * Authored by: Gordon Allott <gord.allott@canonical.com> */ -using Unity; -using Unity.Testing; -using Unity.Places; +#ifndef UBUS_MESSAGES_H +#define UBUS_MESSAGES_H -namespace Unity.Tests.Unit -{ - public class PlacesPlaceFileModelSuite : Object - { - public const string DOMAIN = "/Unit/Places/PlaceFileModel"; - public PlacesPlaceFileModelSuite () - { - Logging.init_fatal_handler (); +// Add ubus messages here so we can easily export them around the place +// keep ordered - Test.add_data_func (DOMAIN + "/Allocation", test_allocation); - } +#define UBUS_HOME_BUTTON_ACTIVATED "PANEL_HOME_ACTIVATED" - private void test_allocation () - { - var model = new PlaceFileModel.with_directory (Config.TESTUNITDIR+"/data"); - assert (model is PlaceFileModel); - assert (model.size == 2); - } - } -} +#endif // UBUS_MESSAGES_H diff --git a/src/WindowButtons.cpp b/src/WindowButtons.cpp new file mode 100644 index 000000000..53a984f29 --- /dev/null +++ b/src/WindowButtons.cpp @@ -0,0 +1,254 @@ +/* + * 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 "Nux/Nux.h" +#include "Nux/HLayout.h" +#include "Nux/VLayout.h" +#include "Nux/Button.h" + +#include "NuxGraphics/GLThread.h" +#include "Nux/BaseWindow.h" +#include "Nux/WindowCompositor.h" + +#include "WindowButtons.h" + +#include <glib.h> + + +// FIXME: This will be all automatic in the future +#define AMBIANCE "/usr/share/themes/Ambiance/metacity-1" + +enum +{ + BUTTON_CLOSE=0, + BUTTON_MINIMISE, + BUTTON_UNMAXIMISE +}; + +class WindowButton : public nux::Button +{ + // A single window button +public: + WindowButton (int type) + : nux::Button ("X", NUX_TRACKER_LOCATION), + _normal_tex (NULL), + _prelight_tex (NULL), + _pressed_tex (NULL) + { + if (type == BUTTON_CLOSE) + LoadImages ("close"); + else if (type == BUTTON_MINIMISE) + LoadImages ("minimize"); + else + LoadImages ("unmaximize"); + } + + ~WindowButton () + { + _normal_tex->UnReference (); + _prelight_tex->UnReference (); + _pressed_tex->UnReference (); + } + + void Draw (nux::GraphicsEngine &GfxContext, bool force_draw) + { + nux::Geometry geo = GetGeometry (); + nux::BaseTexture *tex; + nux::TexCoordXForm texxform; + + GfxContext.PushClippingRectangle (geo); + + if (HasMouseFocus ()) + { + tex = _pressed_tex; + } + else if (IsMouseInside ()) + { + tex = _prelight_tex; + } + else + { + tex = _normal_tex; + } + + GfxContext.GetRenderStates ().SetSeparateBlend (true, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_ONE); + GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); + if (tex) + GfxContext.QRP_GLSL_1Tex (geo.x, + geo.y, + (float)geo.width, + (float)geo.height, + tex->GetDeviceTexture (), + texxform, + nux::Color::White); + GfxContext.GetRenderStates ().SetSeparateBlend (false, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_ONE); + GfxContext.PopClippingRectangle(); + } + + void LoadImages (const char *name) + { + //FIXME: We need to somehow be theme aware. Or, at least support the themes + // we know and have a good default fallback + gchar *filename; + GError *error = NULL; + GdkPixbuf *_normal; + GdkPixbuf *_prelight; + GdkPixbuf *_pressed; + + filename = g_strdup_printf ("%s/%s.png", AMBIANCE, name); + _normal = gdk_pixbuf_new_from_file (filename, &error); + if (error) + { + g_warning ("Unable to load window button %s: %s", filename, error->message); + g_error_free (error); + error = NULL; + } + else + _normal_tex = nux::CreateTextureFromPixbuf (_normal); + g_free (filename); + g_object_unref (_normal); + + filename = g_strdup_printf ("%s/%s_focused_prelight.png", AMBIANCE, name); + _prelight = gdk_pixbuf_new_from_file (filename, &error); + if (error) + { + g_warning ("Unable to load window button %s: %s", filename, error->message); + g_error_free (error); + error = NULL; + } + else + _prelight_tex = nux::CreateTextureFromPixbuf (_prelight); + g_free (filename); + g_object_unref (_prelight); + + filename = g_strdup_printf ("%s/%s_focused_pressed.png", AMBIANCE, name); + _pressed = gdk_pixbuf_new_from_file (filename, &error); + if (error) + { + g_warning ("Unable to load window button %s: %s", name, error->message); + g_error_free (error); + error = NULL; + } + else + _pressed_tex = nux::CreateTextureFromPixbuf (_pressed); + g_free (filename); + g_object_unref (_pressed); + + if (_normal_tex) + SetMinimumSize (_normal_tex->GetWidth (), _normal_tex->GetHeight ()); + } + +private: + nux::BaseTexture *_normal_tex; + nux::BaseTexture *_prelight_tex; + nux::BaseTexture *_pressed_tex; +}; + + +WindowButtons::WindowButtons () +: HLayout ("", NUX_TRACKER_LOCATION) +{ + WindowButton *but; + + but = new WindowButton (BUTTON_CLOSE); + AddView (but, 0, nux::eCenter, nux::eFix); + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnCloseClicked)); + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); + + but = new WindowButton (BUTTON_MINIMISE); + AddView (but, 0, nux::eCenter, nux::eFix); + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnMinimizeClicked)); + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); + + but = new WindowButton (BUTTON_UNMAXIMISE); + AddView (but, 0, nux::eCenter, nux::eFix); + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnRestoreClicked)); + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); + + SetContentDistribution (nux::eStackLeft); +} + + +WindowButtons::~WindowButtons () +{ +} + +void +WindowButtons::OnCloseClicked () +{ + close_clicked.emit (); +} + +void +WindowButtons::OnMinimizeClicked () +{ + minimize_clicked.emit (); +} + +void +WindowButtons::OnRestoreClicked () +{ + restore_clicked.emit (); +} + +const gchar * +WindowButtons::GetName () +{ + return "window-buttons"; +} + +const gchar * +WindowButtons::GetChildsName () +{ + return ""; +} + +void +WindowButtons::AddProperties (GVariantBuilder *builder) +{ + nux::Geometry geo = GetGeometry (); + + /* Now some props from ourselves */ + 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)); +} + +void WindowButtons::RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + redraw_signal.emit (); +} + +void WindowButtons::RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + redraw_signal.emit (); +} + + diff --git a/src/WindowButtons.h b/src/WindowButtons.h new file mode 100644 index 000000000..0f6b3247c --- /dev/null +++ b/src/WindowButtons.h @@ -0,0 +1,63 @@ +/* + * 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 WINDOW_BUTTONS_H +#define WINDOW_BUTTONS_H + +#include <Nux/View.h> + +#include "Introspectable.h" + +class WindowButtons : public nux::HLayout, public Introspectable +{ + // These are the [close][minimize][restore] buttons on the panel when there + // is a maximized window + +public: + WindowButtons (); + ~WindowButtons (); + + sigc::signal<void> close_clicked; + sigc::signal<void> minimize_clicked; + sigc::signal<void> restore_clicked; + sigc::signal<void> redraw_signal; + +protected: + const gchar * GetName (); + const gchar * GetChildsName (); + void AddProperties (GVariantBuilder *builder); + + + // For testing the buttons + 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 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 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); + +private: + void OnCloseClicked (); + void OnMinimizeClicked (); + void OnRestoreClicked (); + +private: + nux::HLayout *_layout; +}; + +#endif diff --git a/src/WindowManager.cpp b/src/WindowManager.cpp new file mode 100644 index 000000000..05e835f3b --- /dev/null +++ b/src/WindowManager.cpp @@ -0,0 +1,171 @@ +/* + * 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 "WindowManager.h" + +#include <gdk/gdkx.h> + +typedef struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" + +static void gdk_window_set_mwm_hints (Window xid, + MotifWmHints *new_hints); + + +static WindowManager *window_manager = NULL; + +class WindowManagerDummy : public WindowManager +{ + bool IsWindowMaximized (guint32 xid) + { + return false; + } + + bool IsWindowDecorated (guint32 xid) + { + return true; + } + + void Restore (guint32 xid) + { + g_debug ("%s", G_STRFUNC); + } + + void Minimize (guint32 xid) + { + g_debug ("%s", G_STRFUNC); + } + + void Close (guint32 xid) + { + g_debug ("%s", G_STRFUNC); + } +}; + +WindowManager * +WindowManager::Default () +{ + if (!window_manager) + window_manager = new WindowManagerDummy (); + + return window_manager; +} + +void +WindowManager::SetDefault (WindowManager *manager) +{ + window_manager = manager; +} + +void +WindowManager::Decorate (guint32 xid) +{ + MotifWmHints hints = { 0 }; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = GDK_DECOR_ALL; + + gdk_window_set_mwm_hints (xid, &hints); +} + +void +WindowManager::Undecorate (guint32 xid) +{ + MotifWmHints hints = { 0 }; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = 0; + + gdk_window_set_mwm_hints (xid, &hints); +} + +/* + * Copied over C code + */ +static void +gdk_window_set_mwm_hints (Window xid, + MotifWmHints *new_hints) +{ + GdkDisplay *display = gdk_display_get_default(); + Atom hints_atom = None; + guchar *data = NULL; + MotifWmHints *hints = NULL; + Atom type = None; + gint format; + gulong nitems; + gulong bytes_after; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + hints_atom = gdk_x11_get_xatom_by_name_for_display (display, + _XA_MOTIF_WM_HINTS); + + gdk_error_trap_push (); + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + xid, + hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), + False, AnyPropertyType, &type, &format, &nitems, + &bytes_after, &data); + gdk_flush (); + if (gdk_error_trap_pop ()) + { + g_debug ("ERROR: Cannot set decorations"); + return; + } + + if (type != hints_atom || !data) + hints = new_hints; + else + { + hints = (MotifWmHints *)data; + + if (new_hints->flags & MWM_HINTS_FUNCTIONS) + { + hints->flags |= MWM_HINTS_FUNCTIONS; + hints->functions = new_hints->functions; + } + if (new_hints->flags & MWM_HINTS_DECORATIONS) + { + hints->flags |= MWM_HINTS_DECORATIONS; + hints->decorations = new_hints->decorations; + } + } + + gdk_error_trap_push (); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), + xid, + hints_atom, hints_atom, 32, PropModeReplace, + (guchar *)hints, sizeof (MotifWmHints)/sizeof (long)); + gdk_flush (); + if (gdk_error_trap_pop ()) + { + g_debug ("ERROR: Setting decorations"); + } + + if (data) + XFree (data); +} diff --git a/src/WindowManager.h b/src/WindowManager.h new file mode 100644 index 000000000..429aad2b4 --- /dev/null +++ b/src/WindowManager.h @@ -0,0 +1,57 @@ +/* + * 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 WINDOW_MANAGER_H +#define WINDOW_MANAGER_H + +#include <glib.h> +#include <sigc++/sigc++.h> + +class WindowManager +{ + // This is a glue interface that breaks the dependancy of Unity with Compiz + // Basically it has a default implementation that does nothing useful, but + // the idea is that unity.cpp uses SetDefault() early enough in it's + // initialization so the things that require it get a usable implementation + // + // Currently only the Panel uses it but hopefully we'll get more of + // PluginAdaptor features moved into here and also get the Launcher to use + // it. + +public: + static WindowManager * Default (); + static void SetDefault (WindowManager *manager); + + virtual bool IsWindowMaximized (guint32 xid) = 0; + virtual bool IsWindowDecorated (guint32 xid) = 0; + + virtual void Restore (guint32 xid) = 0; + virtual void Minimize (guint32 xid) = 0; + virtual void Close (guint32 xid) = 0; + + virtual void Decorate (guint32 xid); + virtual void Undecorate (guint32 xid); + + // Signals + sigc::signal<void, guint32> window_mapped; + sigc::signal<void, guint32> window_unmapped; + sigc::signal<void, guint32> window_maximized; + sigc::signal<void, guint32> window_restored; +}; + +#endif // WINDOW_MANAGER_H diff --git a/src/unity.cpp b/src/unityshell.cpp index d60902979..95d1d8191 100644 --- a/src/unity.cpp +++ b/src/unityshell.cpp @@ -31,7 +31,7 @@ #include "LauncherController.h" #include "PluginAdapter.h" #include "StartupNotifyService.h" -#include "unity.h" +#include "unityshell.h" #include <dbus/dbus.h> #include <dbus/dbus-glib.h> @@ -288,51 +288,28 @@ UnityWindow::glDraw (const GLMatrix &matrix, void UnityWindow::windowNotify (CompWindowNotify n) { - switch (n) - { - case CompWindowNotifyMinimize: - uScreen->controller->PresentIconOwningWindow (window->id ()); - uScreen->launcher->OnWindowDisappear (window); - break; - case CompWindowNotifyUnminimize: - uScreen->launcher->OnWindowAppear (window); - break; - case CompWindowNotifyShade: - uScreen->launcher->OnWindowDisappear (window); - break; - case CompWindowNotifyUnshade: - uScreen->launcher->OnWindowAppear (window); - break; - case CompWindowNotifyHide: - uScreen->launcher->OnWindowDisappear (window); - break; - case CompWindowNotifyShow: - uScreen->launcher->OnWindowAppear (window); - break; - case CompWindowNotifyMap: - uScreen->launcher->OnWindowAppear (window); - break; - case CompWindowNotifyUnmap: - uScreen->launcher->OnWindowDisappear (window); - break; - default: - break; - } - + PluginAdapter::Default ()->Notify (window, n); window->windowNotify (n); } +void +UnityWindow::stateChangeNotify (unsigned int lastState) +{ + PluginAdapter::Default ()->NotifyStateChange (window, window->state (), lastState); + window->stateChangeNotify (lastState); +} + void UnityWindow::moveNotify (int x, int y, bool immediate) { - uScreen->launcher->OnWindowMoved (window); + PluginAdapter::Default ()->NotifyMoved (window, x, y); window->moveNotify (x, y, immediate); } void UnityWindow::resizeNotify (int x, int y, int w, int h) { - uScreen->launcher->OnWindowResized (window); + PluginAdapter::Default ()->NotifyResized (window, x, y, w, h); window->resizeNotify (x, y, w, h); } @@ -391,7 +368,7 @@ UnityScreen::optionChanged (CompOption *opt, static gboolean write_logger_data_to_disk (gpointer data) { - perf_timeline_logger_write_log (perf_timeline_logger_get_default (), "/tmp/unity-perf.log"); + LOGGER_WRITE_LOG ("/tmp/unity-perf.log"); return FALSE; } @@ -417,6 +394,9 @@ UnityScreen::UnityScreen (CompScreen *screen) : CompositeScreenInterface::setHandler (cScreen); GLScreenInterface::setHandler (gScreen); + PluginAdapter::Initialize (screen); + WindowManager::SetDefault (PluginAdapter::Default ()); + StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ()); nux::NuxInitialize (0); @@ -432,12 +412,11 @@ UnityScreen::UnityScreen (CompScreen *screen) : debugger = new IntrospectionDBusInterface (this); - PluginAdapter::Initialize (screen); - optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); g_timeout_add (0, &UnityScreen::initPluginActions, this); + g_timeout_add (5000, (GSourceFunc) write_logger_data_to_disk, NULL); END_FUNCTION (); } @@ -517,6 +496,10 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->panelWindow->EnableInputWindow(true); self->panelWindow->InputWindowEnableStruts(true); LOGGER_END_PROCESS ("initLauncher-Panel"); + + /* Setup Places */ + self->placesController = new PlacesController (); + g_timeout_add (2000, &UnityScreen::strutHackTimeout, self); END_FUNCTION (); diff --git a/src/unity.h b/src/unityshell.h index cec421f57..6062e16d5 100644 --- a/src/unity.h +++ b/src/unityshell.h @@ -30,12 +30,13 @@ #include "Launcher.h" #include "LauncherController.h" #include "PanelView.h" +#include "PlacesController.h" #include "IntrospectionDBusInterface.h" #include <Nux/WindowThread.h> #include <sigc++/sigc++.h> /* base screen class */ -class UnityScreen : +class UnityScreen : public Introspectable, public sigc::trackable, public ScreenInterface, @@ -58,7 +59,7 @@ class UnityScreen : CompositeScreen *cScreen; GLScreen *gScreen; - /* prepares nux for drawing */ + /* prepares nux for drawing */ void nuxPrologue (); @@ -102,36 +103,37 @@ class UnityScreen : const gchar* GetName (); void AddProperties (GVariantBuilder *builder); - + private: static gboolean initPluginActions (gpointer data); - + static void initLauncher (nux::NThread* thread, void* InitData); - + void damageNuxRegions(); - - void + + void onRedrawRequested (); - - static void + + static void launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void* user_data); - static void + static void panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void* user_data); - static void + static void initUnity(nux::NThread* thread, void* InitData); - static gboolean + static gboolean strutHackTimeout (gpointer data); - + Launcher *launcher; LauncherController *controller; PanelView *panelView; + PlacesController *placesController; nux::WindowThread *wt; nux::BaseWindow *launcherWindow; nux::BaseWindow *panelWindow; @@ -161,9 +163,9 @@ class UnityWindow : CompWindow *window; GLWindow *gWindow; - + /* basic window draw function */ - bool + bool glDraw (const GLMatrix &matrix, GLFragment::Attrib &attrib, const CompRegion ®ion, @@ -172,8 +174,10 @@ class UnityWindow : void windowNotify (CompWindowNotify n); void moveNotify (int x, int y, bool immediate); - + void resizeNotify (int x, int y, int w, int h); + + void stateChangeNotify (unsigned int lastState); }; #define EX_SCREEN (screen) \ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6f55fe1df..55eb3e070 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,7 +8,7 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/data/update-manager.desktop # Unit tests # find_package (PkgConfig) -set (TEST_DEPS "${UNITY_PLUGIN_DEPS};indicator") +set (TEST_DEPS "${UNITY_PLUGIN_DEPS};indicator;gee-1.0") pkg_check_modules (TEST_UNIT_DEPS REQUIRED ${TEST_DEPS} indicator) set (CFLAGS @@ -17,16 +17,17 @@ set (CFLAGS "-DGETTEXT_PACKAGE=\"unity\"" "-DINDICATORDIR=\"${CMAKE_BINARY_DIR}/tests\"" "-DINDICATORICONDIR=\"${CMAKE_BINARY_DIR}/tests\"" + "-I${CMAKE_BINARY_DIR}/libunity" ) add_definitions (${CFLAGS}) -set (LIBS ${TEST_UNIT_DEPS_LIBRARIES}) +set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} unity) link_libraries (${LIBS}) -set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS}) +set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS} ${CMAKE_BINARY_DIR}/libunity) link_directories (${LIB_PATHS}) -include_directories (. .. ../services ../src ${CMAKE_BINARY_DIR}) +include_directories (. .. ${CMAKE_BINARY_DIR}/libunity ../services ${CMAKE_BINARY_DIR}) # We can't have convenience libs so we need to rebuild with what we need # Please keep actual test files alphabetically at top and then files @@ -58,6 +59,7 @@ add_executable (test-unit ../src/QuicklistMenuItemSeparator.h ../src/QuicklistView.cpp ../src/QuicklistView.h + ../src/ ) add_executable (test-panel @@ -81,6 +83,29 @@ add_executable (test-panel ../src/Introspectable.h ../src/PanelHomeButton.cpp ../src/PanelHomeButton.h + ../src/PanelMenuView.cpp + ../src/PanelMenuView.h + ../src/StaticCairoText.cpp + ../src/StaticCairoText.h + ../src/WindowButtons.cpp + ../src/WindowButtons.h + ../src/WindowManager.cpp + ../src/WindowManager.h + ../libunity/ubus-server.c + ../libunity/ubus-server.h + ) + +add_executable (test-places + TestPlaces.cpp + ../src/PlacesController.cpp + ../src/PlacesController.h + ../src/PlacesView.cpp + ../src/PlacesView.h + ../src/UBusMessages.h + ../src/Introspectable.cpp + ../src/Introspectable.h + ../libunity/ubus-server.c + ../libunity/ubus-server.h ) add_executable (test-quicklist @@ -104,11 +129,42 @@ add_executable (test-quicklist ) # +# Vala tests +# +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/vala) +include(ValaPrecompile) +include(ValaVersion) + +find_package (Vala) + +vala_precompile (VALA_C vala/test-unit.vala + vala/test-place-browser.vala + vala/test-appinfo-manager.vala + vala/test-io.vala + vala/test-place.vala + vala/test-utils.vala + PACKAGES gtk+-2.0 + gio-2.0 + glib-2.0 + gobject-2.0 + gee-1.0 + dbus-glib-1 + gee-1.0 + OPTIONS --thread + CUSTOM_VAPIS ${CMAKE_SOURCE_DIR}/vapi/dee-1.0.vapi + vala/test-const.vapi + vala/config.vapi + ${CMAKE_BINARY_DIR}/libunity/unity.vapi +) + +add_executable(test-vala ${VALA_C} vala/numpty.cpp) + +# # check target # set (TEST_RESULT_DIR ${CMAKE_BINARY_DIR}/tests) -set (TEST_RESULT_XML ${TEST_RESULT_DIR}/test-unit-results.xml) -set (TEST_RESULT_HTML ${TEST_RESULT_DIR}/test-unit-results.html) -set (TEST_UNIT_COMMAND gtester --verbose -k --g-fatal-warnings -o=${TEST_RESULT_XML} ./test-unit) -add_custom_target (check COMMAND ${TEST_UNIT_COMMAND} DEPENDS test-unit) +set (TEST_RESULT_XML ${TEST_RESULT_DIR}/test-results.xml) +set (TEST_RESULT_HTML ${TEST_RESULT_DIR}/test-results.html) +set (TEST_COMMAND gtester --verbose -k --g-fatal-warnings -o=${TEST_RESULT_XML} ./test-unit ./test-vala) +add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-vala) add_custom_target (check-report COMMAND ${TEST_UNIT_COMMAND} && gtester-report ${TEST_RESULT_XML} > ${TEST_RESULT_HTML}) diff --git a/tests/TestPlaces.cpp b/tests/TestPlaces.cpp new file mode 100644 index 000000000..aabae72b5 --- /dev/null +++ b/tests/TestPlaces.cpp @@ -0,0 +1,144 @@ +/* + * 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/TextureArea.h" +#include "Nux/WindowThread.h" +#include "NuxGraphics/GraphicsEngine.h" +#include <gtk/gtk.h> + +#include "../libunity/ubus-server.h" + +#include "PlacesView.h" +#include "PlacesController.h" +#include "UBusMessages.h" + +class TestRunner +{ +public: + TestRunner (); + ~TestRunner (); + + static void InitWindowThread (nux::NThread* thread, void* InitData); + void Init (); + PlacesController *controller; + nux::HLayout *layout; + +private: + +}; + +TestRunner::TestRunner () +{ +} + +TestRunner::~TestRunner () +{ +} + +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; + + 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"), + 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; + delete wt; + return 0; +} diff --git a/vala_tests/unit/test-const.vapi b/tests/vala/config.vapi index dd1bc17b7..92426606d 100644 --- a/vala_tests/unit/test-const.vapi +++ b/tests/vala/config.vapi @@ -1,5 +1,4 @@ -/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */ -/* +/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- *//* * Copyright (C) 2009 Canonical Ltd * * This program is free software: you can redistribute it and/or modify @@ -14,12 +13,13 @@ * 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> + * Authored by Neil Jagdish Patel <neil.patel@canonical.com> * */ -namespace Unity.Tests { - [CCode (cname = "TESTDIR")] - public static const string TESTDIR; - +[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")] +namespace Config +{ + public const string BUILDDIR; + public const string TESTVALADIR; } diff --git a/vala_tests/unit/data/Makefile.am b/tests/vala/data/Makefile.am index 7b9ebaca8..7b9ebaca8 100644 --- a/vala_tests/unit/data/Makefile.am +++ b/tests/vala/data/Makefile.am diff --git a/vala_tests/unit/data/applications/ubuntu-about.desktop b/tests/vala/data/applications/ubuntu-about.desktop index eabef09fd..eabef09fd 100644 --- a/vala_tests/unit/data/applications/ubuntu-about.desktop +++ b/tests/vala/data/applications/ubuntu-about.desktop diff --git a/vala_tests/unit/data/place0.badplace b/tests/vala/data/place0.badplace index 45ad555b3..45ad555b3 100644 --- a/vala_tests/unit/data/place0.badplace +++ b/tests/vala/data/place0.badplace diff --git a/vala_tests/unit/data/place0.place b/tests/vala/data/place0.place index 5d3ab3b72..5d3ab3b72 100644 --- a/vala_tests/unit/data/place0.place +++ b/tests/vala/data/place0.place diff --git a/vala_tests/unit/data/place1.badplace b/tests/vala/data/place1.badplace index b074254cb..b074254cb 100644 --- a/vala_tests/unit/data/place1.badplace +++ b/tests/vala/data/place1.badplace diff --git a/vala_tests/unit/data/place1.place b/tests/vala/data/place1.place index a4f595644..a4f595644 100644 --- a/vala_tests/unit/data/place1.place +++ b/tests/vala/data/place1.place diff --git a/vala_tests/unit/data/test_desktop_file.desktop b/tests/vala/data/test_desktop_file.desktop index 394d8f46b..394d8f46b 100644 --- a/vala_tests/unit/data/test_desktop_file.desktop +++ b/tests/vala/data/test_desktop_file.desktop diff --git a/tests/vala/numpty.cpp b/tests/vala/numpty.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/vala/numpty.cpp @@ -0,0 +1 @@ + diff --git a/vala_tests/unit/test-appinfo-manager.vala b/tests/vala/test-appinfo-manager.vala index f008d054c..d07eb0f8b 100644 --- a/vala_tests/unit/test-appinfo-manager.vala +++ b/tests/vala/test-appinfo-manager.vala @@ -18,7 +18,6 @@ * */ using Unity; -using Unity.Place; using Unity.Testing; namespace Unity.Tests.Unit @@ -91,8 +90,7 @@ namespace Unity.Tests.Unit string old_datadir = Environment.get_user_data_dir (); var manager = AppInfoManager.get_instance(); - Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR+"/data", true); - debug ("XDG %s", Config.TESTUNITDIR+"/data"); + Environment.set_variable ("XDG_DATA_HOME", Config.TESTVALADIR+"/data", true); var info = manager.lookup ("ubuntu-about.desktop"); assert (info != null); @@ -121,7 +119,7 @@ namespace Unity.Tests.Unit string old_datadir = Environment.get_user_data_dir (); var manager = AppInfoManager.get_instance(); - Environment.set_variable ("XDG_DATA_HOME", Config.TESTUNITDIR+"/data", true); + Environment.set_variable ("XDG_DATA_HOME", Config.TESTVALADIR+"/data", true); try{ var info = yield manager.lookup_async ("ubuntu-about.desktop"); diff --git a/vala_tests/ui/test-const.vapi b/tests/vala/test-const.vapi index dd1bc17b7..dd1bc17b7 100644 --- a/vala_tests/ui/test-const.vapi +++ b/tests/vala/test-const.vapi diff --git a/vala_tests/unit/test-io.vala b/tests/vala/test-io.vala index 5c5d86cfd..66e7f2a78 100644 --- a/vala_tests/unit/test-io.vala +++ b/tests/vala/test-io.vala @@ -38,7 +38,7 @@ Icon=test_desktop_icon.png public IOSuite () { - Test.add_data_func ("/Unit/IO/AsyncDektopFile", + Test.add_data_func ("/Unit/IO/AsyncDesktopFile", IOSuite.test_async_find_and_load); } @@ -52,7 +52,7 @@ Icon=test_desktop_icon.png internal static async void do_test_async_find_and_load (MainLoop mainloop) { string[] dirs = new string[1]; - dirs[0] = Path.build_filename (Config.TESTUNITDIR, "data", null + dirs[0] = Path.build_filename (Config.TESTVALADIR, "data", null ); try { @@ -61,10 +61,10 @@ Icon=test_desktop_icon.png assert (input is FileInputStream); /* Read in small chunks to test reading across buffer pages */ - uchar[] buf = new uchar[16]; - void* data; + uint8[] data; size_t data_size; - yield IO.read_stream_async (input, buf, 16, Priority.DEFAULT, null, + yield IO.read_stream_async (input, + Priority.LOW, null, out data, out data_size); /* The test file is 177 bytes long */ diff --git a/vala_tests/unit/test-place-browser.vala b/tests/vala/test-place-browser.vala index d80e56d1e..d80e56d1e 100644 --- a/vala_tests/unit/test-place-browser.vala +++ b/tests/vala/test-place-browser.vala diff --git a/vala_tests/unit/test-place.vala b/tests/vala/test-place.vala index 1cfb62747..f2e1abba9 100644 --- a/vala_tests/unit/test-place.vala +++ b/tests/vala/test-place.vala @@ -97,13 +97,13 @@ namespace Unity.Tests.Unit var entry_paths = ctl.get_entry_paths(); assert (entry_paths.length == 2); - assert (entry_paths[0] == entry_path1); - assert (entry_paths[1] == entry_path2); + assert (entry_path1 in entry_paths); + assert (entry_path2 in entry_paths); var entries = ctl.get_entries (); assert (entries.length == 2); - assert (entries[0] == entry1); - assert (entries[1] == entry2); + assert (entry1 in entries); + assert (entry2 in entries); /* Assert we can't add them twice */ diff --git a/vala_tests/unit/test-unit.vala b/tests/vala/test-unit.vala index 7b7cc7739..4d8917a3e 100644 --- a/vala_tests/unit/test-unit.vala +++ b/tests/vala/test-unit.vala @@ -24,41 +24,15 @@ public class Main { public static int main (string[] args) { - UnityPixbufCacheSuite unity_pixbuf_cache; - - LauncherSuite launcher; - QuicklistSuite quicklists; - - PanelIndicatorObjectEntryViewSuite panel_object_entry_view_suite; - PanelIndicatorObjectViewSuite panel_object_view_suite; - - PlacesPlaceFileModelSuite place_file_model; - PlacesPlaceSuite places_place; - PlacesSuite places; PlaceSuite place; PlaceBrowserSuite place_browser; IOSuite io; AppInfoManagerSuite appinfo_manager; Gtk.init (ref args); - Ctk.init (ref args); Test.init (ref args); - /* Libunity tests */ - unity_pixbuf_cache = new UnityPixbufCacheSuite (); - - /* Launcher tests */ - launcher = new LauncherSuite (); - quicklists = new QuicklistSuite (); - - /* Panel tests */ - panel_object_entry_view_suite = new PanelIndicatorObjectEntryViewSuite (); - panel_object_view_suite = new PanelIndicatorObjectViewSuite (); - place_file_model = new PlacesPlaceFileModelSuite (); - places_place = new PlacesPlaceSuite (); - /* Places tests */ - places = new PlacesSuite (); place = new PlaceSuite (); place_browser = new PlaceBrowserSuite (); diff --git a/vala_tests/unit/test-unity-pixbuf-cache.vala b/tests/vala/test-unity-pixbuf-cache.vala index c1a2e3178..c1a2e3178 100644 --- a/vala_tests/unit/test-unity-pixbuf-cache.vala +++ b/tests/vala/test-unity-pixbuf-cache.vala diff --git a/tests/vala/test-utils.vala b/tests/vala/test-utils.vala new file mode 100644 index 000000000..4b8530f75 --- /dev/null +++ b/tests/vala/test-utils.vala @@ -0,0 +1,126 @@ +/* + * 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> + * + */ + +namespace G +{ + namespace Test + { + public class Log + { + public delegate bool LogFatalFunc (string? log_domain, + LogLevelFlags flags, + string? message); + + public extern static void set_fatal_handler (LogFatalFunc func); + } + } +} + +namespace Unity.Testing +{ + public class Logging + { + public Logging () + { + Log.set_default_handler (log_handler); + } + + public static bool fatal_handler (string? log_domain, + LogLevelFlags flags, + string? message) + { + if (log_domain == null) + return true; + + if ("liblauncher" in log_domain) + return false; + + if ("bamfdaemon" in log_domain) + return false; + + if ("Gtk" in log_domain) + return false; + + if ("ndicator" in log_domain) + return false; + + if (message == null) + return true; + + if ("widget class `GtkImage' has no property named `x-ayatana-indicator-dynamic'" in message) + return false; + + if ("is currently inside an allocation cycle" in message) + return false; + + if ("Bamf r" in message) + return false; + + return true; + } + + /** + * init_fatal_handler: + * Makes sure that known warnings don't make our testing fail + **/ + public static void init_fatal_handler () + { + G.Test.Log.set_fatal_handler (fatal_handler); + } + + private void log_handler (string? log_domain, + LogLevelFlags flags, + string message) + { + string level; + + if (log_domain == "Clutter" && (flags & LogLevelFlags.LEVEL_WARNING)!=0) + { + if ("is currently inside an allocation cycle" in message) + return; + } + + if (log_domain == "Gtk" && (flags & LogLevelFlags.LEVEL_WARNING) != 0) + { + if ("has no property named `x-ayatana-indicator-dynamic'" in message) + return; + } + + if ((flags & LogLevelFlags.LEVEL_ERROR) != 0) + level = "FATAL"; + else if ((flags & LogLevelFlags.LEVEL_CRITICAL) != 0) + level = "CRITICAL"; + else if ((flags & LogLevelFlags.LEVEL_WARNING) != 0) + level = "WARNING"; + else if ((flags & LogLevelFlags.LEVEL_MESSAGE) != 0) + level = "MESSAGE"; + else if ((flags & LogLevelFlags.LEVEL_INFO) != 0) + level = "INFO"; + else if ((flags & LogLevelFlags.LEVEL_DEBUG) != 0) + level = "DEBUG"; + else + level = @"$flags"; + + print ("%s-%s: %s\n\n", + log_domain == null ? "Unity" : log_domain, + level, + message); + } + } +} diff --git a/unityshell.xml.in b/unityshell.xml.in index 4da8b8931..a35cbfdfc 100644 --- a/unityshell.xml.in +++ b/unityshell.xml.in @@ -3,6 +3,7 @@ <plugin name="unityshell" useBcop="true"> <_short>Ubuntu Unity Plugin</_short> <_long>Plugin to draw the Unity Shell</_long> + <category>Desktop</category> <deps> <relation type="after"> <plugin>bailer</plugin> diff --git a/vala_tests/ui/Makefile.am b/vala_tests/ui/Makefile.am deleted file mode 100644 index 3c0d3a6f5..000000000 --- a/vala_tests/ui/Makefile.am +++ /dev/null @@ -1,73 +0,0 @@ -SUBDIRS = data - -noinst_PROGRAMS = test-ui - -TESTDIR = $(top_srcdir)/tests/ui - -test_ui_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/unity \ - -I$(top_srcdir)/unity-private \ - -I$(top_srcdir)/src \ - -DTESTDIR=\"$(TESTDIR)\" \ - $(BASE_CFLAGS) - -test_ui_LDADD = \ - $(top_builddir)/unity/libunity.la \ - $(top_builddir)/unity-private/libunity-private.la \ - $(BASE_LIBS) \ - $(MAINTAINER_LIBS) - -test_ui_VALAFLAGS = \ - --vapidir=$(top_srcdir)/unity \ - --vapidir=$(top_srcdir)/unity-private \ - --vapidir=$(top_srcdir)/src \ - --vapidir=$(top_srcdir)/vapi/ \ - --vapidir=$(top_srcdir)/tests/ui \ - --pkg Bamf-0.2 \ - --pkg clutter-1.0 \ - --pkg clutter-gtk-0.10 \ - --pkg dbus-glib-1 \ - --pkg Dbusmenu-Glib-0.2 \ - --pkg dee-1.0 \ - --pkg gtk+-2.0 \ - --pkg gdk-2.0 \ - --pkg gee-1.0 \ - --pkg x11 \ - --pkg gtk+-2.0 \ - --pkg gee-1.0 \ - --pkg indicator \ - --pkg clutk-0.3 \ - --pkg launcher-0.3 \ - --pkg test-const \ - --pkg unique-1.0 \ - --pkg unity \ - --pkg unity-const \ - --pkg unity-private \ - $(MAINTAINER_VALAFLAGS) - -test_ui_SOURCES = \ - test-automate.vala \ - test-home-button.vala \ - test-indicators.vala \ - test-quicklist.vala \ - test-ui.vala - -# GTester stuff -XML_REPORT = test-ui-results.xml -HTML_REPORT = test-ui-results.html - -unit-tester: test-ui - @gtester -o=$(XML_REPORT) ./test-ui - -check-report: - @gtester -o=$(XML_REPORT) -k ./test-ui \ - && (gtester-report $(XML_REPORT) \ - | sed 's/GTester UI Test Report</>GTester UI Test Report (normal)</' \ - > $(HTML_REPORT)) \ - && xdg-open $(HTML_REPORT) - -check-local: unit-tester - -EXTRA_DIST = test-const.vapi -CLEANFILES = *.stamp $(XML_REPORT) $(HTML_REPORT) *.c diff --git a/vala_tests/ui/data/Makefile.am b/vala_tests/ui/data/Makefile.am deleted file mode 100644 index 2b603d3ad..000000000 --- a/vala_tests/ui/data/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = *.png diff --git a/vala_tests/ui/data/quicklist_controller_show_label.png b/vala_tests/ui/data/quicklist_controller_show_label.png Binary files differdeleted file mode 100644 index 2fef5d5f6..000000000 --- a/vala_tests/ui/data/quicklist_controller_show_label.png +++ /dev/null diff --git a/vala_tests/ui/data/quicklist_shown_on_hover.png b/vala_tests/ui/data/quicklist_shown_on_hover.png Binary files differdeleted file mode 100644 index aa31bc4a3..000000000 --- a/vala_tests/ui/data/quicklist_shown_on_hover.png +++ /dev/null diff --git a/vala_tests/ui/test-automate.vala b/vala_tests/ui/test-automate.vala deleted file mode 100644 index aa48591bd..000000000 --- a/vala_tests/ui/test-automate.vala +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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> - * - */ - -using Unity; -using Unity.Testing; -using Unity.Launcher; - -GLib.Timer gTimer; -static void -on_animation_started (Clutter.Animation? anim) -{ - //stdout.printf("Animation Started\n"); - gTimer.start (); -} - -static void -on_animation_completed (Clutter.Animation? anim) -{ - //stdout.printf("Animation Completed\n"); - gTimer.stop (); -} - -namespace Unity.Tests.UI -{ - public class AutomationBasicTestSuite : Object - { - private const string DOMAIN = "/UI/Quicklist"; - - Unity.Testing.Window? window; - Clutter.Stage? stage; - - public AutomationBasicTestSuite () - { - Logging.init_fatal_handler (); - - /* Testup the test window */ - window = new Unity.Testing.Window (true, 1024, 600); - window.init_test_mode (); - stage = window.stage; - window.title = "Automation Tests"; - window.show_all (); - - Test.add_data_func (DOMAIN + "/Automation", - test_automation); - - - /* Keep this one last, it's a dummy to clean up the state as Vala cant - * deal with the standard TestSuite stuff properly - */ - Test.add_data_func (DOMAIN +"/Teardown", test_teardown); - } - - private void test_teardown () - { - //window.destroy (); - stage = null; - } - - private void test_automation () - { -/* - ObjectRegistry registry = ObjectRegistry.get_default (); - - Logging.init_fatal_handler (); - - QuicklistController qlcontroller = QuicklistController.get_default (); - ScrollerModel scroller = registry.lookup ("UnityScrollerModel").get(0) as ScrollerModel; - - gTimer = new GLib.Timer(); - int DT = 2500; - stdout.printf("\n"); - - foreach (ScrollerChild launcher in scroller) - { - //launcher = scroller[i] as ScrollerChild; - var dir = new Director (launcher.get_stage() as Clutter.Stage); - - qlcontroller.show_label ("Ubuntu Software Centre", launcher); - - Clutter.Animation? anim; - launcher.opacity = 255; - - - gTimer.start (); - anim = launcher.animate (Clutter.AnimationMode.EASE_IN_SINE, 2500, "opacity", 0); - //anim.started.connect (on_animation_started); - anim.completed.connect (on_animation_completed); - dir.do_wait_for_animation (launcher); - - float dt = (float)gTimer.elapsed (); - float dt0 = (float)DT/1000.0f; - stdout.printf("Expected Duration: %2.3f, Observed Duration: %2.3f, Error: %2.3f%%\n", dt0, dt, - (dt - dt0)*100.0f/dt0); - - gTimer.start (); - anim = launcher.animate (Clutter.AnimationMode.EASE_IN_SINE, 2500, "opacity", 255); - //anim.started.connect (on_animation_started); - anim.completed.connect (on_animation_completed); - dir.do_wait_for_animation (launcher); - - dt = (float)gTimer.elapsed (); - dt0 = (float)DT/1000.0f; - stdout.printf("Expected Duration: %2.3f, Observed Duration: %2.3f, Error: %2.3f%%\n", dt0, dt, - (dt - dt0)*100.0f/dt0); - - - //dir.do_wait_for_timeout (5000); - } - - //debug ("After Animation"); - qlcontroller.close_menu (); -*/ - } - } -} diff --git a/vala_tests/ui/test-home-button.vala b/vala_tests/ui/test-home-button.vala deleted file mode 100644 index c899af6a3..000000000 --- a/vala_tests/ui/test-home-button.vala +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; 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 Mirco Müller <mirco.mueller@canonical.com> - * - */ - -using Unity; -using Unity.Testing; -using Unity.Panel; - -bool g_flag = false; - -namespace Unity.Tests.UI -{ - public class HomeButtonSuite : Object, Shell - { - private const string DOMAIN = "/UI/HomeButton"; - - Unity.Testing.Window? window; - Clutter.Stage? stage; - Unity.Testing.Director director; - Unity.Panel.HomeButton home_button; - public bool super_key_active {get; set;} - public bool is_starting {get; set;} - - public HomeButtonSuite () - { - Logging.init_fatal_handler (); - - /* Testup the test window */ - window = new Unity.Testing.Window (true, 1024, 600); - window.init_test_mode (); - stage = window.stage; - window.title = "HomeButton Test"; - window.show_all (); - - home_button = new Unity.Panel.HomeButton (this); - director = new Unity.Testing.Director (stage); - - Test.add_data_func (DOMAIN + "/HomeButton", test_click_home_button); - } - - - private void test_click_home_button () - { - director.button_press (home_button, 1, true, 1.0f, 1.0f, false); - - Logging.init_fatal_handler (); - - assert (g_flag == true); - } - - // - // mostly a dummy shell-implementation to satisfy the interface - // - public bool menus_swallow_events { get { return true; } } - - public void get_window_details (uint32 xid, out bool a, out bool b) - { - - } - - public void do_window_action (uint32 xid, WindowAction action) - { - - } - - public ShellMode - get_mode () - { - return ShellMode.MINIMIZED; - } - - public Clutter.Stage - get_stage () - { - return this.stage; - } - - public void - show_unity () - { - g_flag = true; - } - - public void - hide_unity () - { - - } - - public int - get_indicators_width () - { - // stub - return 0; - } - - public int - get_launcher_width_foobar () - { - // stub - return 0; - } - - public int - get_panel_height_foobar () - { - // stub - return 0; - } - - public void - ensure_input_region () - { - // stub - } - - public void - add_fullscreen_request (Object o) - { - // stub - } - - public bool - remove_fullscreen_request (Object o) - { - // stub - return false; - } - - public void - grab_keyboard (bool grab, uint32 timestamp) - { - // stub - } - - public void - about_to_show_places () - { - // stub - } - - public void - close_xids (Array<uint32> xids) - { - // stub - } - - public void - show_window (uint32 xid) - { - // stub - } - - public void - expose_xids (Array<uint32> xids) - { - // stub - } - - public void - stop_expose () - { - // stub - } - - public uint32 get_current_time () - { - return Clutter.get_current_event_time (); - } - } -} - diff --git a/vala_tests/ui/test-indicators.vala b/vala_tests/ui/test-indicators.vala deleted file mode 100644 index c136994cc..000000000 --- a/vala_tests/ui/test-indicators.vala +++ /dev/null @@ -1,321 +0,0 @@ -/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; 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 Jay Taoko <jay.taoko@canonical.com> - * - */ - -using Unity; -using Unity.Testing; -using Unity.Panel; -using Unity.Panel.Indicators; - -namespace Unity.Tests.UI -{ - public class FakeIndicatorObject: Indicator.Object - { - public Gee.ArrayList<Indicator.ObjectEntry> indicator_entry_array; - //GLib.List<Indicator.ObjectEntry> list; - - public Gtk.Label _label = null; - public Gtk.Image _image = null; - public Gtk.Menu _menu = null; - public int index {get; set construct;} - - public FakeIndicatorObject (int i) - { - Object(index:i); - } - - construct - { - START_FUNCTION (); - string index_string = "%d".printf(index); - indicator_entry_array = new Gee.ArrayList< unowned Indicator.ObjectEntry> (); - - _label = new Gtk.Label ("Indicator" + index_string); - _image = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - _menu = new Gtk.Menu (); - - END_FUNCTION (); - } - - public void add_entry(Indicator.ObjectEntry entry) - { - int pos = indicator_entry_array.index_of (entry); - if (pos != -1) - return; - - indicator_entry_array.add (entry); - entry_added (entry); - } - - public void remove_entry(Indicator.ObjectEntry entry) - { - int pos = indicator_entry_array.index_of (entry); - if (pos != -1) - { - indicator_entry_array.remove_at (pos); - entry_removed (entry); - } - } - - public override unowned Gtk.Label get_label () - { - return this._label; - } - - public override unowned Gtk.Image get_image () - { - return this._image; - } - - public override unowned Gtk.Menu get_menu () - { - return this._menu; - } - -// public override unowned GLib.List<Indicator.ObjectEntry> get_entries () -// { -// list = new GLib.List<Indicator.ObjectEntry> (); -// foreach(Indicator.ObjectEntry element in indicator_entry_array) -// { -// list.append (element); -// } -// return list; -// } - } - - public class FakeIndicatorsModel : IndicatorsModel - { - public Gee.HashMap<Indicator.Object, string> indicator_map; - public Gee.ArrayList<Indicator.Object> indicator_list; - - - public FakeIndicatorObject indicator_object_0; - public FakeIndicatorObject indicator_object_1; - - public FakeIndicatorsModel () - { - START_FUNCTION (); - - indicator_map = new Gee.HashMap<Indicator.Object, string> (); - indicator_list = new Gee.ArrayList<Indicator.Object> (); - - load_fake_indicators (); - - END_FUNCTION (); - } - - private void load_fake_indicators () - { - indicator_object_0 = new FakeIndicatorObject (0); - indicator_object_1 = new FakeIndicatorObject (1); - - this.indicator_map[indicator_object_0] = "fakeindicator0"; - indicator_list.add (indicator_object_0); - this.indicator_map[indicator_object_1] = "fakeindicator1"; - indicator_list.add (indicator_object_1); - - } - - public override Gee.ArrayList<Indicator.Object> get_indicators () - { - return indicator_list; - } - - public override string get_indicator_name (Indicator.Object o) - { - return indicator_map[o]; - } - } - - - public class IndicatorTestSuite : Object - { - private const string DOMAIN = "/UI/Indicators"; - - Unity.Testing.Window? window; - Clutter.Stage? stage; - Unity.Testing.Director director; - - public Indicator.ObjectEntry entry0; - public Indicator.ObjectEntry entry1; - - private Gtk.Menu menu0; - private Gtk.Label label0; - private Gtk.Image image0; - - private Gtk.Menu menu1; - private Gtk.Label label1; - private Gtk.Image image1; - - private Gtk.MenuItem item; - - public IndicatorTestSuite () - { - Logging.init_fatal_handler (); - - FakeIndicatorsModel fake_indicator_model = new FakeIndicatorsModel (); - IndicatorsModel.set_default (fake_indicator_model); - - - /* Testup the test window */ - window = new Unity.Testing.Window (true, 1024, 600); - window.init_test_mode (); - stage = window.stage; - window.title = "Indicators testing"; - window.show_all (); - - - director = new Unity.Testing.Director (stage); - - FakeIndicatorsModel indicator_model = IndicatorsModel.get_default () as FakeIndicatorsModel; - - menu0 = new Gtk.Menu (); - label0 = new Gtk.Label ("Entry0"); - image0 = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - item = new Gtk.MenuItem.with_label ("MenuItem0"); - item.show(); - menu0.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem1"); - item.show(); - menu0.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem2"); - item.show(); - menu0.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem3"); - item.show(); - menu0.append (item); - - entry0 = new Indicator.ObjectEntry (); - entry0.menu = menu0; - entry0.label = label0; - entry0.image = image0; - indicator_model.indicator_object_0.add_entry (entry0); - - menu1 = new Gtk.Menu (); - label1 = new Gtk.Label ("Entry1"); - image1 = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - item = new Gtk.MenuItem.with_label ("MenuItem0"); - item.show(); - menu1.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem1"); - item.show(); - menu1.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem2"); - item.show(); - menu1.append (item); - item = new Gtk.MenuItem.with_label ("MenuItem3"); - item.show(); - menu1.append (item); - - entry1 = new Indicator.ObjectEntry (); - entry1.menu = menu1; - entry1.label = label1; - entry1.image = image1; - indicator_model.indicator_object_1.add_entry (entry1); - - Test.add_data_func (DOMAIN + "/IndicatorMouseEvent", test_indicators_mouse_event); - Test.add_data_func (DOMAIN + "/IndicatorKeyboardEvent", test_indicators_keyboard_event); - } - - - private void test_indicators_mouse_event () - { - ObjectRegistry registry = ObjectRegistry.get_default (); - Logging.init_fatal_handler (); - - FakeIndicatorsModel indicator_model = IndicatorsModel.get_default () as FakeIndicatorsModel; - - IndicatorBar indicator_bar = registry.lookup ("IndicatorBar").get (0) as IndicatorBar; - assert (indicator_bar != null); - - IndicatorObjectView indicator_object_view0 = indicator_bar.get_indicator_view_matching (indicator_model.indicator_object_0); - assert (indicator_object_view0 != null); - IndicatorObjectView indicator_object_view1 = indicator_bar.get_indicator_view_matching (indicator_model.indicator_object_1); - assert (indicator_object_view1 != null); - - /* Hack to remove the default entries: because get_entries has not been overriden in FakeIndicatorObject */ - indicator_object_view0.remove_first_entry (); - indicator_object_view1.remove_first_entry (); - - indicator_bar.do_queue_redraw (); - - IndicatorObjectEntryView object_entry0 = indicator_object_view0.get_entry_view (entry0); - assert (object_entry0 != null); - IndicatorObjectEntryView object_entry1 = indicator_object_view1.get_entry_view (entry1); - assert (object_entry1 != null); - - // Test button press on first indicator - director.button_press (object_entry0, 1, true, 1.0f, 1.0f, false); - assert (object_entry0.is_open () == true); - assert (object_entry1.is_open () == false); - director.do_wait_for_timeout (1000); - - // Test button press on second indicator - director.button_press (object_entry1, 1, true, 1.0f, 1.0f, false); - assert (object_entry0.is_open () == false); - assert (object_entry1.is_open () == true); - director.do_wait_for_timeout (1000); - - // Press to close - director.button_press (object_entry1, 1, true, 1.0f, 1.0f, false); - assert (object_entry0.is_open () == false); - assert (object_entry1.is_open () == false); - - } - - private void test_indicators_keyboard_event () - { - ObjectRegistry registry = ObjectRegistry.get_default (); - Logging.init_fatal_handler (); - - FakeIndicatorsModel indicator_model = IndicatorsModel.get_default () as FakeIndicatorsModel; - - IndicatorBar indicator_bar = registry.lookup ("IndicatorBar").get (0) as IndicatorBar; - assert (indicator_bar != null); - - IndicatorObjectView indicator_object_view0 = indicator_bar.get_indicator_view_matching (indicator_model.indicator_object_0); - assert (indicator_object_view0 != null); - IndicatorObjectView indicator_object_view1 = indicator_bar.get_indicator_view_matching (indicator_model.indicator_object_1); - assert (indicator_object_view1 != null); - - IndicatorObjectEntryView object_entry0 = indicator_object_view0.get_entry_view (entry0); - assert (object_entry0 != null); - IndicatorObjectEntryView object_entry1 = indicator_object_view1.get_entry_view (entry1); - assert (object_entry1 != null); - - //Simulate key navigation - director.do_wait_for_timeout (1000); - director.button_press (object_entry0, 1, true, 1.0f, 1.0f, false); - assert (object_entry0.is_open () == true); - assert (object_entry1.is_open () == false); - director.do_wait_for_timeout (1000); - - object_entry0.entry.menu.move_current (Gtk.MenuDirectionType.CHILD); - assert (object_entry0.is_open () == false); - assert (object_entry1.is_open () == true); - director.do_wait_for_timeout (1000); - object_entry1.entry.menu.move_current (Gtk.MenuDirectionType.PARENT); - assert (object_entry0.is_open () == true); - assert (object_entry1.is_open () == false); - director.do_wait_for_timeout (1000); - - } - } -} - diff --git a/vala_tests/ui/test-quicklist.vala b/vala_tests/ui/test-quicklist.vala deleted file mode 100644 index 576aa3fcb..000000000 --- a/vala_tests/ui/test-quicklist.vala +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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> - * - */ - -using Unity; -using Unity.Testing; -using Unity.Launcher; - -namespace Unity.Tests.UI -{ - public class QuicklistSuite : Object - { - private const string DOMAIN = "/UI/Quicklist"; - - Unity.Testing.Window? window; - Clutter.Stage? stage; - - public QuicklistSuite () - { - Logging.init_fatal_handler (); - - /* Testup the test window */ - Unity.favorites_singleton = new TestFavorites (); - window = new Unity.Testing.Window (true, 1024, 600); - window.init_test_mode (); - stage = window.stage; - window.title = "Quicklist Tests"; - window.show_all (); - - Test.add_data_func (DOMAIN + "/ControllerShowLabel", - test_controller_show_label); - - - /* Keep this one last, it's a dummy to clean up the state as Vala cant - * deal with the standard TestSuite stuff properly - */ - Test.add_data_func (DOMAIN +"/Teardown", test_teardown); - } - - private void test_teardown () - { - //window.destroy (); - stage = null; - } - - private void test_controller_show_label () - { -/* - string img = TESTDIR + "/data/quicklist_controller_show_label.png"; - ObjectRegistry registry = ObjectRegistry.get_default (); - - Logging.init_fatal_handler (); - - ScrollerModel scroller = (registry.lookup ("UnityScrollerModel")[0]) as ScrollerModel; - ScrollerChild first = scroller[0] as ScrollerChild; - - QuicklistController qlcontroller = QuicklistController.get_default (); - qlcontroller.show_label ("Ubuntu Software Centre", first); - - while (Gtk.events_pending ()) - Gtk.main_iteration (); - - assert (Utils.compare_snapshot (stage, img, 54, 30, 200, 50)); - - qlcontroller.close_menu (); - */ - } - - } -} diff --git a/vala_tests/ui/test-ui.vala b/vala_tests/ui/test-ui.vala deleted file mode 100644 index af448a648..000000000 --- a/vala_tests/ui/test-ui.vala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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> - * - */ -using Gee; -using Unity; -using Unity.Testing; -using Unity.Tests.UI; - -namespace Unity.Tests.UI -{ -public class TestFavorites : Unity.Favorites - { - public override ArrayList<string> get_favorites () - { - var retlist = new ArrayList<string> (); - retlist.add ("app-firefox"); - return retlist; - } - - public override string find_uid_for_desktop_file (string desktop_file) - { - return "app-firefox"; - } - - public override void add_favorite (string uid) - { - } - public override void remove_favorite (string uid) - { - } - public override bool is_favorite (string uid) - { - return true; - } - - public override string? get_string (string uid, string name) - { - if (name == "type") - return "application"; - - return "/usr/share/applications/firefox.desktop"; - } - - public override void set_string (string uid, string name, string value) - { - } - - public override int? get_int (string uid, string name) - { - return null; - } - public override void set_int (string uid, string name, int value) - { - } - - - public override float? get_float (string uid, string name) - { - return null; - } - public override void set_float (string uid, string name, float value) - { - } - - public override bool? get_bool (string uid, string name) - { - return null; - } - - public override void set_bool (string uid, string name, bool value) - { - } - } -} - -public class Main -{ - public static int main (string[] args) - { - Logging logger; - QuicklistSuite quicklist_suite; - HomeButtonSuite home_button_suite; - AutomationBasicTestSuite basic_test_suite; - IndicatorTestSuite indicator_test_suite; - - - Environment.set_variable ("UNITY_DISABLE_TRAY", "1", true); - Environment.set_variable ("UNITY_DISABLE_IDLES", "1", true); - Environment.set_variable ("UNITY_PANEL_INDICATORS_SKIP", "all", true); - - Gtk.init (ref args); - Gtk.Settings.get_default ().gtk_xft_dpi = 96 * 1024; - - Ctk.init (ref args); - Test.init (ref args); - - logger = new Logging (); - - basic_test_suite = new AutomationBasicTestSuite (); - quicklist_suite = new QuicklistSuite (); - home_button_suite = new HomeButtonSuite (); - indicator_test_suite = new IndicatorTestSuite (); - - Timeout.add_seconds (3, ()=> { - Test.run (); - Gtk.main_quit (); - return false; - }); - - Gtk.main (); - - return 0; - } -} diff --git a/vala_tests/unit/Makefile.am b/vala_tests/unit/Makefile.am deleted file mode 100644 index ce051f9b9..000000000 --- a/vala_tests/unit/Makefile.am +++ /dev/null @@ -1,85 +0,0 @@ -SUBDIRS = data - -noinst_PROGRAMS = test-unit - -TESTDIR = $(top_srcdir)/tests/unit - -test_unit_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/unity \ - -I$(top_srcdir)/unity-private \ - -I$(top_srcdir)/src \ - -DTESTDIR=\"$(TESTDIR)\" \ - $(BASE_CFLAGS) - -test_unit_LDADD = \ - $(top_builddir)/unity/libunity.la \ - $(top_builddir)/unity-private/libunity-private.la \ - $(BASE_LIBS) \ - $(MAINTAINER_LIBS) - -test_unit_VALAFLAGS = \ - --vapidir=$(top_srcdir)/unity \ - --vapidir=$(top_srcdir)/unity-private \ - --vapidir=$(top_srcdir)/src \ - --vapidir=$(top_srcdir)/vapi/ \ - --vapidir=$(top_srcdir)/tests \ - --vapidir=$(top_srcdir)/tests/unit \ - --pkg gio-2.0 \ - --pkg Bamf-0.2 \ - --pkg clutter-1.0 \ - --pkg clutter-gtk-0.10 \ - --pkg config \ - --pkg dbus-glib-1 \ - --pkg Dbusmenu-Glib-0.2 \ - --pkg dee-1.0 \ - --pkg gtk+-2.0 \ - --pkg gdk-2.0 \ - --pkg gee-1.0 \ - --pkg x11 \ - --pkg gtk+-2.0 \ - --pkg gee-1.0 \ - --pkg indicator \ - --pkg clutk-0.3 \ - --pkg launcher-0.3 \ - --pkg posix \ - --pkg test-const \ - --pkg unique-1.0 \ - --pkg unity \ - --pkg unity-const \ - --pkg unity-private \ - $(MAINTAINER_VALAFLAGS) - -test_unit_SOURCES = \ - test-dbusmenu-quicklists.vala \ - test-launcher.vala \ - test-panel-indicator-object-entry-view.vala \ - test-panel-indicator-object-view.vala \ - test-places-place-file-model.vala \ - test-places-place.vala \ - test-places.vala \ - test-place.vala \ - test-place-browser.vala \ - test-io.vala \ - test-appinfo-manager.vala \ - test-unity-pixbuf-cache.vala \ - test-unit.vala - -# GTester stuff -XML_REPORT = test-unit-results.xml -HTML_REPORT = test-unit-results.html - -unit-tester: test-unit - @gtester -o=$(XML_REPORT) ./test-unit - -check-report: - @gtester -o=$(XML_REPORT) -k ./test-unit \ - && (gtester-report $(XML_REPORT) \ - | sed 's/GTester Unit Test Report</>GTester Unit Test Report (normal)</' \ - > $(HTML_REPORT)) \ - && xdg-open $(HTML_REPORT) - -check-local: unit-tester - -EXTRA_DIST = test-const.vapi -CLEANFILES = *.stamp $(XML_REPORT) $(HTML_REPORT) *.c diff --git a/vala_tests/unit/test-dbusmenu-quicklists.vala b/vala_tests/unit/test-dbusmenu-quicklists.vala deleted file mode 100644 index 029c9b0e7..000000000 --- a/vala_tests/unit/test-dbusmenu-quicklists.vala +++ /dev/null @@ -1,188 +0,0 @@ -/* - * test-launcher.vala - * 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 as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - * - * Authored by Gordon Allott <gord.allott@canonical.com> - */ -using Unity; -using Unity.Launcher; -using Unity.Testing; - -/* TODO - add more tests once we have bamf and can test the controllers */ -namespace Unity.Tests.Unit -{ - public class TestScrollerChildController : ScrollerChildController - { - public TestScrollerChildController (ScrollerChild child_) - { - Object (child: child_); - } - - construct - { - name = "Testing"; - } - - public override void get_menu_actions (ScrollerChildController.menu_cb callback) - { - // our actions menu goes as follows - // + Root - // - Checked Menu Item, unchecked, "Unchecked" - // - Checked Menu Item, checked, "Checked" - // - Separator - // - Label "A Label" - // - Radio Menu Item, checked, "Radio Active" - // - Radio Menu Item, unchecked, "Radio Unactive" - Dbusmenu.Menuitem root = new Dbusmenu.Menuitem (); - root.set_root (true); - - Dbusmenu.Menuitem menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Unchecked"); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_CHECK); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_UNCHECKED); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Checked"); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_CHECK); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set ("type", Dbusmenu.CLIENT_TYPES_SEPARATOR); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "A Label"); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Radio Active"); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_RADIO); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Radio Unactive"); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_RADIO); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_UNCHECKED); - root.child_append (menuitem); - - callback (root); - } - - public override void get_menu_navigation (ScrollerChildController.menu_cb callback) - { - // just tests that the order is correct - Dbusmenu.Menuitem root = new Dbusmenu.Menuitem (); - root.set_root (true); - - Dbusmenu.Menuitem menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "1"); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "2"); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - root.child_append (menuitem); - - menuitem = new Dbusmenu.Menuitem (); - menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "3"); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_ENABLED, true); - menuitem.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, true); - root.child_append (menuitem); - - callback (root); - } - - public override void activate () - { - } - - public override QuicklistController? get_menu_controller () - { - QuicklistController new_menu = new ApplicationQuicklistController (this); - return new_menu; - } - } - - public class QuicklistSuite - { - public QuicklistSuite () - { - Test.add_data_func ("/Unity/Launcher/TestDbusMenu", test_dbus_menu); - } - - private void test_dbus_menu() - { - ScrollerChild child = new TestScrollerChild (); - TestScrollerChildController controller = new TestScrollerChildController(child); - ApplicationQuicklistController menu = controller.get_menu_controller () as ApplicationQuicklistController; - menu.state = QuicklistControllerState.LABEL; - - unowned GLib.List<Ctk.MenuItem> menuitems = null; - assert (menuitems.length () == 0); - - menu.state = QuicklistControllerState.MENU; - - // this assert here will only work for our local dbusmenu's because they return - // immediately. remote dbusmenu's need to be slightly more clever - menuitems = menu.get_view ().get_items (); - assert (menuitems.length () >= 10); - - assert (menuitems.data is Ctk.CheckMenuItem); - assert ((menuitems.data as Ctk.CheckMenuItem).active == false); - menuitems = menuitems.next; - - assert (menuitems.data is Ctk.CheckMenuItem); - assert ((menuitems.data as Ctk.CheckMenuItem).active == true); - menuitems = menuitems.next; - - assert (menuitems.data is Ctk.MenuSeperator); - menuitems = menuitems.next; - - assert (menuitems.data is Ctk.MenuItem); - assert ((menuitems.data as Ctk.MenuItem).label == "A Label"); - menuitems = menuitems.next; - - assert (menuitems.data is Ctk.RadioMenuItem); - assert ((menuitems.data as Ctk.RadioMenuItem).active == true); - menuitems = menuitems.next; - - assert (menuitems.data is Ctk.RadioMenuItem); - assert ((menuitems.data as Ctk.RadioMenuItem).active == true); - menuitems = menuitems.next; - } - } -} diff --git a/vala_tests/unit/test-launcher.vala b/vala_tests/unit/test-launcher.vala deleted file mode 100644 index 0c13609b4..000000000 --- a/vala_tests/unit/test-launcher.vala +++ /dev/null @@ -1,223 +0,0 @@ -/* - * test-launcher.vala - * 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 as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - * - * Authored by Gordon Allott <gord.allott@canonical.com> - */ -using Unity; -using Unity.Launcher; -using Unity.Testing; - -namespace Unity.Tests.Unit -{ - // can't use this code yet because bamf hates testing :'( -/* - public class TestBamfIndicator : Bamf.Indicator - { - public TestBamfIndicator () - { - } - - construct - { - } - - public new string get_dbus_menu_path () - { - return ""; - } - public new string get_remote_address () - { - return ""; - } - public new string get_remote_path () - { - return ""; - } - } -*/ - - public class TestBamfApplication : Bamf.Application - { - public bool test_is_active = true; - public bool test_is_urgent = false; - public bool test_user_visible = true; - public bool test_is_running = true; - - public string desktop_file = "firefox.desktop"; - public string name = "firefox"; - public string icon = "firefox"; - private GLib.List<Bamf.View> children; - - public TestBamfApplication () - { - Object (path: "/null"); - } - - construct - { - children = new GLib.List<Bamf.View> (); - } - - public new unowned string get_desktop_file () - { - return desktop_file; - } - - GLib.List<Object> temp_list; - public new unowned GLib.List get_windows () - { - temp_list = new GLib.List<Object> (); - return temp_list; - } - - public override GLib.List get_children () - { - GLib.List<Bamf.View> tmplist = new GLib.List<Bamf.View> (); - foreach (Bamf.View child in children) - { - tmplist.append (child); - } - return tmplist; - } - - public new GLib.Array get_xids () - { - Array<uint32> retarray = new Array<uint32> (true, false, (uint)sizeof (uint32)); - return retarray; - } - - public override string get_icon () - { - return icon; - } - - public override string get_name () - { - return name; - } - - public override bool is_active () - { - return test_is_active; - } - - public override bool is_running () - { - return test_is_running; - } - - public override bool is_urgent () - { - return test_is_urgent; - } - - public new bool user_visible () - { - return test_user_visible; - } - - public override unowned string view_type () - { - return "test"; - } - } - - public class TestScrollerChild : ScrollerChild - { - } - - public class LauncherSuite - { - public LauncherSuite () - { - Test.add_data_func ("/Unity/Launcher/TestScrollerModel", test_scroller_model); - Test.add_data_func ("/Unity/Launcher/TestScrollerChildController", test_scroller_child_controller); - } - - - // very basic tests for scroller model, makes sure its list interface works - // as expected - private void test_scroller_model () - { - ScrollerModel model = new ScrollerModel (); - ScrollerChild child_a = new TestScrollerChild (); - ScrollerChild child_b = new TestScrollerChild (); - ScrollerChild child_c = new TestScrollerChild (); - - model.add (child_a); - model.add (child_c); - model.insert (child_b, 1); - - // make sure each model is in the correct position - assert (model[1] == child_b); - assert (model[2] == child_c); - - // make sure non of the children got lost somehow - foreach (ScrollerChild child in model) - { - assert (child is ScrollerChild); - } - - assert (child_a in model); - - // make sure that after removing a child, everything is still in the correct order - model.remove (child_b); - assert (model[1] == child_c); - } - - private void test_scroller_child_controller () - { - TestBamfApplication test_app = new TestBamfApplication (); - ScrollerChild child = new TestScrollerChild (); - ApplicationController controller = new ApplicationController (Config.TESTUNITDIR + "/data/test_desktop_file.desktop", child); - - test_app.name = "Test Application-New"; - test_app.desktop_file = Config.TESTUNITDIR + "/data/test_desktop_file.desktop"; - test_app.icon = Config.TESTUNITDIR + "/data/test_desktop_icon.png"; - test_app.test_is_active = true; - test_app.test_is_urgent = false; - test_app.test_user_visible = true; - test_app.test_is_running = true; - - //assert that the controller set the model into the correct state - assert (child.running == false); - assert (child.active == false); - assert (child.needs_attention == false); - assert (controller.name == "Test Application"); - - // unfortunately we need to disable the bamf tests for now, bamf is not letting us subclass for fake objects -/* - controller.attach_application (test_app); - assert (child.running == true); - assert (child.active == true); - assert (controller.name == "Test Application-New"); - - test_app.test_is_active = false; - test_app.active_changed (test_app.test_is_active); - assert (child.active == false); - - test_app.test_is_running = false; - test_app.running_changed (test_app.test_is_running); - assert (child.running == false); - assert (controller.debug_is_application_attached () == false); -*/ - } - } -} diff --git a/vala_tests/unit/test-panel-indicator-object-entry-view.vala b/vala_tests/unit/test-panel-indicator-object-entry-view.vala deleted file mode 100644 index d6d20a87c..000000000 --- a/vala_tests/unit/test-panel-indicator-object-entry-view.vala +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2009 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> - * - */ -using Unity; -using Unity.Testing; -using Unity.Panel.Indicators; - -namespace Unity.Tests.Unit -{ - public class PanelIndicatorObjectEntryViewSuite : Object - { - public const string DOMAIN = "/Unit/Panel/Indicator/ObjectEntry"; - - private Indicator.ObjectEntry entry; - private Gtk.Menu menu; - private Gtk.Label label; - private Gtk.Image image; - - public PanelIndicatorObjectEntryViewSuite () - { - Logging.init_fatal_handler (); - - entry = new Indicator.ObjectEntry (); - - menu = new Gtk.Menu (); - entry.menu = menu; - - label = new Gtk.Label ("Test Label"); - entry.label = label; - - image = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - entry.image = image; - - Test.add_data_func (DOMAIN + "/Allocation", test_allocation); - Test.add_data_func (DOMAIN + "/LabelSync", test_label_sync); - Test.add_data_func (DOMAIN + "/ImageSync", test_image_sync); - } - - private void test_allocation () - { - var e = new IndicatorObjectEntryView (entry); - - assert (e is IndicatorObjectEntryView); - } - - private void test_label_sync () - { - var e = new IndicatorObjectEntryView (entry); - - assert (e is IndicatorObjectEntryView); - - /* Make sure text is in sync */ - assert (e.text.text == label.label); - - /* Update the label and check again */ - label.label = "Test Label 2"; - assert (e.text.text == label.label); - - label.label = "Test Label"; - } - - private void test_image_sync () - { - var e = new IndicatorObjectEntryView (entry); - assert (e is IndicatorObjectEntryView); - - /* Test that the icon name has synced */ - assert (e.image.stock_id == image.icon_name); - - /* Test that if it changes entry keeps it in sync */ - image.icon_name = "gtk-close"; - assert (e.image.stock_id == image.icon_name); - - /* Test pixbuf */ - var p = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8, 100, 100); - image.pixbuf = p; - assert (e.image.pixbuf == image.pixbuf); - - image.icon_name = "gtk-apply"; - } - } -} diff --git a/vala_tests/unit/test-panel-indicator-object-view.vala b/vala_tests/unit/test-panel-indicator-object-view.vala deleted file mode 100644 index ad8286910..000000000 --- a/vala_tests/unit/test-panel-indicator-object-view.vala +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2009 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 Jay Taoko <jay.taoko.patel@canonical.com> - * - */ -using Unity; -using Unity.Testing; -using Unity.Panel.Indicators; - -namespace Unity.Tests.Unit -{ - public class FakeIndicatorObject: Indicator.Object - { - public Gee.ArrayList<Indicator.ObjectEntry> indicator_entry_array; - public Gtk.Label _label; - public Gtk.Image _image; - public Gtk.Menu _menu; - - public FakeIndicatorObject () - { - Object(); - } - - construct - { - START_FUNCTION (); - indicator_entry_array = new Gee.ArrayList< unowned Indicator.ObjectEntry> (); - - _label = new Gtk.Label ("Test Label"); - _image = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - _menu = new Gtk.Menu (); - END_FUNCTION (); - } - - public void add_entry(Indicator.ObjectEntry entry) - { - int pos = indicator_entry_array.index_of (entry); - if (pos != -1) - return; - - indicator_entry_array.add (entry); - entry_added (entry); - } - - public void remove_entry(Indicator.ObjectEntry entry) - { - int pos = indicator_entry_array.index_of (entry); - if (pos != -1) - { - indicator_entry_array.remove_at (pos); - entry_removed (entry); - } - } - - public override unowned Gtk.Label get_label () - { - return this._label; - } - - public override unowned Gtk.Image get_image () - { - return this._image; - } - - public override unowned Gtk.Menu get_menu () - { - return this._menu; - } - -// public override GLib.List<unowned Indicator.ObjectEntry> get_entries () -// { -// GLib.List<unowned Indicator.ObjectEntry> list = new GLib.List<unowned Indicator.ObjectEntry> (); -// foreach(unowned Indicator.ObjectEntry element in indicator_entry_array) -// { -// list.append (element); -// } -// return list; -// } - } - - public class PanelIndicatorObjectViewSuite : Object - { - public const string DOMAIN = "/Unit/Panel/Indicator/ObjectView"; - - private Indicator.ObjectEntry entry; - private Gtk.Menu menu; - private Gtk.Label label; - private Gtk.Image image; - - public PanelIndicatorObjectViewSuite () - { - Logging.init_fatal_handler (); - - entry = new Indicator.ObjectEntry (); - - menu = new Gtk.Menu (); - entry.menu = menu; - - label = new Gtk.Label ("Test Label"); - entry.label = label; - - image = new Gtk.Image.from_icon_name ("gtk-apply", Gtk.IconSize.MENU); - entry.image = image; - - Test.add_data_func (DOMAIN + "/FakeIndicator", test_fake_indicator_object); - Test.add_data_func (DOMAIN + "/FakeIndicatorAddEntry", test_indicator_add_entry); - Test.add_data_func (DOMAIN + "/TestEntryView", test_indicator_enty_view); - } - - private void test_fake_indicator_object () - { - var fakeobject = new FakeIndicatorObject (); - - assert (fakeobject is FakeIndicatorObject); - } - - private void test_indicator_add_entry () - { - var fakeobject = new FakeIndicatorObject (); - var e = new IndicatorObjectView (fakeobject); - - fakeobject.add_entry (entry); - - assert (e.find_entry (entry)); - } - - private void test_indicator_enty_view () - { - var fakeobject = new FakeIndicatorObject (); - var e = new IndicatorObjectView (fakeobject); - - fakeobject.add_entry (entry); - IndicatorObjectEntryView? entry_view = e.get_entry_view (entry); - - assert (entry_view.entry == entry); - assert (entry_view.entry.label == entry.label); - assert (entry_view.entry.image == entry.image); - assert (entry_view.entry.menu == entry.menu); - } - } -} diff --git a/vala_tests/unit/test-places-place.vala b/vala_tests/unit/test-places-place.vala deleted file mode 100644 index c99369603..000000000 --- a/vala_tests/unit/test-places-place.vala +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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> - * - */ -using Unity; -using Unity.Testing; -using Unity.Places; -using GLib.Test; - -namespace Unity.Tests.Unit -{ - public class PlacesPlaceSuite : Object - { - public const string DOMAIN = "/Unit/Places/Place"; - - public PlacesPlaceSuite () - { - Logging.init_fatal_handler (); - - Test.add_data_func (DOMAIN + "/Allocation", test_allocation); - Test.add_data_func (DOMAIN + "/SimplePlaceFile", test_simple_placefile); - Test.add_data_func (DOMAIN + "/AdvancedPlaceFile", test_advanced_place_file); - Test.add_data_func (DOMAIN + "/BadSimplePlaceFile", test_bad_simple_place_file); - Test.add_data_func (DOMAIN + "/BadAdvancedPlaceFile", test_bad_advanced_place_file); - } - - private void test_allocation () - { - var place = new Places.Place ("__name__", "__path__"); - assert (place is Places.Place); - assert (place.dbus_name == "__name__"); - assert (place.dbus_path == "__path__"); - } - - private void test_simple_placefile () - { - var file = new KeyFile (); - try { - file.load_from_file (Config.TESTUNITDIR + "/data/place0.place", - KeyFileFlags.NONE); - } catch (Error e) { - error ("Unable to load test place: %s", e.message); - } - - var place = Places.Place.new_from_keyfile (file); - assert (place is Places.Place); - - /* Test Place group was loaded properly */ - assert (place.dbus_name == "org.ayatana.Unity.Place0"); - assert (place.dbus_path == "/org/ayatana/Unity/Place0"); - - /* Test entries were loaded properly */ - assert (place.n_entries == 0); - } - - private void test_advanced_place_file () - { - var file = new KeyFile (); - try { - file.load_from_file (Config.TESTUNITDIR + "/data/place1.place", - KeyFileFlags.NONE); - } catch (Error error) { - warning ("Unable to load test place: %s", error.message); - } - - var place = Places.Place.new_from_keyfile (file); - assert (place is Places.Place); - - /* Test Place group was loaded properly */ - assert (place.dbus_name == "org.ayatana.Unity.Place1"); - assert (place.dbus_path == "/org/ayatana/Unity/Place1"); - - /* Test entries were loaded properly */ - assert (place.n_entries == 3); - - /* Test individual entry's properties were loaded correctly */ - PlaceEntryDbus? e; - - e = place.get_nth_entry (0) as PlaceEntryDbus;; - assert (e is PlaceEntry); - assert (e.dbus_path == "/org/ayatana/Unity/Place1/Entry1"); - assert (e.name == "One"); - assert (e.icon == "gtk-apply"); - assert (e.description == "One Description"); - assert (e.show_global == true); - assert (e.show_entry == false); - - e = place.get_nth_entry (1) as PlaceEntryDbus; - assert (e is PlaceEntry); - assert (e.dbus_path == "/org/ayatana/Unity/Place1/Entry2"); - assert (e.name == "Two"); - assert (e.icon == "gtk-close"); - assert (e.description == "Two Description"); - assert (e.show_global == false); - assert (e.show_entry == true); - - e = place.get_nth_entry (2) as PlaceEntryDbus; - assert (e is PlaceEntry); - assert (e.dbus_path == "/org/ayatana/Unity/Place1/Entry3"); - assert (e.name == "Three"); - assert (e.icon == "gtk-cancel"); - assert (e.description == "Three Description"); - assert (e.show_global == false); - assert (e.show_entry == false); - } - - private void test_bad_simple_place_file () - { - var file = new KeyFile (); - try { - file.load_from_file (Config.TESTUNITDIR + "/data/place0.badplace", - KeyFileFlags.NONE); - } catch (Error error) { - warning ("Unable to load test place: %s", error.message); - } - - if (trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) - { - var place = Places.Place.new_from_keyfile (file); - assert (place is Places.Place); - Posix.exit (0); - } - trap_has_passed (); - trap_assert_stderr ("*Does not contain 'Place' grou*"); - } - - private void test_bad_advanced_place_file () - { - var file = new KeyFile (); - try { - file.load_from_file (Config.TESTUNITDIR + "/data/place1.badplace", - KeyFileFlags.NONE); - } catch (Error error) { - warning ("Unable to load test place: %s", error.message); - } - - if (trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) - { - var place = Places.Place.new_from_keyfile (file); - assert (place is Places.Place); - Posix.exit (0); - } - trap_has_passed (); - trap_assert_stderr ("*Does not contain valid DBusObjectPat*"); - } - } -} diff --git a/vala_tests/unit/test-places.vala b/vala_tests/unit/test-places.vala deleted file mode 100644 index 689ede92a..000000000 --- a/vala_tests/unit/test-places.vala +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */ -/* - * Copyright (C) 2009 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> - * - */ -using Unity; -using Unity.Testing; - -namespace Unity.Tests.Unit -{ - public class PlacesSuite - { - public PlacesSuite () - { - /*Test.add_func ("/Unit/Places/TestPlace", () => { - - Logging.init_fatal_handler (); - - var place = new TestPlace (); - - assert (place is TestPlace); - - var loop = new MainLoop (null, false); - - try - { - DBus.Connection conn = DBus.Bus.get (DBus.BusType.SESSION); - - Utils.register_object_on_dbus (conn, - "/com/canonical/Unity/Place", - place); - loop.get_context ().iteration (true); - } - catch (Error e) - { - warning ("TestPlace error: %s", e.message); - } - });*/ - } - - /*public class TestPlace : Unity.Place - { - public TestPlace () - { - Object (name:"neil", icon_name:"gtk-apply", tooltip:"hello"); - } - - construct - { - this.is_active.connect ((a) => {print (@"$a\n");}); - } - }*/ - } -} |
