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 /src | |
| parent | 491e2f0f05062b3e1032054d573e876ca4f68ddb (diff) | |
| parent | 8b5d71a9a2292a1d29b1bfcbc98c6866ea72f543 (diff) | |
Import upstream version 3.2.8upstream-3.2.8
(bzr r55.4.37)
Diffstat (limited to 'src')
49 files changed, 3563 insertions, 743 deletions
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/src/UBusMessages.h b/src/UBusMessages.h new file mode 100644 index 000000000..a4b94ff34 --- /dev/null +++ b/src/UBusMessages.h @@ -0,0 +1,27 @@ +/* + * 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 UBUS_MESSAGES_H +#define UBUS_MESSAGES_H + + +// Add ubus messages here so we can easily export them around the place +// keep ordered + +#define UBUS_HOME_BUTTON_ACTIVATED "PANEL_HOME_ACTIVATED" + +#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) \ |
