Logo Search packages:      
Sourcecode: agave version File versions  Download package

gcs-textswatch.cc

/*******************************************************************************
 *  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 <iostream>
#include <sstream>

#include <gtkmm/actiongroup.h>
#include <gtkmm/stock.h>
#include <gtkmm/clipboard.h>
#include <gdkmm/gc.h>
#include <pangomm/layout.h>
#include <glibmm/ustring.h>

#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());
            alloc_bg();
            LOG("TextSwatch Created!");
            Glib::RefPtr<Gtk::ActionGroup> 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 = 
                "<ui>"
                "    <popup name='ColorSwatchPopup'>"
                "       <menuitem action='CopyColor'/>"
                "    </popup>"
                "</ui>";

            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<Gtk::Menu*>(m_refUIManager->get_widget("/ColorSwatchPopup"));
        }


        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<SwatchText>(new SwatchText(*c.m_pMinText));
            m_pMaxText = std::auto_ptr<SwatchText>(new SwatchText(*c.m_pMaxText));
        }


        TextSwatch::~TextSwatch(void)
        {
            //delete &m_background;
        }


00103         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<Gdk::Window> window = get_window();
            // set the size of the swatch.
            set_size_request(m_minSize, m_minSize);
            m_textGC = Gdk::GC::create(window);
            m_borderGC = Gdk::GC::create(window);
            m_borderGC->set_line_attributes(m_borderWidth, Gdk::LINE_SOLID,
                    Gdk::CAP_BUTT, Gdk::JOIN_MITER);
            m_borderGC->set_foreground(m_black->gdk());
            add_events(Gdk::BUTTON_PRESS_MASK | Gdk::ENTER_NOTIFY_MASK |
                    Gdk::LEAVE_NOTIFY_MASK);
            Glib::RefPtr<Pango::Context> 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)
        {
            if (m_background->get_value() > 65)
            {
                m_foreground = m_black;
            }
            else
            {
                m_foreground = m_white;
            }
            m_textGC->set_foreground(m_foreground->gdk());
            redraw();
            return true;
        }


00144         void TextSwatch::redraw(void)
        {
            ColorSwatch::redraw();
            Glib::RefPtr<Gdk::Window> 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());
            }
        }


00178         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);

        }


00203         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;
        }


00234         void TextSwatch::on_action_copy(void)
        {
            LOG("Colorswatch on_action_copy");
            m_clipboardBuffer = m_background->get_hexstring();

            Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();

            //Targets:
            std::list<Gtk::TargetEntry> 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));
        }

00250         void TextSwatch::on_clipboard_get(Gtk::SelectionData& data, guint info)
        {
            if (data.get_target() == "UTF8_STRING")
            {
                data.set_text(m_clipboardBuffer);
            }
        }

00258         void TextSwatch::on_clipboard_clear(void)
        {}


        TextSwatch::SwatchText::SwatchText(Glib::RefPtr<Pango::Context> context,
                Glib::ustring txt)
            : m_refLayout(Pango::Layout::create(context))
            {
                m_refLayout->set_alignment(Pango::ALIGN_CENTER);
                set_text(txt);
            }

        TextSwatch::SwatchText::~SwatchText(void)
        { }

00273         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;
        }


00281         void TextSwatch::SwatchText::set_text(Glib::ustring text)
        {
            m_refLayout->set_text(text);
            update_extents();
        }

    } // namespace Widgets
} // namespace gcs

Generated by  Doxygen 1.6.0   Back to index