Fawkes API Fawkes Development Version
twolines_cellrenderer.cpp
1
2/***************************************************************************
3 * twolines_cellrenderer.cpp - Gtk rell renderer for two lines of text
4 *
5 * Created: Sat Nov 29 16:36:41 2008
6 * Copyright 2008-2011 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <gui_utils/twolines_cellrenderer.h>
25
26#include <algorithm>
27#include <cstdio>
28#include <cstring>
29#include <glib-object.h>
30#include <gtkmm.h>
31
32namespace fawkes {
33
34/** @class TwoLinesCellRenderer <gui_utils/twolines_cellrenderer.h>
35 * Gtk cell renderer for two lines of text in a cell.
36 * This cell renderer allows you to have two lines of text in a single
37 * cell. It works by getting the text via two properties. The first line is
38 * the primary line and printed "normally". The second line is the secondary
39 * line and printed with a slightly smaller font.
40 * @author Tim Niemueller
41 */
42
43/** Constructor. */
45: Glib::ObjectBase(typeid(TwoLinesCellRenderer)),
46 Gtk::CellRenderer()
47#ifdef GLIBMM_PROPERTIES_ENABLED
48 ,
49 property_line1_(*this, "line1", ""),
50 property_line2_(*this, "line2", ""),
51 property_line2_enabled_(*this, "line2_enabled", true)
52#endif
53{
54}
55
56/** Destructor. */
58{
59}
60
61#ifdef GLIBMM_PROPERTIES_ENABLED
62/** Get property proxy for first line.
63 * @return property proxy for first line
64 */
65Glib::PropertyProxy<Glib::ustring>
66TwoLinesCellRenderer::property_line1()
67{
68 return property_line1_.get_proxy();
69}
70
71/** Get property proxy for second line.
72 * @return property proxy for second line
73 */
74Glib::PropertyProxy<Glib::ustring>
75TwoLinesCellRenderer::property_line2()
76{
77 return property_line2_.get_proxy();
78}
79
80/** Get property proxy that indicates whether the second line is enabled.
81 * @return property proxy that indicates whether the second line is enabled
82 */
83Glib::PropertyProxy<bool>
84TwoLinesCellRenderer::property_line2_enabled()
85{
86 return property_line2_enabled_.get_proxy();
87}
88#endif
89
90#if GTK_VERSION_GE(3, 0)
91/** Get required size for widget.
92 * @param widget widget to create Pango layouts from
93 * @param width upon return contains the required width
94 * @param height upon return contains the required height
95 */
96void
97TwoLinesCellRenderer::get_size(Gtk::Widget &widget, int *width, int *height) const
98#else
99/** Get required size for cell.
100 * @param widget widget
101 * @param cell_area area of the cell
102 * @param x_offset ignored
103 * @param y_offset ignored
104 * @param width upon return contains the required width of the cell
105 * @param height upon return contains the required height of the cell
106 */
107void
109 const Gdk::Rectangle *cell_area,
110 int * x_offset,
111 int * y_offset,
112 int * width,
113 int * height) const
114#endif
115{
116#ifdef GLIBMM_PROPERTIES_ENABLED
117 // Compute text width
118 Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(property_line1_);
119 Pango::Rectangle rect = layout_ptr->get_pixel_logical_extents();
120
121 int line1_width = property_xpad() * 2 + rect.get_width();
122 int line1_height = property_ypad() * 2 + rect.get_height();
123 int line2_height;
124
125 if (property_line2_enabled_.get_value()) {
126 Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(property_line2_);
127# if GTK_VERSION_GE(3, 0)
128 Pango::FontDescription font2("sans 10");
129# else
130 Glib::RefPtr<Gtk::Style> style = widget.get_style();
131 Pango::FontDescription font2 = style->get_font();
132# endif
133
134 font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size()));
135 layout2->set_font_description(font2);
136 Pango::Rectangle rect2 = layout2->get_pixel_logical_extents();
137 layout2->set_ellipsize(Pango::ELLIPSIZE_END);
138
139 line2_height = property_ypad() * 2 + rect2.get_height();
140 } else {
141 line2_height = 0;
142 }
143
144 if (width)
145 *width = line1_width;
146 if (height)
147 *height = line1_height + 4 + line2_height;
148#endif
149}
150
151#if GTK_VERSION_GE(3, 0)
152/** Get required size for cell.
153 * @param widget widget
154 * @param minimum_width upon return contains the required width of the cell
155 * @param natural_width upon return contains the required width of the cell
156 */
157void
158TwoLinesCellRenderer::get_preferred_width_vfunc(Gtk::Widget &widget,
159 int & minimum_width,
160 int & natural_width) const
161{
162 int width = 0;
163 get_size(widget, &width, NULL);
164 minimum_width = natural_width = width;
165}
166
167/** Get required size for cell.
168 * @param widget widget
169 * @param minimum_height upon return contains the required height of the cell
170 * @param natural_height upon return contains the required height of the cell
171 */
172void
173TwoLinesCellRenderer::get_preferred_height_vfunc(Gtk::Widget &widget,
174 int & minimum_height,
175 int & natural_height) const
176{
177 int height = 0;
178 get_size(widget, NULL, &height);
179 minimum_height = natural_height = height;
180}
181#endif
182
183#if GTK_VERSION_GE(3, 0)
184/** Render the cell.
185 * This is called to render the cell.
186 * @param cr graphic context to use for drawing
187 * @param widget widget
188 * @param background_area dimensions of the background area
189 * @param cell_area dimensions of the cell area
190 * @param flags render flags
191 */
192void
193TwoLinesCellRenderer::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr,
194 Gtk::Widget & widget,
195 const Gdk::Rectangle & background_area,
196 const Gdk::Rectangle & cell_area,
197 Gtk::CellRendererState flags)
198#else
199/** Render the cell.
200 * This is called to render the cell.
201 * @param window window
202 * @param widget widget
203 * @param background_area dimensions of the background area
204 * @param cell_area dimensions of the cell area
205 * @param expose_area dimensions of the exposed area
206 * @param flags render flags
207 */
208void
209TwoLinesCellRenderer::render_vfunc(const Glib::RefPtr<Gdk::Drawable> &window,
210 Gtk::Widget & widget,
211 const Gdk::Rectangle & background_area,
212 const Gdk::Rectangle & cell_area,
213 const Gdk::Rectangle & expose_area,
214 Gtk::CellRendererState flags)
215#endif
216{
217#ifdef GLIBMM_PROPERTIES_ENABLED
218 // Get cell size
219 int x_offset = 0, y_offset = 0;
220# if GTK_VERSION_LT(3, 0)
221 int width = 0, height = 0;
222 get_size(widget, cell_area, x_offset, y_offset, width, height);
223
224 // Get cell state
225 //Gtk::StateType state;
226 Gtk::StateType text_state;
227 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) {
228 //state = Gtk::STATE_SELECTED;
229 text_state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE;
230 } else {
231 //state = Gtk::STATE_NORMAL;
232 text_state = (widget.is_sensitive()) ? Gtk::STATE_NORMAL : Gtk::STATE_INSENSITIVE;
233 }
234
235 // Draw color text
236 Glib::RefPtr<Gdk::Window> win = Glib::RefPtr<Gdk::Window>::cast_dynamic(window);
237# endif
238 Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(property_line1_);
239 Pango::Rectangle rect1 = layout_ptr->get_pixel_logical_extents();
240# if GTK_VERSION_GE(3, 0)
241 Glib::RefPtr<Gtk::StyleContext> stylecontext = widget.get_style_context();
242 Gdk::RGBA c = stylecontext->get_color(Gtk::STATE_FLAG_NORMAL);
243
244 cr->set_source_rgba(c.get_red(), c.get_green(), c.get_blue(), c.get_alpha());
245 cr->move_to(cell_area.get_x() + x_offset + 2 * property_xpad(),
246 cell_area.get_y() + y_offset + 2 * property_ypad());
247 layout_ptr->show_in_cairo_context(cr);
248# else
249 widget.get_style()->paint_layout(win,
250 text_state,
251 true,
252 cell_area,
253 widget,
254 "cellrenderertext",
255 cell_area.get_x() + x_offset + 2 * property_xpad(),
256 cell_area.get_y() + y_offset + 2 * property_ypad(),
257 layout_ptr);
258# endif
259
260 if (property_line2_enabled_.get_value()) {
261 Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(property_line2_);
262# if GTK_VERSION_GE(3, 0)
263 Pango::FontDescription font2("sans 10");
264# else
265 Glib::RefPtr<Gtk::Style> style = widget.get_style();
266 Pango::FontDescription font2 = style->get_font();
267# endif
268 font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size()));
269 layout2->set_font_description(font2);
270 //Pango::Rectangle rect2 = layout2->get_pixel_logical_extents();
271 layout2->set_ellipsize(Pango::ELLIPSIZE_END);
272 layout2->set_width((cell_area.get_width() - property_xpad()) * Pango::SCALE);
273
274# if GTK_VERSION_GE(3, 0)
275 cr->move_to(cell_area.get_x() + x_offset + property_xpad(),
276 cell_area.get_y() + y_offset + property_ypad() + rect1.get_height() + 4);
277 layout2->show_in_cairo_context(cr);
278# else
279 widget.get_style()->paint_layout(win,
280 text_state,
281 true,
282 cell_area,
283 widget,
284 "cellrenderertext",
285 cell_area.get_x() + x_offset + property_xpad(),
286 cell_area.get_y() + y_offset + property_ypad()
287 + rect1.get_height() + 4,
288 layout2);
289# endif
290 }
291#endif
292}
293
294} // end namespace fawkes
Gtk cell renderer for two lines of text in a cell.
virtual void render_vfunc(const Glib::RefPtr< Gdk::Drawable > &window, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, const Gdk::Rectangle &expose_area, Gtk::CellRendererState flags)
Render the cell.
virtual void get_size_vfunc(Gtk::Widget &widget, const Gdk::Rectangle *cell_area, int *x_offset, int *y_offset, int *width, int *height) const
Get required size for cell.
virtual ~TwoLinesCellRenderer()
Destructor.
Fawkes library namespace.