Back to index

unity  6.0.0
HudButton.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 <pango/pango.h>
00024 #include <pango/pangocairo.h>
00025 #include <gdk/gdk.h>
00026 #include <gtk/gtk.h>
00027 
00028 #include <Nux/Nux.h>
00029 #include <Nux/HLayout.h>
00030 #include <NuxCore/Logger.h>
00031 #include <NuxGraphics/CairoGraphics.h>
00032 #include <NuxGraphics/NuxGraphics.h>
00033 #include <UnityCore/GLibWrapper.h>
00034 #include <UnityCore/Variant.h>
00035 
00036 #include "unity-shared/DashStyle.h"
00037 #include "unity-shared/StaticCairoText.h"
00038 
00039 #include "HudButton.h"
00040 #include "HudPrivate.h"
00041 
00042 namespace
00043 {
00044 nux::logging::Logger logger("unity.hud.HudButton");
00045 
00046 const int hlayout_left_padding = 46;
00047 const char* const button_font = "Ubuntu 13"; // 17px = 13
00048 }
00049 
00050 namespace unity
00051 {
00052 namespace hud
00053 {
00054 
00055 NUX_IMPLEMENT_OBJECT_TYPE(HudButton);
00056 
00057 HudButton::HudButton(NUX_FILE_LINE_DECL)
00058   : nux::Button(NUX_FILE_LINE_PARAM)
00059   , is_rounded(false)
00060   , is_focused_(false)
00061   , skip_draw_(true)
00062 {
00063   hlayout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
00064   hlayout_->SetLeftAndRightPadding(hlayout_left_padding, -1);
00065   SetLayout(hlayout_);
00066 
00067   InitTheme();
00068 
00069   key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection)
00070   {
00071     QueueDraw();
00072   });
00073 
00074   fake_focused.changed.connect([&](bool)
00075   {
00076     QueueDraw();
00077   });
00078 }
00079 
00080 void HudButton::InitTheme()
00081 {
00082   is_rounded.changed.connect([&](bool)
00083   {
00084     nux::Geometry const& geo = GetGeometry();
00085     prelight_->Invalidate(geo);
00086     active_->Invalidate(geo);
00087     normal_->Invalidate(geo);
00088   });
00089 
00090   SetMinimumHeight(42);
00091 
00092   if (!active_)
00093   {
00094     nux::Geometry const& geo = GetGeometry();
00095 
00096     prelight_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)));
00097     active_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_PRESSED)));
00098     normal_.reset(new nux::CairoWrapper(geo, sigc::bind(sigc::mem_fun(this, &HudButton::RedrawTheme), nux::ButtonVisualState::VISUAL_STATE_NORMAL)));
00099   }
00100 }
00101 
00102 void HudButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state)
00103 {
00104   dash::Style::Instance().SquareButton(cr, faked_state, "",
00105                                        is_rounded, 17,
00106                                        dash::Alignment::LEFT, true);
00107 }
00108 
00109 bool HudButton::AcceptKeyNavFocus()
00110 {
00111   // The button will not receive the keyboard focus. The keyboard focus is always to remain with the
00112   // text entry in the hud.
00113   return false;
00114 }
00115 
00116 
00117 long HudButton::ComputeContentSize()
00118 {
00119   long ret = nux::Button::ComputeContentSize();
00120   nux::Geometry const& geo = GetGeometry();
00121 
00122   if (cached_geometry_ != geo)
00123   {
00124     prelight_->Invalidate(geo);
00125     active_->Invalidate(geo);
00126     normal_->Invalidate(geo);
00127 
00128     cached_geometry_ = geo;
00129   }
00130 
00131   return ret;
00132 }
00133 
00134 void HudButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
00135 {
00136   if (skip_draw_)
00137     return;
00138 
00139   nux::Geometry const& geo = GetGeometry();
00140   GfxContext.PushClippingRectangle(geo);
00141   gPainter.PaintBackground(GfxContext, geo);
00142 
00143   // set up our texture mode
00144   nux::TexCoordXForm texxform;
00145   texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
00146   texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00147 
00148   // clear what is behind us
00149   unsigned int alpha = 0, src = 0, dest = 0;
00150   GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
00151   GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00152   GfxContext.GetRenderStates().SetBlend(true);
00153 
00154   nux::Color col(nux::color::Black);
00155   col.alpha = 0;
00156   GfxContext.QRP_Color(geo.x,
00157                        geo.y,
00158                        geo.width,
00159                        geo.height,
00160                        col);
00161 
00162   nux::BaseTexture* texture = normal_->GetTexture();
00163 
00164   if (HasKeyFocus() || fake_focused())
00165     texture = active_->GetTexture();
00166   else if (HasKeyFocus())
00167     texture = prelight_->GetTexture();
00168   else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
00169     texture = active_->GetTexture();
00170 
00171   GfxContext.QRP_1Tex(geo.x,
00172                       geo.y,
00173                       texture->GetWidth(),
00174                       texture->GetHeight(),
00175                       texture->GetDeviceTexture(),
00176                       texxform,
00177                       nux::color::White);
00178 
00179   GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
00180 
00181   GfxContext.PopClippingRectangle();
00182 }
00183 
00184 void HudButton::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
00185 {
00186   if (skip_draw_)
00187     return;
00188 
00189   if (IsFullRedraw())
00190   {
00191     GfxContext.PushClippingRectangle(GetGeometry());
00192     hlayout_->ProcessDraw(GfxContext, force_draw);
00193     GfxContext.PopClippingRectangle();
00194   }
00195 }
00196 
00197 void HudButton::SetQuery(Query::Ptr query)
00198 {
00199   query_ = query;
00200   label = query->formatted_text;
00201 
00202   auto items(impl::RefactorText(label));
00203 
00204   hlayout_->Clear();
00205   for (auto item : items)
00206   {
00207     nux::StaticCairoText* text = new nux::StaticCairoText(item.first);
00208     text->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, item.second ? 1.0f : 0.5f));
00209     text->SetFont(button_font);
00210     hlayout_->AddView(text, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
00211   }
00212 }
00213 
00214 Query::Ptr HudButton::GetQuery()
00215 {
00216   return query_;
00217 }
00218 
00219 void HudButton::SetSkipDraw(bool skip_draw)
00220 {
00221   skip_draw_ = skip_draw;
00222 }
00223 
00224 
00225 // Introspectable
00226 std::string HudButton::GetName() const
00227 {
00228   return "HudButton";
00229 }
00230 
00231 void HudButton::AddProperties(GVariantBuilder* builder)
00232 {
00233   variant::BuilderWrapper(builder)
00234     .add("label", label())
00235     .add("focused", fake_focused());
00236 }
00237 
00238 } // namespace hud
00239 } // namespace unity