Back to index

unity  6.0.0
SearchBar.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2010-2011 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 detais.
00013  *
00014  * You shoud 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  */
00019 
00020 #include "config.h"
00021 
00022 #include <Nux/Nux.h>
00023 #include <Nux/HLayout.h>
00024 #include <Nux/VLayout.h>
00025 #include <NuxCore/Logger.h>
00026 
00027 #include <UnityCore/Variant.h>
00028 
00029 #include <glib/gi18n-lib.h>
00030 
00031 #include "SearchBar.h"
00032 #include "CairoTexture.h"
00033 #include "unity-shared/DashStyle.h"
00034 
00035 namespace
00036 {
00037 const float kExpandDefaultIconOpacity = 1.0f;
00038 const int LIVE_SEARCH_TIMEOUT = 40;
00039 const int SPINNER_TIMEOUT = 100;
00040 
00041 const int SPACE_BETWEEN_SPINNER_AND_TEXT = 5;
00042 const int SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT = 10;
00043 const int LEFT_INTERNAL_PADDING = 6;
00044 const int SEARCH_ENTRY_RIGHT_BORDER = 10;
00045 
00046 const int HIGHLIGHT_HEIGHT = 24;
00047 
00048 // Fonts
00049 const std::string HINT_LABEL_FONT_SIZE = "20px";
00050 const std::string HINT_LABEL_FONT_STYLE = "Italic";
00051 const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE;
00052 
00053 const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu";
00054 const int PANGO_ENTRY_FONT_SIZE = 22;
00055 
00056 const std::string SHOW_FILTERS_LABEL_FONT_SIZE = "13";
00057 const std::string SHOW_FILTERS_LABEL_FONT_STYLE = "Bold";
00058 const std::string SHOW_FILTERS_LABEL_DEFAULT_FONT = "Ubuntu " + SHOW_FILTERS_LABEL_FONT_STYLE + " " + SHOW_FILTERS_LABEL_FONT_SIZE;
00059 
00060 }
00061 
00062 namespace
00063 {
00064 
00065 nux::logging::Logger logger("unity");
00066 
00067 class ExpanderView : public nux::View
00068 {
00069 public:
00070   ExpanderView(NUX_FILE_LINE_DECL)
00071    : nux::View(NUX_FILE_LINE_PARAM)
00072   {
00073     SetAcceptKeyNavFocusOnMouseDown(false);
00074     SetAcceptKeyNavFocusOnMouseEnter(true);
00075   }
00076 
00077 protected:
00078   void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
00079   {}
00080 
00081   void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
00082   {
00083     if (GetLayout())
00084       GetLayout()->ProcessDraw(graphics_engine, force_draw);
00085   }
00086 
00087   bool AcceptKeyNavFocus()
00088   {
00089     return true;
00090   }
00091 
00092   nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
00093   {
00094     bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
00095 
00096     if (mouse_inside == false)
00097       return nullptr;
00098 
00099     return this;
00100   }
00101 };
00102 
00103 }
00104 
00105 namespace unity
00106 {
00107 
00108 NUX_IMPLEMENT_OBJECT_TYPE(SearchBar);
00109 
00110 SearchBar::SearchBar(NUX_FILE_LINE_DECL)
00111   : View(NUX_FILE_LINE_PARAM)
00112   , search_hint("")
00113   , showing_filters(false)
00114   , can_refine_search(false)
00115   , show_filter_hint_(true)
00116   , expander_view_(nullptr)
00117   , show_filters_(nullptr)
00118   , last_width_(-1)
00119   , last_height_(-1)
00120 {
00121   Init();
00122 }
00123 
00124 SearchBar::SearchBar(bool show_filter_hint_, NUX_FILE_LINE_DECL)
00125   : View(NUX_FILE_LINE_PARAM)
00126   , search_hint("")
00127   , showing_filters(false)
00128   , can_refine_search(false)
00129   , show_filter_hint_(show_filter_hint_)
00130   , expander_view_(nullptr)
00131   , show_filters_(nullptr)
00132   , last_width_(-1)
00133   , last_height_(-1)
00134 {
00135   Init();
00136 }
00137 
00138 void SearchBar::Init()
00139 {
00140   dash::Style& style = dash::Style::Instance();
00141   nux::BaseTexture* icon = style.GetSearchMagnifyIcon();
00142 
00143   bg_layer_.reset(new nux::ColorLayer(nux::Color(0xff595853), true));
00144 
00145   layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
00146   layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, SEARCH_ENTRY_RIGHT_BORDER);
00147   layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT);
00148   SetLayout(layout_);
00149 
00150   entry_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
00151   entry_layout_->SetLeftAndRightPadding(0, 10);
00152   layout_->AddLayout(entry_layout_);
00153 
00154   spinner_ = new SearchBarSpinner();
00155   spinner_->SetMinMaxSize(icon->GetWidth(), icon->GetHeight());
00156   spinner_->mouse_click.connect(sigc::mem_fun(this, &SearchBar::OnClearClicked));
00157   entry_layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
00158   entry_layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_SPINNER_AND_TEXT);
00159 
00160   nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
00161 
00162   hint_ = new nux::StaticCairoText(" ");
00163   hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
00164   hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str());
00165   hint_layout->AddView(hint_,  0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
00166 
00167   pango_entry_ = new IMTextEntry();
00168   pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str());
00169   pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
00170   pango_entry_->text_changed.connect(sigc::mem_fun(this, &SearchBar::OnSearchChanged));
00171   pango_entry_->activated.connect([&]() { activated.emit(); });
00172   pango_entry_->cursor_moved.connect([&](int i) { QueueDraw(); });
00173   pango_entry_->mouse_down.connect(sigc::mem_fun(this, &SearchBar::OnMouseButtonDown));
00174   pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &SearchBar::OnEndKeyFocus));
00175 
00176   layered_layout_ = new nux::LayeredLayout();
00177   layered_layout_->AddLayout(hint_layout);
00178   layered_layout_->AddLayer(pango_entry_);
00179   layered_layout_->SetPaintAll(true);
00180   layered_layout_->SetActiveLayerN(1);
00181   entry_layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
00182 
00183   if (show_filter_hint_)
00184   {
00185     std::string filter_str(_("Filter results"));
00186     show_filters_ = new nux::StaticCairoText(filter_str);
00187     show_filters_->SetVisible(false);
00188     show_filters_->SetFont(SHOW_FILTERS_LABEL_DEFAULT_FONT.c_str());
00189     show_filters_->SetTextColor(nux::color::White);
00190     show_filters_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_RIGHT);
00191     show_filters_->SetLines(1);
00192 
00193     nux::BaseTexture* arrow;
00194     arrow = style.GetGroupExpandIcon();
00195     expand_icon_ = new IconTexture(arrow,
00196                                    arrow->GetWidth(),
00197                                    arrow->GetHeight());
00198     expand_icon_->SetOpacity(kExpandDefaultIconOpacity);
00199     expand_icon_->SetMinimumSize(arrow->GetWidth(), arrow->GetHeight());
00200     expand_icon_->SetVisible(false);
00201 
00202     filter_layout_ = new nux::HLayout();
00203     filter_layout_->SetHorizontalInternalMargin(8);
00204     filter_layout_->SetLeftAndRightPadding(style.GetFilterResultsHighlightLeftPadding(), style.GetFilterResultsHighlightRightPadding());
00205     filter_layout_->SetContentDistribution(nux::MAJOR_POSITION_END);
00206     filter_layout_->AddView(show_filters_, 0, nux::MINOR_POSITION_CENTER);
00207 
00208     arrow_layout_  = new nux::VLayout();
00209     arrow_top_space_ = new nux::SpaceLayout(2, 2, 12, 12);
00210     arrow_bottom_space_ = new nux::SpaceLayout(2, 2, 8, 8);
00211     arrow_layout_->AddView(arrow_top_space_, 0, nux::MINOR_POSITION_CENTER);
00212     arrow_layout_->AddView(expand_icon_, 0, nux::MINOR_POSITION_CENTER);
00213     arrow_layout_->AddView(arrow_bottom_space_, 0, nux::MINOR_POSITION_CENTER);
00214 
00215     filter_layout_->AddView(arrow_layout_, 0, nux::MINOR_POSITION_CENTER);
00216 
00217     expander_view_ = new ExpanderView(NUX_TRACKER_LOCATION);
00218     expander_view_->SetVisible(false);
00219     expander_view_->SetLayout(filter_layout_);
00220     layout_->AddView(expander_view_, 0, nux::MINOR_POSITION_RIGHT, nux::MINOR_SIZE_FULL);
00221 
00222     int width = style.GetFilterBarWidth() +
00223                 style.GetFilterResultsHighlightLeftPadding() +
00224                 style.GetFilterResultsHighlightRightPadding();
00225 
00226     expander_view_->SetMaximumWidth(width);
00227     expander_view_->SetMinimumWidth(width);
00228     show_filters_->SetMaximumWidth(style.GetFilterBarWidth() - arrow_layout_->GetBaseWidth() - 8);
00229 
00230     // Lambda functions
00231     auto mouse_expand = [&](int, int, unsigned long, unsigned long)
00232     {
00233       showing_filters = !showing_filters;
00234     };
00235 
00236     auto key_redraw = [&](nux::Area*, bool, nux::KeyNavDirection)
00237     {
00238       QueueDraw();
00239     };
00240 
00241     auto key_expand = [&](nux::Area*)
00242     {
00243       showing_filters = !showing_filters;
00244     };
00245 
00246     // Signals
00247     expander_view_->mouse_click.connect(mouse_expand);
00248     expander_view_->key_nav_focus_change.connect(key_redraw);
00249     expander_view_->key_nav_focus_activate.connect(key_expand);
00250     show_filters_->mouse_click.connect(mouse_expand);
00251     expand_icon_->mouse_click.connect(mouse_expand);
00252   }
00253 
00254   sig_manager_.Add(new glib::Signal<void, GtkSettings*, GParamSpec*>
00255       (gtk_settings_get_default(),
00256        "notify::gtk-font-name",
00257        sigc::mem_fun(this, &SearchBar::OnFontChanged)));
00258   OnFontChanged(gtk_settings_get_default());
00259 
00260   search_hint.changed.connect([&](std::string const& s) { OnSearchHintChanged(); });
00261   search_string.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_search_string));
00262   search_string.SetSetterFunction(sigc::mem_fun(this, &SearchBar::set_search_string));
00263   im_active.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_im_active));
00264   im_preedit.SetGetterFunction(sigc::mem_fun(this, &SearchBar::get_im_preedit));
00265   showing_filters.changed.connect(sigc::mem_fun(this, &SearchBar::OnShowingFiltersChanged));
00266   can_refine_search.changed.connect([&] (bool can_refine)
00267   {
00268     if (show_filter_hint_)
00269     {
00270       expander_view_->SetVisible(can_refine);
00271       show_filters_->SetVisible(can_refine);
00272       expand_icon_->SetVisible(can_refine);
00273     }
00274   });
00275 }
00276 
00277 void SearchBar::OnFontChanged(GtkSettings* settings, GParamSpec* pspec)
00278 {
00279   glib::String font_name;
00280   PangoFontDescription* desc;
00281   std::ostringstream font_desc;
00282 
00283   g_object_get(settings, "gtk-font-name", &font_name, NULL);
00284 
00285   desc = pango_font_description_from_string(font_name.Value());
00286   if (desc)
00287   {
00288     pango_entry_->SetFontFamily(pango_font_description_get_family(desc));
00289     pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE);
00290     pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default()));
00291 
00292     font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE;
00293     hint_->SetFont(font_desc.str().c_str());
00294 
00295     font_desc.str("");
00296     font_desc.clear();
00297     font_desc << pango_font_description_get_family(desc) << " " << SHOW_FILTERS_LABEL_FONT_STYLE << " " << SHOW_FILTERS_LABEL_FONT_SIZE;
00298     show_filters_->SetFont(font_desc.str().c_str());
00299 
00300     pango_font_description_free(desc);
00301   }
00302 }
00303 
00304 void SearchBar::OnSearchHintChanged()
00305 {
00306   gchar* tmp = g_markup_escape_text(search_hint().c_str(), -1);
00307 
00308   hint_->SetText(tmp);
00309 
00310   g_free(tmp);
00311 }
00312 
00313 void SearchBar::OnSearchChanged(nux::TextEntry* text_entry)
00314 {
00315   // We don't want to set a new search string on every new character, so we add a sma
00316   // timeout to see if the user is typing a sentence. If more characters are added, we
00317   // keep restarting the timeout unti the user has actuay paused.
00318   live_search_timeout_.reset(new glib::Timeout(LIVE_SEARCH_TIMEOUT));
00319   live_search_timeout_->Run(sigc::mem_fun(this, &SearchBar::OnLiveSearchTimeout));
00320 
00321   // Don't animate the spinner immediately, the searches are fast and
00322   // the spinner would just flicker
00323   start_spinner_timeout_.reset(new glib::Timeout(SPINNER_TIMEOUT));
00324   start_spinner_timeout_->Run(sigc::mem_fun(this, &SearchBar::OnSpinnerStartCb));
00325 
00326   bool is_empty = pango_entry_->im_active() ? false : pango_entry_->GetText() == "";
00327   hint_->SetVisible(is_empty);
00328 
00329   pango_entry_->QueueDraw();
00330   hint_->QueueDraw();
00331   QueueDraw();
00332 
00333   search_changed.emit(pango_entry_->GetText());
00334 }
00335 
00336 bool SearchBar::OnLiveSearchTimeout()
00337 {
00338   live_search_reached.emit(pango_entry_->GetText());
00339   return false;
00340 }
00341 
00342 bool SearchBar::OnSpinnerStartCb()
00343 {
00344   spinner_->SetState(STATE_SEARCHING);
00345   return false;
00346 }
00347 
00348 void SearchBar::OnShowingFiltersChanged(bool is_showing)
00349 {
00350   if (show_filter_hint_)
00351   {
00352     dash::Style& style = dash::Style::Instance();
00353     if (is_showing)
00354       expand_icon_->SetTexture(style.GetGroupUnexpandIcon());
00355     else
00356       expand_icon_->SetTexture(style.GetGroupExpandIcon());
00357   }
00358 }
00359 
00360 void SearchBar::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
00361 {
00362   nux::Geometry const& base = GetGeometry();
00363 
00364   UpdateBackground(false);
00365 
00366   GfxContext.PushClippingRectangle(base);
00367   nux::GetPainter().PaintBackground(GfxContext, base);
00368 
00369   bg_layer_->SetGeometry(nux::Geometry(base.x, base.y, last_width_, last_height_));
00370   nux::GetPainter().RenderSinglePaintLayer(GfxContext,
00371                                            bg_layer_->GetGeometry(),
00372                                            bg_layer_.get());
00373 
00374   if (ShouldBeHighlighted())
00375   {
00376     dash::Style& style = dash::Style::Instance();
00377 
00378     nux::Geometry geo(expander_view_->GetGeometry());
00379 
00380     geo.y -= (HIGHLIGHT_HEIGHT- geo.height) / 2;
00381     geo.height = HIGHLIGHT_HEIGHT;
00382 
00383     if (!highlight_layer_)
00384       highlight_layer_.reset(style.FocusOverlay(geo.width, geo.height));
00385 
00386     highlight_layer_->SetGeometry(geo);
00387     highlight_layer_->Renderlayer(GfxContext);
00388   }
00389 
00390   GfxContext.PopClippingRectangle();
00391 }
00392 
00393 void SearchBar::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
00394 {
00395   nux::Geometry const& geo = GetGeometry();
00396 
00397   GfxContext.PushClippingRectangle(geo);
00398 
00399   if (highlight_layer_ && ShouldBeHighlighted() && !IsFullRedraw())
00400   {
00401     nux::GetPainter().PushLayer(GfxContext, highlight_layer_->GetGeometry(), highlight_layer_.get());
00402   }
00403 
00404 
00405   if (!IsFullRedraw())
00406   {
00407     gPainter.PushLayer(GfxContext, bg_layer_->GetGeometry(), bg_layer_.get());
00408   }
00409   else
00410   {
00411     nux::GetPainter().PushPaintLayerStack();
00412   }
00413 
00414   layout_->ProcessDraw(GfxContext, force_draw);
00415 
00416   if (!IsFullRedraw())
00417   {
00418     gPainter.PopBackground();
00419   }
00420   else
00421   {
00422     nux::GetPainter().PopPaintLayerStack();
00423   }
00424 
00425   GfxContext.PopClippingRectangle();
00426 }
00427 
00428 void SearchBar::OnClearClicked(int x, int y, unsigned long button_fags,
00429                                      unsigned long key_fags)
00430 {
00431   pango_entry_->SetText("");
00432   start_spinner_timeout_.reset();
00433   live_search_reached.emit("");
00434 }
00435 
00436 void SearchBar::OnEntryActivated()
00437 {
00438   activated.emit();
00439 }
00440 
00441 void SearchBar::ForceSearchChanged()
00442 {
00443   // this method will emit search_changed (and live_search_reached after
00444   // returning to mainloop) and starts animating the spinner
00445   live_search_timeout_.reset(new glib::Idle(glib::Source::Priority::DEFAULT));
00446   live_search_timeout_->Run(sigc::mem_fun(this, &SearchBar::OnLiveSearchTimeout));
00447 
00448   // Don't animate the spinner immediately, the searches are fast and
00449   // the spinner would just flicker
00450   start_spinner_timeout_.reset(new glib::Timeout(SPINNER_TIMEOUT * 2));
00451   start_spinner_timeout_->Run(sigc::mem_fun(this, &SearchBar::OnSpinnerStartCb));
00452 
00453   search_changed.emit(pango_entry_->GetText());
00454 }
00455 
00456 void
00457 SearchBar::SearchFinished()
00458 {
00459   start_spinner_timeout_.reset();
00460 
00461   bool is_empty = pango_entry_->im_active() ?
00462     false : pango_entry_->GetText() == "";
00463   spinner_->SetState(is_empty ? STATE_READY : STATE_CLEAR);
00464 }
00465 
00466 void SearchBar::UpdateBackground(bool force)
00467 {
00468   int RADIUS = 5;
00469   nux::Geometry geo(GetGeometry());
00470   geo.width = layered_layout_->GetAbsoluteX() +
00471               layered_layout_->GetAbsoluteWidth() -
00472               GetAbsoluteX() +
00473               SEARCH_ENTRY_RIGHT_BORDER;
00474 
00475   LOG_DEBUG(logger) << "height: "
00476   << geo.height << " - "
00477   << layered_layout_->GetGeometry().height << " - "
00478   << pango_entry_->GetGeometry().height;
00479 
00480   if (geo.width == last_width_
00481       && geo.height == last_height_
00482       && force == false)
00483     return;
00484 
00485   last_width_ = geo.width;
00486   last_height_ = geo.height;
00487 
00488   nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, last_width_, last_height_);
00489   cairo_t* cr = cairo_graphics.GetContext();
00490 
00491   cairo_graphics.DrawRoundedRectangle(cr,
00492                                       1.0f,
00493                                       0.5, 0.5,
00494                                       RADIUS,
00495                                       last_width_ - 1, last_height_ - 1,
00496                                       false);
00497 
00498   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
00499   cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f);
00500   cairo_fill_preserve(cr);
00501   cairo_set_line_width(cr, 1);
00502   cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.7f);
00503   cairo_stroke(cr);
00504 
00505   cairo_destroy(cr);
00506   nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);
00507 
00508   nux::TexCoordXForm texxform;
00509   texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00510   texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00511 
00512   nux::ROPConfig rop;
00513   rop.Blend = true;
00514   rop.SrcBlend = GL_ONE;
00515   rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
00516 
00517   bg_layer_.reset(new nux::TextureLayer(texture2D->GetDeviceTexture(),
00518                                         texxform,
00519                                         nux::color::White,
00520                                         true,
00521                                         rop));
00522 
00523   texture2D->UnReference();
00524 }
00525 
00526 void SearchBar::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key)
00527 {
00528   hint_->SetVisible(false);
00529 }
00530 
00531 void SearchBar::OnEndKeyFocus()
00532 {
00533   hint_->SetVisible(search_string().empty());
00534 }
00535 
00536 
00537 nux::TextEntry* SearchBar::text_entry() const
00538 {
00539   return pango_entry_;
00540 }
00541 
00542 nux::View* SearchBar::show_filters() const
00543 {
00544   return expander_view_;
00545 }
00546 
00547 std::string SearchBar::get_search_string() const
00548 {
00549   return pango_entry_->GetText();
00550 }
00551 
00552 bool SearchBar::set_search_string(std::string const& string)
00553 {
00554   pango_entry_->SetText(string.c_str());
00555   spinner_->SetState(string == "" ? STATE_READY : STATE_CLEAR);
00556 
00557   // we don't want the spinner animating in this case
00558   start_spinner_timeout_.reset();
00559 
00560   return true;
00561 }
00562 
00563 bool SearchBar::get_im_active() const
00564 {
00565   return pango_entry_->im_active();
00566 }
00567 
00568 bool SearchBar::get_im_preedit() const
00569 {
00570   return pango_entry_->im_preedit();
00571 }
00572 
00573 //
00574 // Highlight
00575 //
00576 bool SearchBar::ShouldBeHighlighted()
00577 {
00578   return ((expander_view_ && expander_view_->IsVisible() && expander_view_->HasKeyFocus()));
00579 }
00580 
00581 //
00582 // Key navigation
00583 //
00584 bool SearchBar::AcceptKeyNavFocus()
00585 {
00586   return false;
00587 }
00588 
00589 //
00590 // Introspection
00591 //
00592 std::string SearchBar::GetName() const
00593 {
00594   return "SearchBar";
00595 }
00596 
00597 void SearchBar::AddProperties(GVariantBuilder* builder)
00598 {
00599   unity::variant::BuilderWrapper(builder)
00600   .add(GetAbsoluteGeometry())
00601   .add("has_focus", pango_entry_->HasKeyFocus())
00602   .add("search_string", pango_entry_->GetText())
00603   .add("expander-has-focus", expander_view_->HasKeyFocus())
00604   .add("showing-filters", showing_filters)
00605   .add("filter-label-x", show_filters_->GetAbsoluteX())
00606   .add("filter-label-y", show_filters_->GetAbsoluteY())
00607   .add("filter-label-width", show_filters_->GetAbsoluteWidth())
00608   .add("filter-label-height", show_filters_->GetAbsoluteHeight())
00609   .add("im_active", pango_entry_->im_active());
00610 }
00611 
00612 } // namespace unity