Back to index

unity  6.0.0
FilterMultiRangeButton.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2011 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser 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, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00012  * License for more details.
00013  *
00014  * You should have received a copy of both the GNU Lesser General Public
00015  * License version 3 along with this program.  If not, see
00016  * <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Gordon Allott <gord.allott@canonical.com>
00019  *
00020  */
00021 #include "config.h"
00022 
00023 #include <Nux/Nux.h>
00024 
00025 #include "unity-shared/DashStyle.h"
00026 #include "FilterMultiRangeButton.h"
00027 
00028 namespace unity
00029 {
00030 namespace dash
00031 {
00032 
00033 FilterMultiRangeButton::FilterMultiRangeButton(std::string const& label, NUX_FILE_LINE_DECL)
00034   : nux::ToggleButton(label, NUX_FILE_LINE_PARAM)
00035   , has_arrow_(MultiRangeArrow::NONE)
00036   , side_(MultiRangeSide::CENTER)
00037 {
00038   Init();
00039 }
00040 
00041 FilterMultiRangeButton::FilterMultiRangeButton(NUX_FILE_LINE_DECL)
00042   : nux::ToggleButton(NUX_FILE_LINE_PARAM)
00043   , has_arrow_(MultiRangeArrow::NONE)
00044   , side_(MultiRangeSide::CENTER)
00045 {
00046   Init();
00047 }
00048 
00049 FilterMultiRangeButton::~FilterMultiRangeButton()
00050 {
00051 }
00052 
00053 void FilterMultiRangeButton::Init()
00054 {
00055   InitTheme();
00056   SetAcceptKeyNavFocusOnMouseDown(false);
00057   SetAcceptKeyNavFocusOnMouseEnter(true);
00058 
00059   state_change.connect(sigc::mem_fun(this, &FilterMultiRangeButton::OnActivated));
00060   key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection) { QueueDraw(); });
00061   key_nav_focus_activate.connect([&](nux::Area* area) { Active() ? Deactivate() : Activate(); });
00062 }
00063 
00064 void FilterMultiRangeButton::OnActivated(nux::Area* area)
00065 {
00066   if (filter_)
00067     filter_->active = Active();
00068 }
00069 
00070 void FilterMultiRangeButton::OnActiveChanged(bool value)
00071 {
00072   NeedRedraw();
00073 }
00074 
00075 void FilterMultiRangeButton::SetFilter(FilterOption::Ptr const& filter)
00076 {
00077   filter_ = filter;
00078   SetActive(filter_->active);
00079 }
00080 
00081 FilterOption::Ptr FilterMultiRangeButton::GetFilter()
00082 {
00083   return filter_;
00084 }
00085 
00086 void FilterMultiRangeButton::SetVisualSide(MultiRangeSide side)
00087 {
00088   if (side_ == side)
00089     return;
00090   side_ = side;
00091 
00092   QueueDraw();
00093 }
00094 
00095 void FilterMultiRangeButton::SetHasArrow(MultiRangeArrow value)
00096 {
00097   if (has_arrow_ == value)
00098     return;
00099   has_arrow_ = value;
00100 
00101   QueueDraw();
00102 }
00103 
00104 long FilterMultiRangeButton::ComputeContentSize()
00105 {
00106   long ret = nux::ToggleButton::ComputeContentSize();
00107   nux::Geometry const& geo = GetGeometry();
00108   if (cached_geometry_ != geo)
00109   {
00110     cached_geometry_ = geo;
00111 
00112     std::vector<MultiRangeSide> sides = {MultiRangeSide::LEFT, MultiRangeSide::RIGHT, MultiRangeSide::CENTER};
00113     std::vector<MultiRangeArrow> arrows = {MultiRangeArrow::LEFT, MultiRangeArrow::RIGHT, MultiRangeArrow::BOTH, MultiRangeArrow::NONE};
00114 
00115     for (auto arrow : arrows)
00116     {
00117       for (auto side : sides)
00118       {
00119         prelight_[MapKey(arrow, side)]->Invalidate(geo);
00120         active_[MapKey(arrow, side)]->Invalidate(geo);
00121         normal_[MapKey(arrow, side)]->Invalidate(geo);
00122         focus_[MapKey(arrow, side)]->Invalidate(geo);
00123       }
00124     }
00125   }
00126 
00127   return ret;
00128 }
00129 
00130 void FilterMultiRangeButton::InitTheme()
00131 {
00132   if (!active_[MapKey(MultiRangeArrow::LEFT, MultiRangeSide::LEFT)])
00133   {
00134     nux::Geometry const& geo = GetGeometry();
00135 
00136     std::vector<MultiRangeSide> sides = {MultiRangeSide::LEFT, MultiRangeSide::RIGHT, MultiRangeSide::CENTER};
00137     std::vector<MultiRangeArrow> arrows = {MultiRangeArrow::LEFT, MultiRangeArrow::RIGHT, MultiRangeArrow::BOTH, MultiRangeArrow::NONE};
00138 
00139     for (auto arrow : arrows)
00140     {
00141       for (auto side : sides)
00142       {
00143         active_[MapKey(arrow, side)].reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &FilterMultiRangeButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRESSED, arrow, side)));
00144         normal_[MapKey(arrow, side)].reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &FilterMultiRangeButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL, arrow, side)));
00145         prelight_[MapKey(arrow, side)].reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &FilterMultiRangeButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRELIGHT, arrow, side)));
00146         focus_[MapKey(arrow, side)].reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &FilterMultiRangeButton::RedrawFocusOverlay), arrow, side)));
00147       }
00148     }
00149   }
00150 
00151   SetMinimumHeight(dash::Style::Instance().GetFilterButtonHeight() + 3);
00152 }
00153 
00154 void FilterMultiRangeButton::RedrawTheme(nux::Geometry const& geom,
00155                                          cairo_t* cr,
00156                                          nux::ButtonVisualState faked_state,
00157                                          MultiRangeArrow faked_arrow,
00158                                          MultiRangeSide faked_side)
00159 {
00160   std::string name("10");
00161 
00162   if (filter_)
00163   {
00164     name = filter_->name;
00165   }
00166 
00167   Arrow arrow;
00168   if (faked_arrow == MultiRangeArrow::NONE)
00169     arrow = Arrow::NONE;
00170   else if (faked_arrow == MultiRangeArrow::LEFT)
00171     arrow = Arrow::LEFT;
00172   else if (faked_arrow == MultiRangeArrow::BOTH)
00173     arrow = Arrow::BOTH;
00174   else
00175     arrow = Arrow::RIGHT;
00176 
00177   Segment segment;
00178   if (faked_side == MultiRangeSide::LEFT)
00179     segment = Segment::LEFT;
00180   else if (faked_side == MultiRangeSide::CENTER)
00181     segment = Segment::MIDDLE;
00182   else
00183     segment = Segment::RIGHT;
00184 
00185   Style::Instance().MultiRangeSegment(cr, faked_state, name, arrow, segment);
00186   NeedRedraw();
00187 }
00188 
00189 void FilterMultiRangeButton::RedrawFocusOverlay(nux::Geometry const& geom,
00190                                                 cairo_t* cr,
00191                                                 MultiRangeArrow faked_arrow,
00192                                                 MultiRangeSide faked_side)
00193 {
00194   Arrow arrow;
00195   if (faked_arrow == MultiRangeArrow::NONE)
00196     arrow = Arrow::NONE;
00197   else if (faked_arrow == MultiRangeArrow::LEFT)
00198     arrow = Arrow::LEFT;
00199   else if (faked_arrow == MultiRangeArrow::BOTH)
00200     arrow = Arrow::BOTH;
00201   else
00202     arrow = Arrow::RIGHT;
00203 
00204   Segment segment;
00205   if (faked_side == MultiRangeSide::LEFT)
00206     segment = Segment::LEFT;
00207   else if (faked_side == MultiRangeSide::CENTER)
00208     segment = Segment::MIDDLE;
00209   else
00210     segment = Segment::RIGHT;
00211 
00212   Style::Instance().MultiRangeFocusOverlay(cr, arrow, segment);
00213   QueueDraw();
00214 }
00215 
00216 void FilterMultiRangeButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
00217 {
00218   nux::Geometry const& geo = GetGeometry();
00219 
00220   gPainter.PaintBackground(GfxContext, geo);
00221   // set up our texture mode
00222   nux::TexCoordXForm texxform;
00223   texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00224   texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00225 
00226   // clear what is behind us
00227   unsigned int alpha = 0, src = 0, dest = 0;
00228   GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
00229   GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00230 
00231   nux::Color col = nux::color::Black;
00232   col.alpha = 0;
00233   GfxContext.QRP_Color(geo.x,
00234                        geo.y,
00235                        geo.width,
00236                        geo.height,
00237                        col);
00238 
00239   nux::BaseTexture* texture = normal_[MapKey(has_arrow_, side_)]->GetTexture();
00240   if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)
00241   {
00242     texture = prelight_[MapKey(has_arrow_, side_)]->GetTexture();
00243   }
00244 
00245   if (Active())
00246   {
00247     texture = active_[MapKey(has_arrow_, side_)]->GetTexture();
00248   }
00249 
00250   if (HasKeyFocus())
00251   {
00252     GfxContext.QRP_1Tex(geo.x,
00253                         geo.y,
00254                         geo.width,
00255                         geo.height,
00256                         focus_[MapKey(has_arrow_, side_)]->GetTexture()->GetDeviceTexture(),
00257                         texxform,
00258                         nux::color::White);
00259   }
00260 
00261   GfxContext.QRP_1Tex(geo.x,
00262                       geo.y,
00263                       geo.width,
00264                       geo.height,
00265                       texture->GetDeviceTexture(),
00266                       texxform,
00267                       nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
00268   GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
00269 }
00270 
00271 } // namespace dash
00272 } // namespace unity