diff options
Diffstat (limited to 'unity-shared')
| -rw-r--r-- | unity-shared/BGHash.cpp | 4 | ||||
| -rw-r--r-- | unity-shared/CMakeLists.txt | 32 | ||||
| -rw-r--r-- | unity-shared/FakeKeyboardUtil.cpp | 36 | ||||
| -rw-r--r-- | unity-shared/IconRenderer.cpp | 6 | ||||
| -rw-r--r-- | unity-shared/OverlayRenderer.cpp | 4 | ||||
| -rw-r--r-- | unity-shared/ResizingBaseWindow.h | 2 | ||||
| -rw-r--r-- | unity-shared/TextInput.cpp | 366 | ||||
| -rw-r--r-- | unity-shared/TextInput.h | 102 |
8 files changed, 543 insertions, 9 deletions
diff --git a/unity-shared/BGHash.cpp b/unity-shared/BGHash.cpp index 4f66a873a..0b2b5afe1 100644 --- a/unity-shared/BGHash.cpp +++ b/unity-shared/BGHash.cpp @@ -22,6 +22,10 @@ #include <NuxCore/Logger.h> #include "unity-shared/UBusMessages.h" +#ifndef XA_STRING +#define XA_STRING ((Atom) 31) +#endif + namespace { nux::logging::Logger logger("unity.BGHash"); diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt index c8ac7bc1d..28dcc84e8 100644 --- a/unity-shared/CMakeLists.txt +++ b/unity-shared/CMakeLists.txt @@ -52,6 +52,7 @@ set (UNITY_SHARED_SOURCES SearchBarSpinner.cpp StaticCairoText.cpp TextureCache.cpp + TextInput.cpp TextureThumbnailProvider.cpp ThumbnailGenerator.cpp Timer.cpp @@ -63,10 +64,21 @@ set (UNITY_SHARED_SOURCES UnityWindowView.cpp UserThumbnailProvider.cpp WindowManager.cpp - XKeyboardUtil.cpp - XWindowManager.cpp ) +if(UNITY_ENABLE_X_ORG_SUPPORT) + set (UNITY_SHARED_SOURCES + XKeyboardUtil.cpp + XWindowManager.cpp + ${UNITY_SHARED_SOURCES} + ) +else() + set (UNITY_SHARED_SOURCES + FakeKeyboardUtil.cpp + ${UNITY_SHARED_SOURCES} + ) +endif() + add_library (unity-shared STATIC ${UNITY_SHARED_SOURCES}) target_link_libraries (unity-shared ${LIBS}) add_dependencies (unity-shared unity-core-${UNITY_API_VERSION}) @@ -75,14 +87,16 @@ add_dependencies (unity-shared unity-core-${UNITY_API_VERSION}) # We also need to build compiz specific parts and standalone variants of those parts # -# compiz -set (UNITY_SHARED_COMPIZ_SOURCES - PluginAdapter.cpp - ) -add_library (unity-shared-compiz STATIC ${UNITY_SHARED_COMPIZ_SOURCES}) -target_link_libraries (unity-shared-compiz ${LIBS}) +if(UNITY_ENABLE_X_ORG_SUPPORT) + # compiz + set (UNITY_SHARED_COMPIZ_SOURCES + PluginAdapter.cpp + ) + add_library (unity-shared-compiz STATIC ${UNITY_SHARED_COMPIZ_SOURCES}) + target_link_libraries (unity-shared-compiz ${LIBS}) -add_dependencies (unity-shared-compiz unity-shared) + add_dependencies (unity-shared-compiz unity-shared) +endif() # standalone set (UNITY_SHARED_STANDALONE_SOURCES diff --git a/unity-shared/FakeKeyboardUtil.cpp b/unity-shared/FakeKeyboardUtil.cpp new file mode 100644 index 000000000..0ea1089e8 --- /dev/null +++ b/unity-shared/FakeKeyboardUtil.cpp @@ -0,0 +1,36 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Tim Penhey <tim.penhey@canonical.com> + */ + +namespace unity +{ +namespace keyboard +{ + +bool is_printable_key_symbol(unsigned long key_symbol) +{ + return false; +} + +bool is_move_key_symbol(unsigned long key_symbol) +{ + return false; +} + +} +} diff --git a/unity-shared/IconRenderer.cpp b/unity-shared/IconRenderer.cpp index c2ffb91f0..ca6b0db5f 100644 --- a/unity-shared/IconRenderer.cpp +++ b/unity-shared/IconRenderer.cpp @@ -208,7 +208,9 @@ std::vector<nux::BaseTexture*> icon_shadow; std::vector<nux::BaseTexture*> icon_shine; nux::ObjectPtr<nux::IOpenGLBaseTexture> offscreen_progress_texture; nux::ObjectPtr<nux::IOpenGLShaderProgram> shader_program_uv_persp_correction; +#ifndef USE_GLES nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> asm_shader; +#endif std::map<char, nux::BaseTexture*> label_map; void generate_textures(); @@ -867,7 +869,9 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext, } else { +#ifndef USE_GLES local::asm_shader->End(); +#endif } } @@ -1168,6 +1172,7 @@ void setup_shaders() } else { +#ifndef USE_GLES asm_shader = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); asm_shader->LoadVertexShader(TCHAR_TO_ANSI(PerspectiveCorrectVtx.c_str())); @@ -1184,6 +1189,7 @@ void setup_shaders() } asm_shader->Link(); +#endif } } diff --git a/unity-shared/OverlayRenderer.cpp b/unity-shared/OverlayRenderer.cpp index 6575172a5..76e10be25 100644 --- a/unity-shared/OverlayRenderer.cpp +++ b/unity-shared/OverlayRenderer.cpp @@ -84,8 +84,10 @@ public: void InitASMInverseTextureMaskShader(); void InitSlInverseTextureMaskShader(); +#ifndef NUX_OPENGLES_20 nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> inverse_texture_mask_asm_prog_; nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> inverse_texture_rect_mask_asm_prog_; +#endif nux::ObjectPtr<nux::IOpenGLShaderProgram> inverse_texture_mask_prog_; void RenderInverseMask_GLSL(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0); @@ -239,6 +241,7 @@ void OverlayRendererImpl::InitASMInverseTextureMaskShader() SUB result.color, {1.0, 1.0, 1.0, 1.0}, temp0.aaaa; \n\ END"; +#ifndef NUX_OPENGLES_20 inverse_texture_mask_asm_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); inverse_texture_mask_asm_prog_->LoadVertexShader(AsmVtx.c_str()); inverse_texture_mask_asm_prog_->LoadPixelShader(AsmFrg.c_str()); @@ -248,6 +251,7 @@ void OverlayRendererImpl::InitASMInverseTextureMaskShader() inverse_texture_rect_mask_asm_prog_->LoadVertexShader(AsmVtx.c_str()); inverse_texture_rect_mask_asm_prog_->LoadPixelShader(AsmFrgRect.c_str()); inverse_texture_rect_mask_asm_prog_->Link(); +#endif } void OverlayRendererImpl::RenderInverseMask_ASM(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture, nux::TexCoordXForm &texxform, const nux::Color &color) diff --git a/unity-shared/ResizingBaseWindow.h b/unity-shared/ResizingBaseWindow.h index ff400c1c2..c7f50cbb2 100644 --- a/unity-shared/ResizingBaseWindow.h +++ b/unity-shared/ResizingBaseWindow.h @@ -35,8 +35,10 @@ public: void UpdateInputWindowGeometry() { +#ifdef UNITY_HAS_X_ORG_SUPPORT if (m_input_window && m_input_window_enabled) m_input_window->SetGeometry(geo_func_(GetGeometry())); +#endif } virtual void SetGeometry(const nux::Geometry &geo) diff --git a/unity-shared/TextInput.cpp b/unity-shared/TextInput.cpp new file mode 100644 index 000000000..5cad7ea21 --- /dev/null +++ b/unity-shared/TextInput.cpp @@ -0,0 +1,366 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more detais. + * + * You shoud have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Manuel de la Pena <manuel.delapena@canonical.com> + */ + +#include "config.h" + +#include <Nux/Nux.h> +#include <Nux/HLayout.h> +#include <Nux/VLayout.h> +#include <NuxCore/Logger.h> + +#include <UnityCore/Variant.h> + +#include <glib/gi18n-lib.h> + +#include "TextInput.h" +#include "CairoTexture.h" + +namespace +{ +const float kExpandDefaultIconOpacity = 1.0f; + +const int SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT = 10; +const int LEFT_INTERNAL_PADDING = 6; +const int TEXT_INPUT_RIGHT_BORDER = 10; + +const int HIGHLIGHT_HEIGHT = 24; + +// Fonts +const std::string HINT_LABEL_FONT_SIZE = "12px"; +const std::string HINT_LABEL_FONT_STYLE = "Italic"; +const std::string HINT_LABEL_DEFAULT_FONT = "Ubuntu " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE; + +const std::string PANGO_ENTRY_DEFAULT_FONT_FAMILY = "Ubuntu"; +const int PANGO_ENTRY_FONT_SIZE = 14; + +} + +namespace +{ + +nux::logging::Logger logger("unity"); + +class ExpanderView : public nux::View +{ +public: + ExpanderView(NUX_FILE_LINE_DECL) + : nux::View(NUX_FILE_LINE_PARAM) + { + SetAcceptKeyNavFocusOnMouseDown(false); + SetAcceptKeyNavFocusOnMouseEnter(true); + } + +protected: + void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) + {} + + void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) + { + if (GetLayout()) + GetLayout()->ProcessDraw(graphics_engine, force_draw); + } + + bool AcceptKeyNavFocus() + { + return true; + } + + nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) + { + bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); + + if (mouse_inside == false) + return nullptr; + + return this; + } +}; + +} + +namespace unity +{ + +NUX_IMPLEMENT_OBJECT_TYPE(TextInput); + +TextInput::TextInput(NUX_FILE_LINE_DECL) + : View(NUX_FILE_LINE_PARAM) + , input_hint("") + , last_width_(-1) + , last_height_(-1) +{ + Init(); +} + +void TextInput::Init() +{ + bg_layer_.reset(new nux::ColorLayer(nux::Color(0xff595853), true)); + + layout_ = new nux::HLayout(NUX_TRACKER_LOCATION); + layout_->SetLeftAndRightPadding(LEFT_INTERNAL_PADDING, TEXT_INPUT_RIGHT_BORDER); + layout_->SetSpaceBetweenChildren(SPACE_BETWEEN_ENTRY_AND_HIGHLIGHT); + SetLayout(layout_); + + nux::HLayout* hint_layout = new nux::HLayout(NUX_TRACKER_LOCATION); + + hint_ = new nux::StaticCairoText(" "); + hint_->SetTextColor(nux::Color(1.0f, 1.0f, 1.0f, 0.5f)); + hint_->SetFont(HINT_LABEL_DEFAULT_FONT.c_str()); + hint_layout->AddView(hint_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + + pango_entry_ = new IMTextEntry(); + pango_entry_->SetFontFamily(PANGO_ENTRY_DEFAULT_FONT_FAMILY.c_str()); + pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE); + pango_entry_->cursor_moved.connect([&](int i) { QueueDraw(); }); + pango_entry_->mouse_down.connect(sigc::mem_fun(this, &TextInput::OnMouseButtonDown)); + pango_entry_->end_key_focus.connect(sigc::mem_fun(this, &TextInput::OnEndKeyFocus)); + + layered_layout_ = new nux::LayeredLayout(); + layered_layout_->AddLayout(hint_layout); + layered_layout_->AddLayer(pango_entry_); + layered_layout_->SetPaintAll(true); + layered_layout_->SetActiveLayerN(1); + layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); + + sig_manager_.Add<void, GtkSettings*, GParamSpec*>(gtk_settings_get_default(), + "notify::gtk-font-name", sigc::mem_fun(this, &TextInput::OnFontChanged)); + OnFontChanged(gtk_settings_get_default()); + + input_string.SetGetterFunction(sigc::mem_fun(this, &TextInput::get_input_string)); + input_string.SetSetterFunction(sigc::mem_fun(this, &TextInput::set_input_string)); + 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([&](std::string const& s) { OnInputHintChanged(); }); + +} + +void TextInput::OnFontChanged(GtkSettings* settings, GParamSpec* pspec) +{ + glib::String font_name; + PangoFontDescription* desc; + std::ostringstream font_desc; + + g_object_get(settings, "gtk-font-name", &font_name, NULL); + + desc = pango_font_description_from_string(font_name.Value()); + if (desc) + { + pango_entry_->SetFontFamily(pango_font_description_get_family(desc)); + pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE); + pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default())); + + font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE; + hint_->SetFont(font_desc.str().c_str()); + + font_desc.str(""); + font_desc.clear(); + + pango_font_description_free(desc); + } +} + +void TextInput::OnInputHintChanged() +{ + glib::String tmp(g_markup_escape_text(input_hint().c_str(), -1)); + hint_->SetText(tmp); +} + +void TextInput::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry const& base = GetGeometry(); + + UpdateBackground(false); + + GfxContext.PushClippingRectangle(base); + nux::GetPainter().PaintBackground(GfxContext, base); + + bg_layer_->SetGeometry(nux::Geometry(base.x, base.y, last_width_, last_height_)); + nux::GetPainter().RenderSinglePaintLayer(GfxContext, + bg_layer_->GetGeometry(), + bg_layer_.get()); + + GfxContext.PopClippingRectangle(); +} + +void TextInput::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry const& geo = GetGeometry(); + + GfxContext.PushClippingRectangle(geo); + + if (highlight_layer_ && ShouldBeHighlighted() && !IsFullRedraw()) + { + nux::GetPainter().PushLayer(GfxContext, highlight_layer_->GetGeometry(), highlight_layer_.get()); + } + + + if (!IsFullRedraw()) + { + gPainter.PushLayer(GfxContext, bg_layer_->GetGeometry(), bg_layer_.get()); + } + else + { + nux::GetPainter().PushPaintLayerStack(); + } + + layout_->ProcessDraw(GfxContext, force_draw); + + if (!IsFullRedraw()) + { + gPainter.PopBackground(); + } + else + { + nux::GetPainter().PopPaintLayerStack(); + } + + GfxContext.PopClippingRectangle(); +} + +void TextInput::UpdateBackground(bool force) +{ + int RADIUS = 5; + nux::Geometry geo(GetGeometry()); + geo.width = layered_layout_->GetAbsoluteX() + + layered_layout_->GetAbsoluteWidth() - + GetAbsoluteX() + + TEXT_INPUT_RIGHT_BORDER; + + LOG_DEBUG(logger) << "height: " + << geo.height << " - " + << layered_layout_->GetGeometry().height << " - " + << pango_entry_->GetGeometry().height; + + if (geo.width == last_width_ + && geo.height == last_height_ + && force == false) + return; + + last_width_ = geo.width; + last_height_ = geo.height; + + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, last_width_, last_height_); + cairo_t* cr = cairo_graphics.GetContext(); + + cairo_graphics.DrawRoundedRectangle(cr, + 1.0f, + 0.5, 0.5, + RADIUS, + last_width_ - 1, last_height_ - 1, + false); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f); + cairo_fill_preserve(cr); + cairo_set_line_width(cr, 1); + cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.7f); + cairo_stroke(cr); + + cairo_destroy(cr); + nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics); + + nux::TexCoordXForm texxform; + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); + + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + + bg_layer_.reset(new nux::TextureLayer(texture2D->GetDeviceTexture(), + texxform, + nux::color::White, + true, + rop)); + + texture2D->UnReference(); +} + +void TextInput::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key) +{ + hint_->SetVisible(false); +} + +void TextInput::OnEndKeyFocus() +{ + hint_->SetVisible(input_string().empty()); +} + + +nux::TextEntry* TextInput::text_entry() const +{ + return pango_entry_; +} + +std::string TextInput::get_input_string() const +{ + return pango_entry_->GetText(); +} + +bool TextInput::set_input_string(std::string const& string) +{ + pango_entry_->SetText(string.c_str()); + return true; +} + +bool TextInput::get_im_active() const +{ + return pango_entry_->im_active(); +} + +bool TextInput::get_im_preedit() const +{ + return pango_entry_->im_preedit(); +} + +// +// Highlight +// +bool TextInput::ShouldBeHighlighted() +{ + return true; +} + +// +// Key navigation +// +bool TextInput::AcceptKeyNavFocus() +{ + return false; +} + +// +// Introspection +// +std::string TextInput::GetName() const +{ + return "TextInput"; +} + +void TextInput::AddProperties(GVariantBuilder* builder) +{ + unity::variant::BuilderWrapper(builder) + .add(GetAbsoluteGeometry()) + .add("has_focus", pango_entry_->HasKeyFocus()) + .add("input_string", pango_entry_->GetText()) + .add("im_active", pango_entry_->im_active()); +} + +} // namespace unity diff --git a/unity-shared/TextInput.h b/unity-shared/TextInput.h new file mode 100644 index 000000000..e68f29262 --- /dev/null +++ b/unity-shared/TextInput.h @@ -0,0 +1,102 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Manuel de la Pena <manuel.delapena@canonical.com> + */ + +#ifndef TEXTINPUT_H +#define TEXTINPUT_H + +#include <gtk/gtk.h> +#include <NuxCore/Property.h> +#include <Nux/LayeredLayout.h> +#include <Nux/VLayout.h> +#include <Nux/TextEntry.h> +#include <UnityCore/GLibSignal.h> +#include <UnityCore/GLibSource.h> + +#include "unity-shared/IconTexture.h" +#include "unity-shared/IMTextEntry.h" +#include "unity-shared/Introspectable.h" +#include "unity-shared/StaticCairoText.h" + +namespace nux +{ +class AbstractPaintLayer; +class LinearLayout; +} + +namespace unity +{ + +class TextInput : public unity::debug::Introspectable, public nux::View +{ + NUX_DECLARE_OBJECT_TYPE(TextInput, nux::View); +public: + typedef nux::ObjectPtr<TextInput> Ptr; + TextInput(NUX_FILE_LINE_PROTO); + TextInput(bool show_filter_hint, NUX_FILE_LINE_PROTO); + + nux::TextEntry* text_entry() const; + + nux::RWProperty<std::string> input_string; + nux::Property<std::string> input_hint; + nux::ROProperty<bool> im_active; + nux::ROProperty<bool> im_preedit; + +private: + + void Init(); + + void OnFontChanged(GtkSettings* settings, GParamSpec* pspec=NULL); + void OnInputHintChanged(); + + void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + + void OnMouseButtonDown(int x, int y, unsigned long button_flags, unsigned long key_flags); + void OnEndKeyFocus(); + + void UpdateBackground(bool force); + + std::string get_input_string() const; + bool set_input_string(std::string const& string); + bool get_im_active() const; + bool get_im_preedit() const; + + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + bool AcceptKeyNavFocus(); + +private: + bool ShouldBeHighlighted(); + + std::unique_ptr<nux::AbstractPaintLayer> bg_layer_; + std::unique_ptr<nux::AbstractPaintLayer> highlight_layer_; + nux::HLayout* layout_; + nux::LayeredLayout* layered_layout_; + nux::StaticCairoText* hint_; + IMTextEntry* pango_entry_; + + int last_width_; + int last_height_; + + glib::SignalManager sig_manager_; +}; + +} + +#endif |
