Back to index

unity  6.0.0
PanelController.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2011 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
00018  */
00019 
00020 #include "PanelController.h"
00021 
00022 #include <vector>
00023 #include <NuxCore/Logger.h>
00024 #include <Nux/BaseWindow.h>
00025 #include <UnityCore/Variant.h>
00026 
00027 #include "unity-shared/UScreen.h"
00028 #include "PanelView.h"
00029 #include "unity-shared/PanelStyle.h"
00030 
00031 namespace unity
00032 {
00033 namespace panel
00034 {
00035 
00036 const char window_title[] = "unity-panel";
00037 
00038 namespace
00039 {
00040 nux::logging::Logger logger("unity.panel");
00041 }
00042 
00043 class Controller::Impl
00044 {
00045 public:
00046   Impl();
00047 
00048   void FirstMenuShow();
00049   void QueueRedraw();
00050 
00051   std::vector<Window> GetTrayXids() const;
00052   std::vector<nux::View*> GetPanelViews() const;
00053   std::vector<nux::Geometry> GetGeometries() const;
00054 
00055   // NOTE: nux::Property maybe?
00056   void SetOpacity(float opacity);
00057   void SetOpacityMaximizedToggle(bool enabled);
00058 
00059   float opacity() const;
00060 
00061   void SetMenuShowTimings(int fadein, int fadeout, int discovery,
00062                           int discovery_fadein, int discovery_fadeout);
00063 
00064   void OnScreenChanged(unsigned int primary_monitor, std::vector<nux::Geometry>& monitors, Introspectable *iobj);
00065 private:
00066   typedef nux::ObjectPtr<nux::BaseWindow> BaseWindowPtr;
00067 
00068   unity::PanelView* ViewForWindow(BaseWindowPtr const& window) const;
00069 
00070   static void WindowConfigureCallback(int            window_width,
00071                                       int            window_height,
00072                                       nux::Geometry& geo,
00073                                       void*          user_data);
00074 
00075 private:
00076   std::vector<BaseWindowPtr> windows_;
00077   float opacity_;
00078   bool opacity_maximized_toggle_;
00079   int menus_fadein_;
00080   int menus_fadeout_;
00081   int menus_discovery_;
00082   int menus_discovery_fadein_;
00083   int menus_discovery_fadeout_;
00084 };
00085 
00086 
00087 Controller::Impl::Impl()
00088   : opacity_(1.0f)
00089   , opacity_maximized_toggle_(false)
00090   , menus_fadein_(0)
00091   , menus_fadeout_(0)
00092   , menus_discovery_(0)
00093   , menus_discovery_fadein_(0)
00094   , menus_discovery_fadeout_(0)
00095 {
00096 }
00097 
00098 std::vector<Window> Controller::Impl::GetTrayXids() const
00099 {
00100   std::vector<Window> xids;
00101 
00102   for (auto window: windows_)
00103   {
00104     xids.push_back(ViewForWindow(window)->GetTrayXid());
00105   }
00106 
00107   return xids;
00108 }
00109 
00110 std::vector<nux::View*> Controller::Impl::GetPanelViews() const
00111 {
00112   std::vector<nux::View*> views;
00113   views.reserve(windows_.size());
00114   for (auto window: windows_)
00115     views.push_back(ViewForWindow(window));
00116   return views;
00117 }
00118 
00119 std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
00120 {
00121   std::vector<nux::Geometry> geometries;
00122 
00123   for (auto window : windows_)
00124   {
00125     geometries.push_back(window->GetAbsoluteGeometry());
00126   }
00127 
00128   return geometries;
00129 }
00130 
00131 void Controller::Impl::FirstMenuShow()
00132 {
00133   for (auto window: windows_)
00134   {
00135     if (ViewForWindow(window)->FirstMenuShow())
00136       break;
00137   }
00138 }
00139 
00140 void Controller::Impl::SetOpacity(float opacity)
00141 {
00142   opacity_ = opacity;
00143 
00144   for (auto window: windows_)
00145   {
00146     ViewForWindow(window)->SetOpacity(opacity_);
00147   }
00148 }
00149 
00150 void Controller::Impl::SetOpacityMaximizedToggle(bool enabled)
00151 {
00152   opacity_maximized_toggle_ = enabled;
00153 
00154   for (auto window: windows_)
00155   {
00156     ViewForWindow(window)->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
00157   }
00158 }
00159 
00160 void Controller::Impl::SetMenuShowTimings(int fadein, int fadeout, int discovery,
00161                                           int discovery_fadein, int discovery_fadeout)
00162 {
00163   menus_fadein_ = fadein;
00164   menus_fadeout_ = fadeout;
00165   menus_discovery_ = discovery;
00166   menus_discovery_fadein_ = discovery_fadein;
00167   menus_discovery_fadeout_ = discovery_fadeout;
00168 
00169   for (auto window: windows_)
00170   {
00171     ViewForWindow(window)->SetMenuShowTimings(fadein, fadeout, discovery,
00172                                               discovery_fadein, discovery_fadeout);
00173   }
00174 }
00175 
00176 void Controller::Impl::QueueRedraw()
00177 {
00178   for (auto window: windows_)
00179   {
00180     window->QueueDraw();
00181   }
00182 }
00183 
00184 PanelView* Controller::Impl::ViewForWindow(BaseWindowPtr const& window) const
00185 {
00186   nux::Layout* layout = window->GetLayout();
00187   auto it = layout->GetChildren().begin();
00188 
00189   return static_cast<PanelView*>(*it);
00190 }
00191 
00192 // We need to put a panel on every monitor, and try and re-use the panels we already have
00193 void Controller::Impl::OnScreenChanged(unsigned int primary_monitor,
00194                                        std::vector<nux::Geometry>& monitors,
00195                                        Introspectable *iobj)
00196 {
00197   std::vector<BaseWindowPtr>::iterator it;
00198   unsigned n_monitors = monitors.size();
00199   unsigned int i = 0;
00200 
00201   for (it = windows_.begin(); it != windows_.end(); ++it)
00202   {
00203     if (i < n_monitors)
00204     {
00205       PanelView* view;
00206 
00207       (*it)->EnableInputWindow(false);
00208       (*it)->InputWindowEnableStruts(false);
00209 
00210       nux::Geometry geo = monitors[i];
00211       geo.height = panel::Style::Instance().panel_height;
00212       (*it)->SetGeometry(geo);
00213       (*it)->SetMinMaxSize(geo.width, geo.height);
00214 
00215       view = ViewForWindow(*it);
00216       view->SetPrimary(i == primary_monitor);
00217       view->SetMonitor(i);
00218 
00219       (*it)->EnableInputWindow(true);
00220       (*it)->InputWindowEnableStruts(true);
00221 
00222       LOG_DEBUG(logger) << "Updated Panel for Monitor " << i;
00223 
00224       i++;
00225     }
00226     else
00227       break;
00228   }
00229 
00230   // Add new ones if needed
00231   if (i < n_monitors)
00232   {
00233     for (i = i; i < n_monitors; i++)
00234     {
00235       nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
00236 
00237       PanelView* view = new PanelView();
00238       view->SetMaximumHeight(panel::Style::Instance().panel_height);
00239       view->SetOpacity(opacity_);
00240       view->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
00241       view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_,
00242                                menus_discovery_fadein_, menus_discovery_fadeout_);
00243       view->SetPrimary(i == primary_monitor);
00244       view->SetMonitor(i);
00245 
00246       layout->AddView(view, 1);
00247       layout->SetContentDistribution(nux::eStackLeft);
00248       layout->SetVerticalExternalMargin(0);
00249       layout->SetHorizontalExternalMargin(0);
00250 
00251       BaseWindowPtr window(new nux::BaseWindow());
00252       nux::Geometry geo = monitors[i];
00253       geo.height = panel::Style::Instance().panel_height;
00254 
00255       window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window.GetPointer());
00256       window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
00257       window->ShowWindow(true);
00258       window->EnableInputWindow(true, panel::window_title, false, false);
00259       window->InputWindowEnableStruts(true);
00260       window->SetGeometry(geo);
00261       window->SetMinMaxSize(geo.width, geo.height);
00262       window->SetLayout(layout);
00263 
00264       windows_.push_back(window);
00265 
00266       // add to introspectable tree:
00267       iobj->AddChild(view);
00268 
00269       LOG_DEBUG(logger) << "Added Panel for Monitor " << i;
00270     }
00271   }
00272 
00273   if (windows_.size() > n_monitors)
00274   {
00275     LOG_DEBUG(logger) << "Removed extra Panels";
00276     windows_.erase(it, windows_.end());
00277   }
00278 }
00279 
00280 void Controller::Impl::WindowConfigureCallback(int window_width,
00281                                                int window_height,
00282                                                nux::Geometry& geo,
00283                                                void* user_data)
00284 {
00285   nux::BaseWindow* window = static_cast<nux::BaseWindow*>(user_data);
00286   geo = window->GetGeometry();
00287 }
00288 
00289 float Controller::Impl::opacity() const
00290 {
00291   return opacity_;
00292 }
00293 
00294 Controller::Controller()
00295   : pimpl(new Impl())
00296 {
00297   UScreen* screen = UScreen::GetDefault();
00298   screen->changed.connect(sigc::mem_fun(this, &Controller::OnScreenChanged));
00299   OnScreenChanged(screen->GetPrimaryMonitor(), screen->GetMonitors());
00300 }
00301 
00302 Controller::~Controller()
00303 {
00304   delete pimpl;
00305 }
00306 
00307 void Controller::FirstMenuShow()
00308 {
00309   pimpl->FirstMenuShow();
00310 }
00311 
00312 void Controller::SetOpacity(float opacity)
00313 {
00314   pimpl->SetOpacity(opacity);
00315 }
00316 
00317 void Controller::SetOpacityMaximizedToggle(bool enabled)
00318 {
00319   pimpl->SetOpacityMaximizedToggle(enabled);
00320 }
00321 
00322 void Controller::SetMenuShowTimings(int fadein, int fadeout, int discovery,
00323                                     int discovery_fadein, int discovery_fadeout)
00324 {
00325   pimpl->SetMenuShowTimings(fadein, fadeout, discovery, discovery_fadein, discovery_fadeout);
00326 }
00327 
00328 void Controller::QueueRedraw()
00329 {
00330   pimpl->QueueRedraw();
00331 }
00332 
00333 std::vector<Window> Controller::GetTrayXids() const
00334 {
00335   return pimpl->GetTrayXids();
00336 }
00337 
00338 std::vector<nux::View*> Controller::GetPanelViews() const
00339 {
00340   return pimpl->GetPanelViews();
00341 }
00342 
00343 std::vector<nux::Geometry> Controller::GetGeometries() const
00344 {
00345   return pimpl->GetGeometries();
00346 }
00347 
00348 float Controller::opacity() const
00349 {
00350   return pimpl->opacity();
00351 }
00352 
00353 std::string Controller::GetName() const
00354 {
00355   return "PanelController";
00356 }
00357 
00358 void Controller::AddProperties(GVariantBuilder* builder)
00359 {
00360   variant::BuilderWrapper(builder)
00361     .add("opacity", pimpl->opacity());
00362 }
00363 
00364 void Controller::OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors)
00365 {
00366   pimpl->OnScreenChanged(primary_monitor, monitors, this);
00367 }
00368 
00369 } // namespace panel
00370 } // namespace unity