Back to index

unity  6.0.0
FilterExpanderLabel.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright 2011 Canonical Ltd.
00004  *
00005  * This program is free software: you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser 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, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License version 3 along with this program.  If not, see
00017  * <http://www.gnu.org/licenses/>
00018  *
00019  * Authored by: Gordon Allott <gord.allott@canonical.com>
00020  *
00021  */
00022 
00023 #include "unity-shared/DashStyle.h"
00024 #include "FilterExpanderLabel.h"
00025 #include "unity-shared/LineSeparator.h"
00026 
00027 namespace
00028 {
00029 
00030 const float EXPAND_DEFAULT_ICON_OPACITY = 1.0f;
00031 
00032 // expander_layout_
00033 const int EXPANDER_LAYOUT_SPACE_BETWEEN_CHILDREN = 8;
00034 
00035 // font
00036 const char* const FONT_EXPANDER_LABEL = "Ubuntu Bold 13"; // 17px = 13
00037 
00038 class ExpanderView : public nux::View
00039 {
00040 public:
00041   ExpanderView(NUX_FILE_LINE_DECL)
00042    : nux::View(NUX_FILE_LINE_PARAM)
00043   {
00044     SetAcceptKeyNavFocusOnMouseDown(false);
00045     SetAcceptKeyNavFocusOnMouseEnter(true);
00046   }
00047 
00048 protected:
00049   void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
00050   {};
00051 
00052   void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
00053   {
00054     if (GetLayout())
00055       GetLayout()->ProcessDraw(graphics_engine, force_draw);
00056   }
00057 
00058   bool AcceptKeyNavFocus()
00059   {
00060     return true;
00061   }
00062 
00063   nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
00064   {
00065     bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
00066 
00067     if (mouse_inside == false)
00068       return nullptr;
00069 
00070     return this;
00071   }
00072 };
00073 
00074 }
00075 
00076 namespace unity
00077 {
00078 namespace dash
00079 {
00080 
00081 NUX_IMPLEMENT_OBJECT_TYPE(FilterExpanderLabel);
00082 
00083 FilterExpanderLabel::FilterExpanderLabel(std::string const& label, NUX_FILE_LINE_DECL)
00084   : nux::View(NUX_FILE_LINE_PARAM)
00085   , expanded(true)
00086   , draw_separator(false)
00087   , layout_(nullptr)
00088   , top_bar_layout_(nullptr)
00089   , expander_view_(nullptr)
00090   , expander_layout_(nullptr)
00091   , right_hand_contents_(nullptr)
00092   , cairo_label_(nullptr)
00093   , raw_label_(label)
00094   , label_("label")
00095   , separator_(nullptr)
00096 {
00097   expanded.changed.connect(sigc::mem_fun(this, &FilterExpanderLabel::DoExpandChange));
00098   BuildLayout();
00099   SetAcceptKeyNavFocusOnMouseDown(false);
00100 
00101   separator_ = new HSeparator;
00102   separator_->SinkReference();
00103 
00104   dash::Style& style = dash::Style::Instance();
00105   int space_height = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding();
00106 
00107   space_ = new nux::SpaceLayout(space_height, space_height, space_height, space_height);
00108   space_->SinkReference();
00109 
00110   draw_separator.changed.connect([&](bool value)
00111   {
00112     if (value and !separator_->IsChildOf(layout_))
00113     {
00114       layout_->AddLayout(space_, 0);
00115       layout_->AddView(separator_, 0);
00116     }
00117     else if (!value and separator_->IsChildOf(layout_))
00118     {
00119       layout_->RemoveChildObject(space_);
00120       layout_->RemoveChildObject(separator_);
00121     }
00122     QueueDraw();
00123   });
00124 }
00125 
00126 FilterExpanderLabel::~FilterExpanderLabel()
00127 {
00128   if (space_)
00129     space_->UnReference();
00130 
00131   if (separator_)
00132     separator_->UnReference();
00133 }
00134 
00135 void FilterExpanderLabel::SetLabel(std::string const& label)
00136 {
00137   raw_label_ = label;
00138 
00139   cairo_label_->SetText(label.c_str());
00140 }
00141 
00142 void FilterExpanderLabel::SetRightHandView(nux::View* view)
00143 {
00144   dash::Style& style = dash::Style::Instance();
00145 
00146   right_hand_contents_ = view;
00147   right_hand_contents_->SetMinimumHeight(style.GetAllButtonHeight());
00148   right_hand_contents_->SetMaximumHeight(style.GetAllButtonHeight());
00149   top_bar_layout_->AddView(right_hand_contents_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
00150 }
00151 
00152 void FilterExpanderLabel::SetContents(nux::Layout* contents)
00153 {
00154   // Since the contents is initially unowned, we don't want to Adopt it, just assign.
00155   contents_ = contents;
00156 
00157   layout_->AddLayout(contents_.GetPointer(), 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL);
00158 
00159   QueueDraw();
00160 }
00161 
00162 void FilterExpanderLabel::BuildLayout()
00163 {
00164   dash::Style& style = dash::Style::Instance();
00165 
00166   layout_ = new nux::VLayout(NUX_TRACKER_LOCATION);
00167   layout_->SetLeftAndRightPadding(style.GetFilterBarLeftPadding(), style.GetFilterBarRightPadding());
00168 
00169   top_bar_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
00170   top_bar_layout_->SetTopAndBottomPadding(style.GetFilterHighlightPadding());
00171 
00172   expander_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
00173   expander_layout_->SetSpaceBetweenChildren(EXPANDER_LAYOUT_SPACE_BETWEEN_CHILDREN);
00174 
00175   expander_view_ = new ExpanderView(NUX_TRACKER_LOCATION);
00176   expander_view_->SetLayout(expander_layout_);
00177   top_bar_layout_->AddView(expander_view_, 0);
00178 
00179   cairo_label_ = new nux::StaticCairoText(label_.c_str(), NUX_TRACKER_LOCATION);
00180   cairo_label_->SetFont(FONT_EXPANDER_LABEL);
00181   cairo_label_->SetTextColor(nux::color::White);
00182   cairo_label_->SetAcceptKeyboardEvent(false);
00183 
00184   nux::BaseTexture* arrow;
00185   arrow = dash::Style::Instance().GetGroupUnexpandIcon();
00186   expand_icon_ = new IconTexture(arrow,
00187                                  arrow->GetWidth(),
00188                                  arrow->GetHeight());
00189   expand_icon_->SetOpacity(EXPAND_DEFAULT_ICON_OPACITY);
00190   expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight());
00191   expand_icon_->SetVisible(true);
00192   arrow_layout_  = new nux::VLayout();
00193   arrow_top_space_ = new nux::SpaceLayout(2, 2, 11, 11);
00194   arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 9, 9);
00195   arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER);
00196   arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER);
00197   arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER);
00198 
00199   expander_layout_->AddView(cairo_label_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
00200   expander_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER);
00201   top_bar_layout_->AddSpace(1, 1);
00202 
00203   layout_->AddLayout(top_bar_layout_, 0, nux::MINOR_POSITION_LEFT);
00204   layout_->SetVerticalInternalMargin(0);
00205 
00206   SetLayout(layout_);
00207 
00208   // Lambda functions
00209   auto mouse_expand = [&](int x, int y, unsigned long b, unsigned long k)
00210   {
00211     expanded = !expanded;
00212   };
00213 
00214   auto key_redraw = [&](nux::Area*, bool, nux::KeyNavDirection)
00215   {
00216     QueueDraw();
00217   };
00218 
00219   auto key_expand = [&](nux::Area*)
00220   {
00221     expanded = !expanded;
00222   };
00223 
00224   // Signals
00225   expander_view_->mouse_click.connect(mouse_expand);
00226   expander_view_->key_nav_focus_change.connect(key_redraw);
00227   expander_view_->key_nav_focus_activate.connect(key_expand);
00228   cairo_label_->mouse_click.connect(mouse_expand);
00229   expand_icon_->mouse_click.connect(mouse_expand);
00230   key_nav_focus_change.connect([&](nux::Area* area, bool has_focus, nux::KeyNavDirection direction)
00231   {
00232     if(has_focus)
00233       nux::GetWindowCompositor().SetKeyFocusArea(expander_view_);
00234   });
00235 
00236   QueueRelayout();
00237   NeedRedraw();
00238 }
00239 
00240 void FilterExpanderLabel::DoExpandChange(bool change)
00241 {
00242   dash::Style& style = dash::Style::Instance();
00243   if (expanded)
00244     expand_icon_->SetTexture(style.GetGroupUnexpandIcon());
00245   else
00246     expand_icon_->SetTexture(style.GetGroupExpandIcon());
00247 
00248   if (change and contents_ and !contents_->IsChildOf(layout_))
00249   {
00250     layout_->AddLayout(contents_.GetPointer(), 1, nux::MINOR_POSITION_LEFT, nux::MINOR_SIZE_FULL, 100.0f, nux::LayoutPosition(1));
00251   }
00252   else if (!change and contents_ and contents_->IsChildOf(layout_))
00253   {
00254     layout_->RemoveChildObject(contents_.GetPointer());
00255   }
00256 
00257   layout_->ComputeContentSize();
00258   QueueDraw();
00259 }
00260 
00261 bool FilterExpanderLabel::ShouldBeHighlighted()
00262 {
00263   return ((expander_view_ && expander_view_->HasKeyFocus()));
00264 }
00265 
00266 void FilterExpanderLabel::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
00267 {
00268   nux::Geometry const& base = GetGeometry();
00269 
00270   GfxContext.PushClippingRectangle(base);
00271   nux::GetPainter().PaintBackground(GfxContext, base);
00272 
00273   if (ShouldBeHighlighted())
00274   {
00275     nux::Geometry geo(top_bar_layout_->GetGeometry());
00276     geo.x = base.x;
00277     geo.width = base.width;
00278 
00279     if (!highlight_layer_)
00280       highlight_layer_.reset(dash::Style::Instance().FocusOverlay(geo.width, geo.height));
00281 
00282     highlight_layer_->SetGeometry(geo);
00283     highlight_layer_->Renderlayer(GfxContext);
00284   }
00285 
00286   GfxContext.PopClippingRectangle();
00287 }
00288 
00289 void FilterExpanderLabel::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
00290 {
00291   GfxContext.PushClippingRectangle(GetGeometry());
00292 
00293   if (ShouldBeHighlighted() && highlight_layer_ && !IsFullRedraw())
00294   {
00295     nux::GetPainter().PushLayer(GfxContext, highlight_layer_->GetGeometry(), highlight_layer_.get());
00296   }
00297 
00298   GetLayout()->ProcessDraw(GfxContext, force_draw);
00299   GfxContext.PopClippingRectangle();
00300 }
00301 
00302 //
00303 // Key navigation
00304 //
00305 bool FilterExpanderLabel::AcceptKeyNavFocus()
00306 {
00307   return true;
00308 }
00309 
00310 //
00311 // Introspection
00312 //
00313 std::string FilterExpanderLabel::GetName() const
00314 {
00315   return "FilterExpanderLabel";
00316 }
00317 
00318 void FilterExpanderLabel::AddProperties(GVariantBuilder* builder)
00319 {
00320   unity::variant::BuilderWrapper wrapper(builder);
00321 
00322   wrapper.add("expander-has-focus", expander_view_->HasKeyFocus());
00323 }
00324 
00325 } // namespace dash
00326 } // namespace unity