1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3
* Copyright (C) 2011 Canonical Ltd
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 3 as
7
* published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
20
#include "PanelController.h"
23
#include <NuxCore/Logger.h>
24
#include <Nux/BaseWindow.h>
25
#include <UnityCore/Variant.h>
27
#include "unity-shared/UScreen.h"
28
#include "PanelView.h"
29
#include "unity-shared/PanelStyle.h"
35
DECLARE_LOGGER(logger, "unity.panel.controller");
37
const char* window_title = "unity-panel";
39
class Controller::Impl
47
std::vector<nux::View*> GetPanelViews() const;
48
std::vector<nux::Geometry> GetGeometries() const;
50
// NOTE: nux::Property maybe?
51
void SetLauncherWidth(int width);
52
void SetOpacity(float opacity);
53
void SetOpacityMaximizedToggle(bool enabled);
55
float opacity() const;
57
void SetMenuShowTimings(int fadein, int fadeout, int discovery,
58
int discovery_fadein, int discovery_fadeout);
60
void OnScreenChanged(unsigned int primary_monitor, std::vector<nux::Geometry>& monitors, Introspectable *iobj);
62
typedef nux::ObjectPtr<nux::BaseWindow> BaseWindowPtr;
64
unity::PanelView* ViewForWindow(BaseWindowPtr const& window) const;
66
static void WindowConfigureCallback(int window_width,
71
std::vector<BaseWindowPtr> windows_;
72
std::vector<Window> tray_xids_;
74
bool opacity_maximized_toggle_;
78
int menus_discovery_fadein_;
79
int menus_discovery_fadeout_;
80
indicator::DBusIndicators::Ptr dbus_indicators_;
84
Controller::Impl::Impl()
86
, opacity_maximized_toggle_(false)
90
, menus_discovery_fadein_(0)
91
, menus_discovery_fadeout_(0)
92
, dbus_indicators_(std::make_shared<indicator::DBusIndicators>())
95
std::vector<nux::View*> Controller::Impl::GetPanelViews() const
97
std::vector<nux::View*> views;
98
views.reserve(windows_.size());
99
for (auto const& window: windows_)
100
views.push_back(ViewForWindow(window));
104
std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
106
std::vector<nux::Geometry> geometries;
108
for (auto const& window : windows_)
110
geometries.push_back(window->GetAbsoluteGeometry());
116
void Controller::Impl::FirstMenuShow()
118
for (auto const& window: windows_)
120
if (ViewForWindow(window)->FirstMenuShow())
125
void Controller::Impl::SetOpacity(float opacity)
129
for (auto const& window: windows_)
131
ViewForWindow(window)->SetOpacity(opacity_);
135
void Controller::Impl::SetLauncherWidth(int width)
137
for (auto const& window: windows_)
139
ViewForWindow(window)->SetLauncherWidth(width);
143
void Controller::Impl::SetOpacityMaximizedToggle(bool enabled)
145
opacity_maximized_toggle_ = enabled;
147
for (auto const& window: windows_)
149
ViewForWindow(window)->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
153
void Controller::Impl::SetMenuShowTimings(int fadein, int fadeout, int discovery,
154
int discovery_fadein, int discovery_fadeout)
156
menus_fadein_ = fadein;
157
menus_fadeout_ = fadeout;
158
menus_discovery_ = discovery;
159
menus_discovery_fadein_ = discovery_fadein;
160
menus_discovery_fadeout_ = discovery_fadeout;
162
for (auto const& window: windows_)
164
ViewForWindow(window)->SetMenuShowTimings(fadein, fadeout, discovery,
165
discovery_fadein, discovery_fadeout);
169
void Controller::Impl::QueueRedraw()
171
for (auto const& window: windows_)
177
PanelView* Controller::Impl::ViewForWindow(BaseWindowPtr const& window) const
179
nux::Layout* layout = window->GetLayout();
180
auto it = layout->GetChildren().begin();
182
return static_cast<PanelView*>(*it);
185
// We need to put a panel on every monitor, and try and re-use the panels we already have
186
void Controller::Impl::OnScreenChanged(unsigned int primary_monitor,
187
std::vector<nux::Geometry>& monitors,
188
Introspectable *iobj)
190
std::vector<BaseWindowPtr>::iterator it;
191
unsigned n_monitors = monitors.size();
194
tray_xids_.resize(n_monitors);
196
for (it = windows_.begin(); it != windows_.end(); ++it)
202
(*it)->EnableInputWindow(false);
203
(*it)->InputWindowEnableStruts(false);
205
nux::Geometry geo = monitors[i];
206
geo.height = panel::Style::Instance().panel_height;
207
(*it)->SetGeometry(geo);
208
(*it)->SetMinMaxSize(geo.width, geo.height);
210
view = ViewForWindow(*it);
211
view->SetPrimary(i == primary_monitor);
213
tray_xids_[i] = view->GetTrayXid();
215
if (nux::GetWindowThread()->IsEmbeddedWindow())
217
(*it)->EnableInputWindow(true);
218
(*it)->InputWindowEnableStruts(true);
221
LOG_DEBUG(logger) << "Updated Panel for Monitor " << i;
229
// Add new ones if needed
232
for (i = i; i < n_monitors; i++)
234
nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
236
PanelView* view = new PanelView(dbus_indicators_);
237
view->SetMaximumHeight(panel::Style::Instance().panel_height);
238
view->SetOpacity(opacity_);
239
view->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
240
view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_,
241
menus_discovery_fadein_, menus_discovery_fadeout_);
242
view->SetPrimary(i == primary_monitor);
244
tray_xids_[i] = view->GetTrayXid();
246
layout->AddView(view, 1);
247
layout->SetContentDistribution(nux::MAJOR_POSITION_START);
248
layout->SetVerticalExternalMargin(0);
249
layout->SetHorizontalExternalMargin(0);
251
BaseWindowPtr window(new nux::BaseWindow());
252
nux::Geometry geo = monitors[i];
253
geo.height = panel::Style::Instance().panel_height;
255
window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window.GetPointer());
256
window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
257
window->ShowWindow(true);
259
if (nux::GetWindowThread()->IsEmbeddedWindow())
260
window->EnableInputWindow(true, panel::window_title, false, false);
262
window->SetGeometry(geo);
263
window->SetMinMaxSize(geo.width, geo.height);
264
window->SetLayout(layout);
265
window->InputWindowEnableStruts(true);
267
windows_.push_back(window);
269
// add to introspectable tree:
270
iobj->AddChild(view);
272
LOG_DEBUG(logger) << "Added Panel for Monitor " << i;
276
if (windows_.size() > n_monitors)
278
LOG_DEBUG(logger) << "Removed extra Panels";
279
windows_.erase(it, windows_.end());
283
void Controller::Impl::WindowConfigureCallback(int window_width,
288
nux::BaseWindow* window = static_cast<nux::BaseWindow*>(user_data);
289
geo = window->GetGeometry();
292
bool Controller::IsMouseInsideIndicator(nux::Point const& mouse_position) const
294
for (auto view : pimpl->GetPanelViews())
296
PanelView* panel_view = static_cast<PanelView*>(view);
298
if (panel_view->IsMouseInsideIndicator(mouse_position))
305
float Controller::Impl::opacity() const
310
Controller::Controller()
314
UScreen* screen = UScreen::GetDefault();
315
screen->changed.connect(sigc::mem_fun(this, &Controller::OnScreenChanged));
316
OnScreenChanged(screen->GetPrimaryMonitor(), screen->GetMonitors());
318
launcher_width.changed.connect([&] (int width)
320
pimpl->SetLauncherWidth(width);
324
Controller::~Controller()
329
void Controller::FirstMenuShow()
331
pimpl->FirstMenuShow();
334
void Controller::SetOpacity(float opacity)
336
pimpl->SetOpacity(opacity);
339
void Controller::SetOpacityMaximizedToggle(bool enabled)
341
pimpl->SetOpacityMaximizedToggle(enabled);
344
void Controller::SetMenuShowTimings(int fadein, int fadeout, int discovery,
345
int discovery_fadein, int discovery_fadeout)
347
pimpl->SetMenuShowTimings(fadein, fadeout, discovery, discovery_fadein, discovery_fadeout);
350
void Controller::QueueRedraw()
352
pimpl->QueueRedraw();
355
std::vector<Window> const& Controller::GetTrayXids() const
357
return pimpl->tray_xids_;
360
std::vector<nux::View*> Controller::GetPanelViews() const
362
return pimpl->GetPanelViews();
365
std::vector<nux::Geometry> Controller::GetGeometries() const
367
return pimpl->GetGeometries();
370
float Controller::opacity() const
372
return pimpl->opacity();
375
std::string Controller::GetName() const
377
return "PanelController";
380
void Controller::AddProperties(GVariantBuilder* builder)
382
variant::BuilderWrapper(builder)
383
.add("opacity", pimpl->opacity());
386
void Controller::OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors)
388
pimpl->OnScreenChanged(primary_monitor, monitors, this);