twolines_cellrenderer.cpp

00001
00002 /***************************************************************************
00003  *  twolines_cellrenderer.cpp - Gtk rell renderer for two lines of text
00004  *
00005  *  Created: Sat Nov 29 16:36:41 2008
00006  *  Copyright  2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <gui_utils/twolines_cellrenderer.h>
00025
00026 #include <gtkmm.h>
00027 #include <gtk/gtkcellrenderer.h>
00028 #include <glib-object.h>
00029
00030 #include <algorithm>
00031 #include <cstring>
00032 #include <cstdio>
00033
00034 namespace fawkes {
00035 #if 0 /* just to make Emacs auto-indent happy */
00036 }
00037 #endif
00038 
00039 /** @class TwoLinesCellRenderer <gui_utils/twolines_cellrenderer.h>
00040  * Gtk cell renderer for two lines of text in a cell.
00041  * This cell renderer allows you to have two lines of text in a single
00042  * cell. It works by getting the text via two properties. The first line is
00043  * the primary line and printed "normally". The second line is the secondary
00044  * line and printed with a slightly smaller font.
00045  * @author Tim Niemueller
00046  */
00047 
00048 /** Constructor. */
00049 TwoLinesCellRenderer::TwoLinesCellRenderer()
00050   : Glib::ObjectBase(typeid(TwoLinesCellRenderer)),
00051     Gtk::CellRenderer(),
00052     __property_line1(*this, "line1", ""),
00053     __property_line2(*this, "line2", "")
00054 {
00055 }
00056 
00057 /** Destructor. */
00058 TwoLinesCellRenderer::~TwoLinesCellRenderer()
00059 {
00060 }
00061 
00062 /** Get property proxy for first line.
00063  * @return property proxy for first line
00064  */
00065 Glib::PropertyProxy<Glib::ustring>
00066 TwoLinesCellRenderer::property_line1()
00067 {
00068   return __property_line1.get_proxy();
00069 }
00070
00071 
00072 /** Get property proxy for second line.
00073  * @return property proxy for second line
00074  */
00075 Glib::PropertyProxy<Glib::ustring>
00076 TwoLinesCellRenderer::property_line2()
00077 {
00078   return __property_line2.get_proxy();
00079 }
00080
00081 
00082 /** Get required size for cell.
00083  * @param widget widget
00084  * @param cell_area area of the cell
00085  * @param x_offset ignored
00086  * @param y_offset ignored
00087  * @param width upon return contains the required width of the cell
00088  * @param height upon return contains the required height of the cell
00089  */
00090 void
00091 TwoLinesCellRenderer::get_size_vfunc(Gtk::Widget &widget,
00092                                      const Gdk::Rectangle *cell_area,
00093                                      int *x_offset, int *y_offset,
00094                                      int *width, int *height) const
00095 {
00096   // Compute text width
00097   Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(__property_line1);
00098   Pango::Rectangle rect = layout_ptr->get_pixel_logical_extents();
00099
00100   int line1_width  = property_xpad() * 2 + rect.get_width();
00101   int line1_height = property_ypad() * 2 + rect.get_height();
00102
00103   Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(__property_line2);
00104   Glib::RefPtr<Gtk::Style> style = widget.get_style();
00105   Pango::FontDescription font2 = style->get_font();
00106   font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size()));
00107   layout2->set_font_description(font2);
00108   Pango::Rectangle rect2 = layout2->get_pixel_logical_extents();
00109   layout2->set_ellipsize(Pango::ELLIPSIZE_END);
00110
00111   int line2_height = property_ypad() * 2 + rect2.get_height();
00112
00113   if ( width )  *width  = line1_width;
00114   if ( height ) *height = line1_height + 4 + line2_height;
00115 }
00116
00117 
00118 /** Render the cell.
00119  * This is called to render the cell.
00120  * @param window window
00121  * @param widget widget
00122  * @param background_area dimensions of the background area
00123  * @param cell_area dimensions of the cell area
00124  * @param expose_area dimensions of the exposed area
00125  * @param flags render flags
00126  */
00127 void
00128 TwoLinesCellRenderer::render_vfunc(const Glib::RefPtr<Gdk::Drawable> &window,
00129                                    Gtk::Widget &widget,
00130                                    const Gdk::Rectangle &background_area,
00131                                    const Gdk::Rectangle &cell_area,
00132                                    const Gdk::Rectangle &expose_area,
00133                                    Gtk::CellRendererState flags)
00134 {
00135   // Get cell size
00136   int x_offset = 0, y_offset = 0, width = 0, height = 0;
00137   get_size(widget, cell_area, x_offset, y_offset, width, height);
00138
00139   // Create the graphic context
00140   Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create(window);
00141
00142   // Get cell state
00143   Gtk::StateType state;
00144   Gtk::StateType text_state;
00145   if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) {
00146     state = Gtk::STATE_SELECTED;
00147     text_state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE;
00148   } else {
00149     state = Gtk::STATE_NORMAL;
00150     text_state = (widget.is_sensitive()) ? Gtk::STATE_NORMAL : Gtk::STATE_INSENSITIVE;
00151   }
00152
00153   // Draw color text
00154   Glib::RefPtr<Gdk::Window> win = Glib::RefPtr<Gdk::Window>::cast_dynamic(window);
00155   Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(__property_line1);
00156   Pango::Rectangle rect1 = layout_ptr->get_pixel_logical_extents();
00157   widget.get_style()->paint_layout (win, text_state, true, cell_area,
00158                                     widget, "cellrenderertext",
00159                                     cell_area.get_x() + x_offset + 2 * property_xpad(),
00160                                     cell_area.get_y() + y_offset + 2 * property_ypad(),
00161                                     layout_ptr);
00162
00163   Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(__property_line2);
00164   Glib::RefPtr<Gtk::Style> style = widget.get_style();
00165   Pango::FontDescription font2 = style->get_font();
00166   font2.set_size((int)roundf(Pango::SCALE_SMALL * std::max(font2.get_size(), 8)));
00167   layout2->set_font_description(font2);
00168   Pango::Rectangle rect2 = layout2->get_pixel_logical_extents();
00169   layout2->set_ellipsize(Pango::ELLIPSIZE_END);
00170   layout2->set_width((cell_area.get_width() - property_xpad()) * Pango::SCALE);
00171   widget.get_style()->paint_layout (win, text_state, true, cell_area,
00172                                     widget, "cellrenderertext",
00173                                     cell_area.get_x() + x_offset + property_xpad(),
00174                                     cell_area.get_y() + y_offset + property_ypad() + rect1.get_height() + 4,
00175                                     layout2);
00176 }
00177
00178
00179 } // end namespace fawkes