diff options
| author | Brandon Schaefer <brandon.schaefer@canonical.com> | 2014-06-06 13:54:37 +0000 |
|---|---|---|
| committer | CI bot <ps-jenkins@lists.canonical.com> | 2014-06-06 13:54:37 +0000 |
| commit | 56667e4319a64bd3fa58aa920969e1fec5fc9aba (patch) | |
| tree | a5e046352625ec38a406dd54df68f58d03c30103 /unity-shared | |
| parent | d1c1567f087d1fbf282c0b0681620b40f6df18fd (diff) | |
| parent | 2cad6786441d64f4b4f6de362080e8e1d1108e56 (diff) | |
TextInput: move the warning icon inside the input field, render it white Fixes: 1307738
Original authors: - Brandon Schaefer <brandon.schaefer@canonical.com> - Brandon Schaefer <brandontschaefer@gmail.com> (bzr r3809)
Diffstat (limited to 'unity-shared')
| -rw-r--r-- | unity-shared/TextInput.cpp | 111 | ||||
| -rw-r--r-- | unity-shared/TextInput.h | 13 |
2 files changed, 118 insertions, 6 deletions
diff --git a/unity-shared/TextInput.cpp b/unity-shared/TextInput.cpp index 2dfb72769..4bed2001d 100644 --- a/unity-shared/TextInput.cpp +++ b/unity-shared/TextInput.cpp @@ -18,6 +18,15 @@ */ #include "TextInput.h" +#include "unity-shared/IconTexture.h" +#include "unity-shared/DashStyle.h" +#include "unity-shared/RawPixel.h" +#include "unity-shared/PreviewStyle.h" + +#include <X11/XKBlib.h> + +namespace unity +{ namespace { @@ -29,6 +38,10 @@ const int TEXT_INPUT_RIGHT_BORDER = 10; const int HIGHLIGHT_HEIGHT = 24; +const RawPixel DEFAULT_ICON_SIZE = 22_em; + +std::string WARNING_ICON = "dialog-warning-symbolic"; + // Fonts const std::string HINT_LABEL_DEFAULT_FONT_NAME = "Ubuntu"; const int HINT_LABEL_FONT_SIZE = 11; @@ -38,19 +51,41 @@ const int PANGO_ENTRY_FONT_SIZE = 14; } -namespace unity -{ - nux::logging::Logger logger("unity.textinput"); NUX_IMPLEMENT_OBJECT_TYPE(TextInput); +nux::AbstractPaintLayer* CreateWarningLayer(nux::BaseTexture* texture) +{ + // Create the texture layer + nux::TexCoordXForm texxform; + + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + texxform.min_filter = nux::TEXFILTER_LINEAR; + texxform.mag_filter = nux::TEXFILTER_LINEAR; + + nux::ROPConfig rop; + rop.Blend = true; + + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + return (new nux::TextureLayer(texture->GetDeviceTexture(), + texxform, + nux::color::White, + true, + rop)); +} + TextInput::TextInput(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , input_hint("") , hint_font_name(HINT_LABEL_DEFAULT_FONT_NAME) , hint_font_size(HINT_LABEL_FONT_SIZE) + , show_caps_lock(false) , bg_layer_(new nux::ColorLayer(nux::Color(0xff595853), true)) + , caps_lock_on(false) , last_width_(-1) , last_height_(-1) { @@ -74,6 +109,7 @@ TextInput::TextInput(NUX_FILE_LINE_DECL) pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE); pango_entry_->cursor_moved.connect([this](int i) { QueueDraw(); }); pango_entry_->mouse_down.connect(sigc::mem_fun(this, &TextInput::OnMouseButtonDown)); + pango_entry_->key_up.connect(sigc::mem_fun(this, &TextInput::OnKeyUp)); pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &TextInput::OnEndKeyFocus)); pango_entry_->text_changed.connect([this](nux::TextEntry*) { hint_->SetVisible(input_string().empty()); @@ -86,6 +122,22 @@ TextInput::TextInput(NUX_FILE_LINE_DECL) layered_layout_->SetActiveLayerN(1); layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); + auto* warning = new IconTexture(LoadWarningIcon(DEFAULT_ICON_SIZE)); + warning->SetVisible(caps_lock_on()); + layout_->AddView(warning, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + caps_lock_on.changed.connect([this, warning] (bool on) { + if (show_caps_lock) + { + warning->SetVisible(on); + QueueRelayout(); + QueueDraw(); + } + }); + + show_caps_lock.changed.connect([this] (bool changed) { + CheckIfCapsLockOn(); + }); + spinner_ = new SearchBarSpinner(); spinner_->SetVisible(false); spinner_->SetMinMaxSize(22, 22); @@ -100,7 +152,19 @@ TextInput::TextInput(NUX_FILE_LINE_DECL) im_active.SetGetterFunction(sigc::mem_fun(this, &TextInput::get_im_active)); im_preedit.SetGetterFunction(sigc::mem_fun(this, &TextInput::get_im_preedit)); input_hint.changed.connect([this](std::string const& s) { OnInputHintChanged(); }); +} +void TextInput::CheckIfCapsLockOn() +{ + Display *dpy = nux::GetGraphicsDisplay()->GetX11Display(); + unsigned int state = 0; + XkbGetIndicatorState(dpy, XkbUseCoreKbd, &state); + + // Caps is on 0x1, couldn't find any #define in /usr/include/X11 + if ((state & 0x1) == 1) + caps_lock_on = true; + else + caps_lock_on = false; } void TextInput::SetSpinnerVisible(bool visible) @@ -118,6 +182,37 @@ void TextInput::UpdateHintFont() hint_->SetFont((hint_font_name() + " " + std::to_string(hint_font_size())).c_str()); } +nux::ObjectPtr<nux::BaseTexture> TextInput::LoadWarningIcon(int icon_size) +{ + auto* theme = gtk_icon_theme_get_default(); + GtkIconLookupFlags flags = GTK_ICON_LOOKUP_FORCE_SIZE; + glib::Error error; + glib::Object<GdkPixbuf> pixbuf(gtk_icon_theme_load_icon(theme, WARNING_ICON.c_str(), icon_size, flags, &error)); + + if (pixbuf != nullptr) + { + nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); + cairo_t* cr = cg.GetInternalContext(); + + cairo_push_group(cr); + gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); + cairo_paint_with_alpha(cr, 1.0); + std::shared_ptr<cairo_pattern_t> pat(cairo_pop_group(cr), cairo_pattern_destroy); + + cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f); + cairo_rectangle(cr, 0, 0, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); + cairo_mask(cr, pat.get()); + + return texture_ptr_from_cairo_graphics(cg); + } + // Use fallback icon (this one is a png, and does not scale!) + else + { + dash::previews::Style& preview_style = dash::previews::Style::Instance(); + return nux::ObjectPtr<nux::BaseTexture>(preview_style.GetWarningIcon()); + } +} + void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec) { glib::String font_name; @@ -254,6 +349,16 @@ void TextInput::UpdateBackground(bool force) texture2D->UnReference(); } +void TextInput::OnKeyUp(unsigned keysym, + unsigned long keycode, + unsigned long state) +{ + if (!caps_lock_on && keysym == NUX_VK_CAPITAL) + caps_lock_on = true; + else if (caps_lock_on && keysym == NUX_VK_CAPITAL) + caps_lock_on = false; +} + void TextInput::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key) { hint_->SetVisible(false); diff --git a/unity-shared/TextInput.h b/unity-shared/TextInput.h index 462474d6e..5f8535829 100644 --- a/unity-shared/TextInput.h +++ b/unity-shared/TextInput.h @@ -62,6 +62,8 @@ public: void SetSpinnerVisible(bool visible); void SetSpinnerState(SpinnerState spinner_state); + void EnableCapsLockWarning() const; + IMTextEntry* text_entry() const; nux::RWProperty<std::string> input_string; @@ -70,6 +72,7 @@ public: nux::Property<int> hint_font_size; nux::ROProperty<bool> im_active; nux::ROProperty<bool> im_preedit; + nux::Property<bool> show_caps_lock; private: void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL); @@ -83,9 +86,15 @@ private: void AddProperties(debug::IntrospectionData&); bool AcceptKeyNavFocus(); + bool ShouldBeHighlighted(); + void CheckIfCapsLockOn(); + + nux::ObjectPtr<nux::BaseTexture> LoadWarningIcon(int icon_size); + protected: void OnInputHintChanged(); void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags); + void OnKeyUp(unsigned keysym, unsigned long keycode, unsigned long state); void OnEndKeyFocus(); // getters & setters @@ -101,19 +110,17 @@ protected: private: - bool ShouldBeHighlighted(); - std::unique_ptr<nux::AbstractPaintLayer> bg_layer_; std::unique_ptr<nux::AbstractPaintLayer> highlight_layer_; nux::HLayout* layout_; nux::LayeredLayout* layered_layout_; SearchBarSpinner* spinner_; + nux::Property<bool> caps_lock_on; int last_width_; int last_height_; glib::SignalManager sig_manager_; - }; } |
