Back to index

unity  6.0.0
PanelTitlebarGrabAreaView.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2010-2012 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  *              Sam Spilsbury <sam.spilsbury@canonical.com>
00019  *              Didier Roche <didier.roche@canonical.com>
00020  *              Marco Trevisan (TreviƱo) <mail@3v1n0.net>
00021  */
00022 
00023 #include <Nux/Nux.h>
00024 
00025 #include "PanelTitlebarGrabAreaView.h"
00026 
00027 #include <UnityCore/Variant.h>
00028 #include <X11/cursorfont.h>
00029 
00030 namespace unity
00031 {
00032 namespace
00033 {
00034 
00035 const int MOUSE_DOWN_TIMEOUT = 150;
00036 const int MOUSE_MOVEMENT_TOLERANCE = 4;
00037 
00038 }
00039 
00040 PanelTitlebarGrabArea::PanelTitlebarGrabArea()
00041   : InputArea(NUX_TRACKER_LOCATION)
00042   , grab_cursor_(None)
00043   , grab_started_(false)
00044   , mouse_down_button_(0)
00045 {
00046   EnableDoubleClick(true);
00047 
00048   mouse_down.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseDown));
00049   mouse_up.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseUp));
00050   mouse_drag.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnGrabMove));
00051 
00052   mouse_double_click.connect([&] (int x, int y, unsigned long button_flags, unsigned long)
00053   {
00054     if (nux::GetEventButton(button_flags) == 1)
00055       restore_request.emit(x, y);
00056   });
00057 }
00058 
00059 PanelTitlebarGrabArea::~PanelTitlebarGrabArea()
00060 {
00061   if (grab_cursor_)
00062     XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), grab_cursor_);
00063 }
00064 
00065 void PanelTitlebarGrabArea::SetGrabbed(bool enabled)
00066 {
00067   auto display = nux::GetGraphicsDisplay()->GetX11Display();
00068   auto panel_window = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
00069 
00070   if (!panel_window || !display)
00071     return;
00072 
00073   if (enabled && !grab_cursor_)
00074   {
00075     grab_cursor_ = XCreateFontCursor(display, XC_fleur);
00076     XDefineCursor(display, panel_window->GetInputWindowId(), grab_cursor_);
00077   }
00078   else if (!enabled && grab_cursor_)
00079   {
00080     XUndefineCursor(display, panel_window->GetInputWindowId());
00081     XFreeCursor(display, grab_cursor_);
00082     grab_cursor_ = None;
00083   }
00084 }
00085 
00086 bool PanelTitlebarGrabArea::IsGrabbed()
00087 {
00088   return (grab_cursor_ != None);
00089 }
00090 
00091 void PanelTitlebarGrabArea::OnMouseDown(int x, int y, unsigned long button_flags, unsigned long)
00092 {
00093   mouse_down_button_ = nux::GetEventButton(button_flags);
00094 
00095   if (mouse_down_button_ == 2)
00096   {
00097     lower_request.emit(x, y);
00098   }
00099   else if (mouse_down_button_ == 1)
00100   {
00101     mouse_down_point_.x = x;
00102     mouse_down_point_.y = y;
00103 
00104     mouse_down_timer_.reset(new glib::Timeout(MOUSE_DOWN_TIMEOUT));
00105     mouse_down_timer_->Run([&] () {
00106       if (!grab_started_)
00107       {
00108         nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
00109         nux::Geometry const& geo = GetAbsoluteGeometry();
00110         grab_started.emit(mouse.x - geo.x, mouse.y - geo.y);
00111         grab_started_ = true;
00112       }
00113 
00114       mouse_down_timer_.reset();
00115       return false;
00116     });
00117   }
00118 }
00119 
00120 void PanelTitlebarGrabArea::OnMouseUp(int x, int y, unsigned long button_flags, unsigned long)
00121 {
00122   int button = nux::GetEventButton(button_flags);
00123 
00124   if (button == 1)
00125   {
00126     if (mouse_down_timer_)
00127     {
00128       mouse_down_timer_.reset();
00129       activate_request.emit(x, y);
00130     }
00131 
00132     if (grab_started_)
00133     {
00134       grab_end.emit(x, y);
00135       grab_started_ = false;
00136     }
00137   }
00138 
00139   mouse_down_button_ = 0;
00140   mouse_down_point_.x = 0;
00141   mouse_down_point_.y = 0;
00142 }
00143 
00144 void PanelTitlebarGrabArea::OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long)
00145 {
00146   if (mouse_down_button_ != 1)
00147     return;
00148 
00149   if (mouse_down_timer_)
00150   {
00151     if (abs(mouse_down_point_.x - x) <= MOUSE_MOVEMENT_TOLERANCE &&
00152         abs(mouse_down_point_.y - y) <= MOUSE_MOVEMENT_TOLERANCE)
00153     {
00154       return;
00155     }
00156 
00157     mouse_down_timer_.reset();
00158   }
00159 
00160   if (!grab_started_)
00161   {
00162     grab_started.emit(x, y);
00163     grab_started_ = true;
00164   }
00165   else
00166   {
00167     grab_move.emit(x, y);
00168   }
00169 }
00170 
00171 std::string
00172 PanelTitlebarGrabArea::GetName() const
00173 {
00174   return "GrabArea";
00175 }
00176 
00177 void
00178 PanelTitlebarGrabArea::AddProperties(GVariantBuilder* builder)
00179 {
00180   unity::variant::BuilderWrapper(builder)
00181   .add(GetAbsoluteGeometry())
00182   .add("grabbed", IsGrabbed());
00183 }
00184 
00185 }