/******************************************************************************* * PROJECT: GNOME Colorscheme * * AUTHOR: Jonathon Jongsma * * Copyright (c) 2005 Jonathon Jongsma * * License: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * *******************************************************************************/ #include #include #include #include #include #include #include #include #include "gcs-textswatch.h" #include "core/log-stream.h" #include "gcs-i18n.h" namespace gcs { namespace Widgets { TextSwatch::TextSwatch(ColorPtr bg) : ColorSwatch(bg), m_refUIManager(Gtk::UIManager::create()), m_pMinText(0), m_pMaxText(0), m_pContextMenu(0) { // get_window() would return 0 because the Gdk::Window has not yet been // realized So we can only allocate the colors here - the rest will // happen in on_realize(). m_colormap = get_default_colormap(); m_colormap->alloc_color(m_black->gdk()); m_colormap->alloc_color(m_white->gdk()); LOG("TextSwatch Created!"); Glib::RefPtr refActions = Gtk::ActionGroup::create(); refActions->add(Gtk::Action::create("CopyColor", Gtk::Stock::COPY), sigc::mem_fun(*this, &TextSwatch::on_action_copy)); m_refUIManager->insert_action_group(refActions); Glib::ustring ui_string = "" " " " " " " ""; try { m_refUIManager->add_ui_from_string(ui_string); LOG("added TextSwatchUI"); } catch(const Glib::Error& ex) { std::cerr << "Building TextSwatch menus failed: " << ex.what(); } m_pContextMenu = dynamic_cast(m_refUIManager->get_widget("/ColorSwatchPopup")); // give the text swatches a bit of a rounded corner look m_cornerRadius = 10; } TextSwatch::TextSwatch(const TextSwatch& c) : ColorSwatch(c) { m_foreground = c.m_foreground; m_textGC = c.m_textGC; m_refContext = c.m_refContext; m_pMinText = std::auto_ptr(new SwatchText(*c.m_pMinText)); m_pMaxText = std::auto_ptr(new SwatchText(*c.m_pMaxText)); } TextSwatch::~TextSwatch(void) { //delete &m_background; } void TextSwatch::on_realize(void) { // We need to call the base on_realize() Gtk::DrawingArea::on_realize(); // Now we can allocate any additional resources we need Glib::RefPtr window = get_window(); // set the size of the swatch. set_size_request(m_minSize, m_minSize); m_textGC = Gdk::GC::create(window); add_events(Gdk::BUTTON_PRESS_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); Glib::RefPtr m_refContext = create_pango_context(); // create a pango layout for just the hex string m_pMinText.reset(new SwatchText(m_refContext, "")); // create a pango layout for the hex string, rgb, and hsv m_pMaxText.reset(new SwatchText(m_refContext, "")); pTooltips->set_tip(*this, _("Double-click to select")); } bool TextSwatch::on_expose_event(GdkEventExpose *e) { ColorSwatch::on_expose_event(e); if (m_background->get_value() > 65) { m_foreground = m_black; } else { m_foreground = m_white; } m_textGC->set_foreground(m_foreground->gdk()); Glib::RefPtr win = get_window(); int winWidth, winHeight; int textX, textY; win->get_size(winWidth, winHeight); SwatchText *pText; if (winWidth > m_pMaxText->get_width() + 2 * m_borderWidth + 2 * m_swatchPadding && winHeight > m_pMaxText->get_height()+ 2 * m_borderWidth + 2 * m_swatchPadding) { pText = m_pMaxText.get(); } else if (winWidth > m_pMinText->get_width() + 2 * m_borderWidth + 2 * m_swatchPadding && winHeight > m_pMinText->get_height()+ 2 * m_borderWidth + 2 * m_swatchPadding) { pText = m_pMinText.get(); } else // swatch is too small -- don't display any text { pText = 0; } if (pText != NULL) { textX = (winWidth - pText->get_width()) / 2; textY = (winHeight - pText->get_height()) / 2; win->draw_layout(m_textGC, textX, textY, pText->get_layout()); } return true; } void TextSwatch::set_color(ColorPtr bg) { ColorSwatch::set_color(bg); std::ostringstream txt; // populate the minimal text string txt << m_background->get_hexstring() << std::endl; Glib::ustring minSpec = txt.str(); //LOG("Mintext = " << minSpec); //LOG("background_ = " << m_background); // We can fit more text in the swatch, so add some more info txt << "rgb(" << m_background->get_red() << ", " << m_background->get_green() << ", " << m_background->get_blue() << ")" << std::endl; txt << "hsv(" << m_background->get_hue() << ", " << m_background->get_saturation() << ", " << m_background->get_value() << ")"; Glib::ustring maxSpec = txt.str(); m_pMinText->set_text(minSpec); m_pMaxText->set_text(maxSpec); } bool TextSwatch::on_button_press_event(GdkEventButton *e) { //Then do our custom stuff: if (e->type == GDK_BUTTON_PRESS) { if (e->button == 3) { // User pressed right mouse button if (m_pContextMenu != NULL) { LOG("context menu registered -- popup " << (long) m_pContextMenu); m_pContextMenu->popup(e->button, e->time); } else { LOG("No context menu registered"); } } } if (e->type == GDK_2BUTTON_PRESS) { if (e->button == 1) { // User pressed left mouse button m_signal_selected.emit(); } } return true; } void TextSwatch::on_action_copy(void) { LOG("Colorswatch on_action_copy"); m_clipboardBuffer = m_background->get_hexstring(); Glib::RefPtr refClipboard = Gtk::Clipboard::get(); //Targets: std::list listTargets; listTargets.push_back(Gtk::TargetEntry("UTF8_STRING")); refClipboard->set(listTargets, sigc::mem_fun(*this, &TextSwatch::on_clipboard_get), sigc::mem_fun(*this, &TextSwatch::on_clipboard_clear)); } void TextSwatch::on_clipboard_get(Gtk::SelectionData& data, guint info) { if (data.get_target() == "UTF8_STRING") { data.set_text(m_clipboardBuffer); } } void TextSwatch::on_clipboard_clear(void) {} TextSwatch::SwatchText::SwatchText(Glib::RefPtr context, Glib::ustring txt) : m_refLayout(Pango::Layout::create(context)) { m_refLayout->set_alignment(Pango::ALIGN_CENTER); set_text(txt); } TextSwatch::SwatchText::~SwatchText(void) { } void TextSwatch::SwatchText::update_extents(void) { Pango::Rectangle extents(m_refLayout->get_ink_extents()); m_width = extents.get_width() / Pango::SCALE; m_height = extents.get_height() / Pango::SCALE; } void TextSwatch::SwatchText::set_text(Glib::ustring text) { m_refLayout->set_text(text); update_extents(); } } // namespace Widgets } // namespace gcs