diff options
| author | Neil Jagdish Patel <neil.patel@canonical.com> | 2011-03-22 14:15:09 +0000 |
|---|---|---|
| committer | Neil Jagdish Patel <neil.patel@canonical.com> | 2011-03-22 14:15:09 +0000 |
| commit | 5300e5d870a9a8ff4e4c6600ffe46571e13f8740 (patch) | |
| tree | ee2fd661b3883d4bc8cfdb5b5b2a4fd5838266e8 | |
| parent | e2c0ed652b75f54aa8b37e5e86439ff56ae87aef (diff) | |
Beginnings of multiple panel support
(bzr r989.1.1)
| -rw-r--r-- | src/PanelController.cpp | 144 | ||||
| -rw-r--r-- | src/PanelController.h | 51 | ||||
| -rw-r--r-- | src/PanelView.cpp | 14 | ||||
| -rw-r--r-- | src/PanelView.h | 3 | ||||
| -rw-r--r-- | src/PlacesController.h | 1 | ||||
| -rw-r--r-- | src/UScreen.cpp | 121 | ||||
| -rw-r--r-- | src/UScreen.h | 53 | ||||
| -rw-r--r-- | src/unityshell.cpp | 3 | ||||
| -rw-r--r-- | src/unityshell.h | 3 |
9 files changed, 390 insertions, 3 deletions
diff --git a/src/PanelController.cpp b/src/PanelController.cpp new file mode 100644 index 000000000..9b1c2dc8f --- /dev/null +++ b/src/PanelController.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "PanelController.h" + +#include "UScreen.h" + +#include "unitya11y.h" +#include "unity-util-accessible.h" + +PanelController::PanelController () +{ + UScreen *screen = UScreen::GetDefault (); + + screen->changed.connect (sigc::mem_fun (this, &PanelController::OnScreenChanged)); + + OnScreenChanged (screen->GetPrimaryMonitor (), screen->GetMonitors ()); +} + +PanelController::~PanelController () +{ + +} + +void +PanelController::SetPrimary (nux::BaseWindow *window, bool primary) +{ + nux::Layout *layout = window->GetLayout (); + std::list<nux::Area *>::iterator it = layout->GetChildren ().begin (); + + static_cast<PanelView *> (*it)->SetPrimary (primary); +} + +// We need to put a panel on every monitor, and try and re-use the panels we already have +void +PanelController::OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors) +{ + std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end (); + int n_monitors = monitors.size (); + int i = 0; + + for (it = _windows.begin (); it != eit; ++it) + { + if (i < n_monitors) + { + nux::Geometry geo = monitors[i]; + geo.height = 24; + (*it)->SetGeometry (geo); + SetPrimary (*it, i == primary_monitor); + i++; + } + } + + // Add new ones if needed + if (i < n_monitors) + { + for (i = i; i < n_monitors; i++) + { + nux::BaseWindow *window; + PanelView *view; + nux::HLayout *layout; + + layout = new nux::HLayout(); + + view = new PanelView (); + view->SetMaximumHeight (24); + AddChild (view); + + layout->AddView (view, 1); + layout->SetContentDistribution (nux::eStackLeft); + layout->SetVerticalExternalMargin (0); + layout->SetHorizontalExternalMargin (0); + + window = new nux::BaseWindow(""); + window->SinkReference (); + window->SetConfigureNotifyCallback(&PanelController::WindowConfigureCallback, window); + window->SetLayout(layout); + window->SetBackgroundColor(nux::Color(0x00000000)); + window->ShowWindow(true); + window->EnableInputWindow(true, "panel", false, false); + window->InputWindowEnableStruts(true); + + nux::Geometry geo = monitors[i]; + geo.height = 24; + window->SetGeometry (geo); + SetPrimary (window, i == primary_monitor); + + /* FIXME: this should not be manual, should be managed with a + show/hide callback like in GAIL*/ + if (unity_a11y_initialized () == TRUE) + unity_util_accessible_add_window (window); + + _windows.push_back (window); + } + } + + if ((int)_windows.size () > n_monitors) + { + std::vector<nux::BaseWindow*>::iterator sit; + for (sit = it; sit != eit; ++sit) + { + (*sit)->UnReference (); + } + + _windows.erase (it, _windows.end ()); + } +} + +void +PanelController::WindowConfigureCallback (int window_width, + int window_height, + nux::Geometry& geo, + void *user_data) +{ + nux::BaseWindow *window = static_cast<nux::BaseWindow *> (user_data); + geo = window->GetGeometry (); +} + +const gchar * +PanelController::GetName () +{ + return "PanelController"; +} + +void +PanelController::AddProperties (GVariantBuilder *builder) +{ + +} diff --git a/src/PanelController.h b/src/PanelController.h new file mode 100644 index 000000000..6e96e7389 --- /dev/null +++ b/src/PanelController.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _PANEL_CONTROLLER_H_ +#define _PANEL_CONTROLLER_H_ + +#include <Nux/Nux.h> +#include <Nux/BaseWindow.h> +#include <vector> + +#include "Introspectable.h" +#include "PanelView.h" + +class PanelController : public nux::Object, public Introspectable +{ +public: + PanelController (); + ~PanelController (); + +protected: + const gchar * GetName (); + void AddProperties (GVariantBuilder *builder); + +private: + void SetPrimary (nux::BaseWindow *window, bool primary); + void OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors); + + static void WindowConfigureCallback (int window_width, + int window_height, + nux::Geometry& geo, + void *user_data); +private: + std::vector<nux::BaseWindow *> _windows; +}; + +#endif // _PANEL_CONTROLLER_H_ diff --git a/src/PanelView.cpp b/src/PanelView.cpp index fe24c8482..819525878 100644 --- a/src/PanelView.cpp +++ b/src/PanelView.cpp @@ -46,7 +46,8 @@ NUX_IMPLEMENT_OBJECT_TYPE (PanelView); PanelView::PanelView (NUX_FILE_LINE_DECL) : View (NUX_FILE_LINE_PARAM), _is_dirty (true), - _opacity (1.0f) + _opacity (1.0f), + _is_primary (false) { _needs_geo_sync = false; _style = new PanelStyle (); @@ -129,7 +130,7 @@ PanelView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) GfxContext.PopClippingRectangle (); - if (_needs_geo_sync) + if (_needs_geo_sync && _is_primary) { SyncGeometries (); _needs_geo_sync = false; @@ -371,6 +372,9 @@ PanelView::EndFirstMenuShow () { std::list<Area *>::iterator it; + if (!_is_primary) + return; + std::list<Area *> my_children = _layout->GetChildren (); for (it = my_children.begin(); it != my_children.end(); it++) { @@ -426,6 +430,12 @@ on_sync_geometries_done_cb (GObject *source, } void +PanelView::SetPrimary (bool primary) +{ + _is_primary = primary; +} + +void PanelView::SyncGeometries () { GVariantBuilder b; diff --git a/src/PanelView.h b/src/PanelView.h index 6af744f76..258a6a589 100644 --- a/src/PanelView.h +++ b/src/PanelView.h @@ -52,6 +52,8 @@ public: void OnEntryActivateRequest (const char *entry_id); void OnEntryActivated (const char *entry_id); void OnSynced (); + + void SetPrimary (bool primary); PanelHomeButton * HomeButton (); @@ -89,6 +91,7 @@ private: bool _is_dirty; float _opacity; bool _needs_geo_sync; + bool _is_primary; }; #endif // PANEL_VIEW_H diff --git a/src/PlacesController.h b/src/PlacesController.h index 6ebe9ead7..f4e2c2569 100644 --- a/src/PlacesController.h +++ b/src/PlacesController.h @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Gordon Allott <gord.allott@canonical.com> + * Neil Jagdish Patel <neil.patel@canonical.com> */ #ifndef PLACES_CONTROLLER_H diff --git a/src/UScreen.cpp b/src/UScreen.cpp new file mode 100644 index 000000000..8cb863883 --- /dev/null +++ b/src/UScreen.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "UScreen.h" + +static UScreen *_default_screen = NULL; + +UScreen::UScreen () +: _refresh_id (0) +{ + GdkScreen *screen; + + screen = gdk_screen_get_default (); + g_signal_connect (screen, "size-changed", + (GCallback)UScreen::Changed, this); + g_signal_connect (screen, "monitors-changed", + (GCallback)UScreen::Changed, this); + + Refresh (); +} + +UScreen::~UScreen () +{ + if (_default_screen == this) + _default_screen = NULL; + + g_signal_handlers_disconnect_by_func ((gpointer)gdk_screen_get_default (), + (gpointer)UScreen::Changed, + (gpointer)this); +} + +UScreen * +UScreen::GetDefault () +{ + if (G_UNLIKELY (!_default_screen)) + _default_screen = new UScreen (); + + return _default_screen; +} + +int +UScreen::GetPrimaryMonitor () +{ + return gdk_screen_get_primary_monitor (gdk_screen_get_default ()); +} + +nux::Geometry +UScreen::GetPrimaryMonitorGeometry () +{ + return _monitors[GetPrimaryMonitor ()]; +} + +std::vector<nux::Geometry>& +UScreen::GetMonitors () +{ + return _monitors; +} + +void +UScreen::Changed (GdkScreen *screen, UScreen *self) +{ + if (self->_refresh_id) + return; + + self->_refresh_id = g_idle_add ((GSourceFunc)UScreen::OnIdleChanged, self); +} + +gboolean +UScreen::OnIdleChanged (UScreen *self) +{ + self->_refresh_id = 0; + self->Refresh (); + + return FALSE; +} + +void +UScreen::Refresh () +{ + GdkScreen *screen; + int primary; + + screen = gdk_screen_get_default (); + primary = GetPrimaryMonitor (); + + _monitors.erase (_monitors.begin (), _monitors.end ()); + + g_print ("\nScreen geometry changed:\n"); + + for (int i = 0; i < gdk_screen_get_n_monitors (screen); i++) + { + GdkRectangle rect = { 0 }; + + gdk_screen_get_monitor_geometry (screen, i, &rect); + + nux::Geometry geo (rect.x, rect.y, rect.width, rect.height); + _monitors.push_back (geo); + + g_print (" Monitor %d%s\n", i, i == primary ? "(primary)" : ""); + g_print (" %dx%dx%dx%d\n", geo.x, geo.y, geo.width, geo.height); + } + + g_print ("\n"); + + changed.emit (primary, _monitors); +} diff --git a/src/UScreen.h b/src/UScreen.h new file mode 100644 index 000000000..9a7f1a2d1 --- /dev/null +++ b/src/UScreen.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef _UNITY_SCREEN_H_ +#define _UNITY_SCREEN_H_ + +#include <gdk/gdk.h> +#include <Nux/Nux.h> +#include <sigc++/sigc++.h> +#include <vector> + +class UScreen : public sigc::trackable +{ +public: + UScreen (); + ~UScreen (); + + static UScreen * GetDefault (); + + int GetPrimaryMonitor (); + nux::Geometry GetPrimaryMonitorGeometry (); + + std::vector<nux::Geometry>& GetMonitors (); + + // <void, primary_monitor, monitors> + sigc::signal<void, int, std::vector<nux::Geometry>&> changed; + +private: + static void Changed (GdkScreen *screen, UScreen *self); + static gboolean OnIdleChanged (UScreen *self); + void Refresh (); + +private: + std::vector<nux::Geometry> _monitors; + guint32 _refresh_id; +}; + +#endif // _UNITY_SCREEN_H_ diff --git a/src/unityshell.cpp b/src/unityshell.cpp index 48fe43cd3..5e893486b 100644 --- a/src/unityshell.cpp +++ b/src/unityshell.cpp @@ -917,6 +917,7 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) /* Setup panel */ LOGGER_START_PROCESS ("initLauncher-Panel"); + self->panelController = new PanelController (); self->panelView = new PanelView (); self->AddChild (self->panelView); @@ -936,7 +937,7 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->panelWindow->SetConfigureNotifyCallback(&UnityScreen::panelWindowConfigureCallback, self); self->panelWindow->SetLayout(layout); self->panelWindow->SetBackgroundColor(nux::Color(0x00000000)); - self->panelWindow->ShowWindow(true); + //self->panelWindow->ShowWindow(true); self->panelWindow->EnableInputWindow(true, "panel", false, false); self->panelWindow->InputWindowEnableStruts(true); diff --git a/src/unityshell.h b/src/unityshell.h index 5a6a46d9b..1cb0c5338 100644 --- a/src/unityshell.h +++ b/src/unityshell.h @@ -33,6 +33,8 @@ #include "Introspectable.h" #include "Launcher.h" #include "LauncherController.h" +#include "PanelController.h" +#include "UScreen.h" #include "PanelView.h" #include "PanelHomeButton.h" #include "PlacesController.h" @@ -204,6 +206,7 @@ class UnityScreen : Launcher *launcher; LauncherController *controller; + PanelController *panelController; PanelView *panelView; PanelHomeButton *panelHomeButton; PlacesController *placesController; |
