Back to index

unity  6.0.0
SwitcherModel.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Jason Smith <jason.smith@canonical.com>
00017  */
00018 
00019 #include <math.h>
00020 
00021 #include "SwitcherModel.h"
00022 #include "unity-shared/WindowManager.h"
00023 
00024 #include <UnityCore/Variant.h>
00025 
00026 namespace unity
00027 {
00028 using launcher::AbstractLauncherIcon;
00029 
00030 namespace switcher
00031 {
00032 
00033 SwitcherModel::SwitcherModel(std::vector<AbstractLauncherIcon::Ptr> icons)
00034   : _inner(icons)
00035   , _index(0)
00036   , _last_index(0)
00037 {
00038   detail_selection = false;
00039   detail_selection_index = 0;
00040   only_detail_on_viewport = false;
00041 
00042   for (auto icon : _inner)
00043   {
00044     AddChild(icon.GetPointer());
00045   }
00046 }
00047 
00048 SwitcherModel::~SwitcherModel()
00049 {
00050   for (auto icon : _inner)
00051   {
00052     RemoveChild(icon.GetPointer());
00053   }
00054 }
00055 
00056 std::string SwitcherModel::GetName() const
00057 {
00058   return "SwitcherModel";
00059 }
00060 
00061 void SwitcherModel::AddProperties(GVariantBuilder* builder)
00062 {
00063   unity::variant::BuilderWrapper(builder)
00064   .add("detail-selection", detail_selection)
00065   .add("detail-selection-index", (int)detail_selection_index)
00066   .add("detail-current-count", DetailXids().size())
00067   .add("only-detail-on-viewport", only_detail_on_viewport)
00068   .add("selection-index", SelectionIndex())
00069   .add("last-selection-index", LastSelectionIndex());
00070 }
00071 
00072 SwitcherModel::iterator
00073 SwitcherModel::begin()
00074 {
00075   return _inner.begin();
00076 }
00077 
00078 SwitcherModel::iterator
00079 SwitcherModel::end()
00080 {
00081   return _inner.end();
00082 }
00083 
00084 SwitcherModel::reverse_iterator
00085 SwitcherModel::rbegin()
00086 {
00087   return _inner.rbegin();
00088 }
00089 
00090 SwitcherModel::reverse_iterator
00091 SwitcherModel::rend()
00092 {
00093   return _inner.rend();
00094 }
00095 
00096 AbstractLauncherIcon::Ptr
00097 SwitcherModel::at(unsigned int index)
00098 {
00099   if ((int) index >= Size ())
00100     return AbstractLauncherIcon::Ptr();
00101   return _inner[index];
00102 }
00103 
00104 int
00105 SwitcherModel::Size()
00106 {
00107   return _inner.size();
00108 }
00109 
00110 AbstractLauncherIcon::Ptr
00111 SwitcherModel::Selection()
00112 {
00113   return _inner.at(_index);
00114 }
00115 
00116 int
00117 SwitcherModel::SelectionIndex()
00118 {
00119   return _index;
00120 }
00121 
00122 AbstractLauncherIcon::Ptr
00123 SwitcherModel::LastSelection()
00124 {
00125   return _inner.at(_last_index);
00126 }
00127 
00128 int
00129 SwitcherModel::LastSelectionIndex()
00130 {
00131   return _last_index;
00132 }
00133 
00134 bool
00135 SwitcherModel::CompareWindowsByActive (guint32 first, guint32 second)
00136 {
00137   return WindowManager::Default ()->GetWindowActiveNumber (first) > WindowManager::Default ()->GetWindowActiveNumber (second);
00138 }
00139 
00140 bool
00141 WindowOnOtherViewport(Window xid)
00142 {
00143   return !WindowManager::Default()->IsWindowOnCurrentDesktop(xid);
00144 }
00145 
00146 std::vector<Window>
00147 SwitcherModel::DetailXids()
00148 {
00149   std::vector<Window> results;
00150   results = Selection()->Windows();
00151 
00152   if (only_detail_on_viewport)
00153   {
00154     results.erase(std::remove_if(results.begin(), results.end(), WindowOnOtherViewport), results.end());
00155   }
00156 
00157   std::sort (results.begin (), results.end (), &CompareWindowsByActive);
00158 
00159   // swap so we focus the last focused window first
00160   if (Selection()->GetQuirk (AbstractLauncherIcon::QUIRK_ACTIVE) && results.size () > 1)
00161     std::swap (results[0], results[1]);
00162 
00163   return results;
00164 }
00165 
00166 Window
00167 SwitcherModel::DetailSelectionWindow ()
00168 {
00169   if (!detail_selection || DetailXids ().empty())
00170     return 0;
00171 
00172   if (detail_selection_index > DetailXids().size() - 1)
00173     return 0;
00174 
00175   return DetailXids()[detail_selection_index];
00176 }
00177 
00178 void
00179 SwitcherModel::Next()
00180 {
00181   _last_index = _index;
00182 
00183   _index++;
00184   if (_index >= _inner.size())
00185     _index = 0;
00186 
00187   detail_selection = false;
00188   detail_selection_index = 0;
00189   selection_changed.emit(Selection());
00190 }
00191 
00192 void
00193 SwitcherModel::Prev()
00194 {
00195   _last_index = _index;
00196 
00197   if (_index > 0)
00198     _index--;
00199   else
00200     _index = _inner.size() - 1;
00201 
00202   detail_selection = false;
00203   detail_selection_index = 0;
00204   selection_changed.emit(Selection());
00205 }
00206 
00207 void
00208 SwitcherModel::NextDetail ()
00209 {
00210   if (!detail_selection())
00211     return;
00212 
00213   if (detail_selection_index < DetailXids().size() - 1)
00214     detail_selection_index = detail_selection_index + 1;
00215   else
00216     detail_selection_index = 0;
00217 }
00218 
00219 void SwitcherModel::PrevDetail ()
00220 {
00221   if (!detail_selection())
00222     return;
00223 
00224   if (detail_selection_index >= (unsigned int) 1)
00225     detail_selection_index = detail_selection_index - 1;
00226   else
00227     detail_selection_index = DetailXids().size() - 1;
00228 }
00229 
00230 void
00231 SwitcherModel::Select(AbstractLauncherIcon::Ptr selection)
00232 {
00233   int i = 0;
00234   for (iterator it = begin(), e = end(); it != e; ++it)
00235   {
00236     if (*it == selection)
00237     {
00238       if ((int) _index != i)
00239       {
00240         _last_index = _index;
00241         _index = i;
00242 
00243         detail_selection = false;
00244         detail_selection_index = 0;
00245         selection_changed.emit(Selection());
00246       }
00247       break;
00248     }
00249     ++i;
00250   }
00251 }
00252 
00253 void
00254 SwitcherModel::Select(unsigned int index)
00255 {
00256   unsigned int target = CLAMP(index, 0, _inner.size() - 1);
00257 
00258   if (target != _index)
00259   {
00260     _last_index = _index;
00261     _index = target;
00262 
00263     detail_selection = false;
00264     detail_selection_index = 0;
00265     selection_changed.emit(Selection());
00266   }
00267 }
00268 
00269 }
00270 }