Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / thumbbrowserentrybase.cc
blob8e89dfaa7da92d0636c0a58ee0a2840087d54e0a
1 /*
2 * This file is part of RawTherapee.
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
19 #include <thumbbrowserentrybase.h>
20 #include <thumbbrowserbase.h>
21 #include <options.h>
22 #include <mytime.h>
24 ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname)
25 : filename(fname), selected(false), drawable(false),framed(false), processing(false),
26 italicstyle(false), preview(NULL), exifline(""), datetimeline(""),
27 buttonSet(NULL), updatepriority(false), redrawRequests(0),
28 parent(NULL), exp_width(0), exp_height(0) {
30 shortname = Glib::path_get_basename (fname);
31 dispname = shortname;
33 upperMargin = 6;
34 borderWidth = 1;
35 sideMargin = 8;
36 lowerMargin = 8;
37 textGap = 6;
39 ofsX = ofsY = 0;
42 ThumbBrowserEntryBase::~ThumbBrowserEntryBase () {
44 delete [] preview;
45 delete buttonSet;
48 void ThumbBrowserEntryBase::addButtonSet (LWButtonSet* bs) {
50 buttonSet = bs;
53 void ThumbBrowserEntryBase::updateBackBuffer () {
55 if (!parent)
56 return;
58 Gtk::Widget* w = parent->getDrawingArea ();
60 backBuffer = Gdk::Pixmap::create (w->get_window(), exp_width, exp_height);
62 bbSelected = selected;
63 bbFramed = framed;
64 bbPreview = preview;
66 Glib::RefPtr<Gdk::GC> gc_ = Gdk::GC::create (backBuffer);
68 Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL);
69 Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED);
70 Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL);
71 Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED);
73 // clear area, draw frames and background
74 gc_->set_foreground (bgn);
75 gc_->set_background (bgn);
76 backBuffer->draw_rectangle (gc_, true, 0, 0, exp_width, exp_height);
77 Cairo::RefPtr<Cairo::Context> cr = backBuffer->create_cairo_context();
78 drawFrame (cr, bgs, bgn);
80 // calculate height of button set
81 int bsHeight = 0;
82 if (buttonSet) {
83 int tmp;
84 buttonSet->getAllocatedDimensions (tmp, bsHeight);
87 // draw preview frame
88 backBuffer->draw_rectangle (gc_, false, (exp_width-prew)/2, upperMargin+bsHeight, prew+1, preh+1);
89 // draw thumbnail image
90 if (preview) {
91 prex = borderWidth + (exp_width-prew)/2;
92 prey = upperMargin+bsHeight+borderWidth;
93 backBuffer->draw_rgb_image (gc_, prex, prey, prew, preh, Gdk::RGB_DITHER_NONE, preview, prew*3);
96 customBackBufferUpdate (cr);
98 // draw icons onto the thumbnail area
99 bbIcons = getIconsOnImageArea ();
101 int infow, infoh;
102 getTextSizes (infow, infoh);
104 int iofs_x = 4, iofs_y = 4;
105 int igap = 2;
106 int istartx = prex;
107 int istarty = prey;
109 if (options.overlayedFileNames) {
110 cr->begin_new_path ();
111 cr->rectangle (istartx, istarty, prew, fnlabh+dtlabh+exlabh+2*iofs_y);
112 if ((texts.get_red_p()+texts.get_green_p()+texts.get_blue_p())/3 > 0.5)
113 cr->set_source_rgba (0, 0, 0, 0.5);
114 else
115 cr->set_source_rgba (1, 1, 1, 0.5);
116 cr->fill ();
119 istartx += iofs_x;
120 istarty += iofs_y;
122 if (bbIcons.size()>0) {
123 int iwidth = igap;
124 int iheight = 0;
125 for (int i=0; i<bbIcons.size(); i++) {
126 iwidth += bbIcons[i]->get_width() + igap;
127 if (bbIcons[i]->get_height() > iheight)
128 iheight = bbIcons[i]->get_height();
130 iheight += 2*igap;
131 if (!options.overlayedFileNames) {
132 cr->begin_new_path ();
133 cr->rectangle (istartx-igap, istarty-igap, iwidth, iheight);
134 cr->set_source_rgba (0, 0, 0, 0.75);
135 cr->fill ();
137 for (int i=0; i<bbIcons.size(); i++) {
138 backBuffer->draw_pixbuf (gc_, bbIcons[i], 0, 0, istartx, istarty, bbIcons[i]->get_width(), bbIcons[i]->get_height(), Gdk::RGB_DITHER_NONE, 0, 0);
139 istartx += bbIcons[i]->get_width() + igap;
143 int textposx_fn, textposx_ex, textposx_dt, textposy, textw;
144 if (!options.overlayedFileNames) {
145 textposx_fn = exp_width/2 - fnlabw/2;
146 if (textposx_fn<0) textposx_fn = 0;
147 textposx_ex = exp_width/2 - exlabw/2;
148 if (textposx_ex<0) textposx_ex = 0;
149 textposx_dt = exp_width/2 - dtlabw/2;
150 if (textposx_dt<0) textposx_dt = 0;
151 textposy = upperMargin + bsHeight + 2*borderWidth + preh + borderWidth + textGap;
152 textw = exp_width - 2*textGap;
153 gc_->set_foreground (selected ? texts : textn);
155 else {
156 textposx_fn = istartx;
157 textposx_ex = istartx;
158 textposx_dt = istartx;
159 textposy = istarty;
160 textw = prew - (istartx - prex);
161 gc_->set_foreground (texts);
164 // draw file name
165 Glib::RefPtr<Pango::Context> context = w->get_pango_context () ;
166 Pango::FontDescription fontd = context->get_font_description ();
167 fontd.set_weight (Pango::WEIGHT_BOLD);
168 if (italicstyle)
169 fontd.set_style (Pango::STYLE_ITALIC);
170 else
171 fontd.set_style (Pango::STYLE_NORMAL);
173 context->set_font_description (fontd);
174 Glib::RefPtr<Pango::Layout> fn = w->create_pango_layout (dispname);
175 fn->set_width (textw*Pango::SCALE);
176 fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
177 backBuffer->draw_layout(gc_, textposx_fn, textposy, fn);
179 fontd.set_weight (Pango::WEIGHT_NORMAL);
180 fontd.set_style (Pango::STYLE_NORMAL);
181 context->set_font_description (fontd);
183 // draw date/time label
184 int tpos = fnlabh;
185 if (options.fbShowDateTime && datetimeline!="") {
186 fn = w->create_pango_layout (datetimeline);
187 fn->set_width (textw*Pango::SCALE);
188 fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
189 backBuffer->draw_layout(gc_, textposx_dt, textposy + tpos, fn);
190 tpos += dtlabh;
192 // draw basic exif info
193 if (options.fbShowBasicExif && exifline!="") {
194 fn = w->create_pango_layout (exifline);
195 fn->set_width (textw*Pango::SCALE);
196 fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
197 backBuffer->draw_layout (gc_, textposx_ex, textposy + tpos, fn);
198 tpos += exlabh;
202 void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) {
204 if (!parent)
205 return;
207 Gtk::Widget* w = parent->getDrawingArea ();
209 // calculate dimensions of the text based fields
210 dispname = shortname;
212 Glib::RefPtr<Pango::Context> context = w->get_pango_context () ;
213 context->set_font_description (w->get_style()->get_font());
215 // filename:
216 Pango::FontDescription fontd = context->get_font_description ();
217 fontd.set_weight (Pango::WEIGHT_BOLD);
218 context->set_font_description (fontd);
219 Glib::RefPtr<Pango::Layout> fn = w->create_pango_layout(shortname);
220 fn->get_pixel_size (fnlabw, fnlabh);
222 // datetime
223 fontd.set_weight (Pango::WEIGHT_NORMAL);
224 context->set_font_description (fontd);
225 fn = w->create_pango_layout (datetimeline);
226 fn->get_pixel_size (dtlabw, dtlabh);
228 // basic exif data
229 fn = w->create_pango_layout (exifline);
230 fn->get_pixel_size (exlabw, exlabh);
232 // calculate cummulated height of all info fields
233 infoh = fnlabh;
234 infow = 0;
235 // add date/tile size:
236 if (options.fbShowDateTime) {
237 infoh += dtlabh;
238 if (dtlabw + 2*sideMargin > infow)
239 infow = dtlabw + 2*sideMargin;
241 if (options.fbShowBasicExif) {
242 infoh += exlabh;
243 if (exlabw + 2*sideMargin > infow)
244 infow = exlabw + 2*sideMargin;
248 void ThumbBrowserEntryBase::resize (int h) {
250 delete [] preview;
251 preview = NULL;
252 height = h;
254 // dimensions of the button set
255 int bsw=0, bsh=0;
256 if (buttonSet)
257 buttonSet->getMinimalDimensions (bsw, bsh);
259 // calculate the height remaining for the thumbnail image
260 preh = height - upperMargin - 2*borderWidth - lowerMargin - bsh;
261 int infow, infoh;
262 if (!options.overlayedFileNames) {
263 // dimensions of the info text
264 getTextSizes (infow, infoh);
265 preh -= infoh + textGap;
268 calcThumbnailSize ();
269 width = prew + 2*sideMargin + 2*borderWidth;
270 if (!options.overlayedFileNames) {
271 width = prew + 2*sideMargin + 2*borderWidth;
272 if (width<infow + 2*sideMargin + 2*borderWidth)
273 width = infow + 2*sideMargin + 2*borderWidth;
274 if (width < bsw + 2*sideMargin + 2*borderWidth)
275 width = bsw + 2*sideMargin + 2*borderWidth;
277 // updateBackBuffer ();
279 refreshThumbnailImage ();
280 drawable = true;
283 void ThumbBrowserEntryBase::drawFrame (Cairo::RefPtr<Cairo::Context> cr, const Gdk::Color& bg, const Gdk::Color& fg) {
285 int radius = 8;
286 if (selected || framed) {
287 cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
288 cr->move_to (radius, 0);
289 cr->arc (exp_width-1-radius, radius, radius, -M_PI/2, 0);
290 cr->arc (exp_width-1-radius, exp_height-1-radius, radius, 0, M_PI/2);
291 cr->arc (radius, exp_height-1-radius, radius, M_PI/2, M_PI);
292 cr->arc (radius, radius, radius, M_PI, -M_PI/2);
293 cr->close_path ();
294 if (selected) {
295 cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
296 cr->fill_preserve ();
298 cr->set_source_rgb (bg.get_red_p()*2/3, bg.get_green_p()*2/3, bg.get_blue_p()*2/3);
299 cr->set_line_width (1.0);
300 cr->stroke ();
304 if (framed) {
305 cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
306 cr->move_to (+2+0.5+radius, +2+0.5);
307 cr->arc (-2+0.5+exp_width-1-radius, +2+0.5+radius, radius, -M_PI/2, 0);
308 cr->arc (-2+0.5+exp_width-1-radius, -2+0.5+exp_height-1-radius, radius, 0, M_PI/2);
309 cr->arc (+2+0.5+radius, -2+exp_height-1-radius, radius, M_PI/2, M_PI);
310 cr->arc (+2+0.5+radius, +2+radius, radius, M_PI, -M_PI/2);
311 cr->close_path ();
312 cr->set_source_rgb (fg.get_red_p(), fg.get_green_p(), fg.get_blue_p());
313 cr->set_line_width (2.0);
314 cr->stroke ();
318 void ThumbBrowserEntryBase::draw () {
320 if (!drawable)
321 return;
323 int bbWidth, bbHeight;
324 if (backBuffer)
325 backBuffer->get_size (bbWidth, bbHeight);
328 if (!backBuffer || selected!=bbSelected || framed!=bbFramed || preview!=bbPreview
329 || exp_width!=bbWidth || exp_height!=bbHeight || getIconsOnImageArea ()!=bbIcons)
330 updateBackBuffer ();
332 if (!parent)
333 return;
335 Gtk::Widget* w = parent->getDrawingArea ();
337 Glib::RefPtr<Gdk::GC> gc_ = Gdk::GC::create (w->get_window());
339 Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL);
340 Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED);
341 Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL);
342 Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED);
344 w->get_window()->draw_drawable (gc_, backBuffer, 0, 0, startx + ofsX, starty + ofsY);
346 // check icon set changes!!!
348 // drawProgressBar (window, gc_, selected ? texts : textn, selected ? bgs : bgn, ofsX+startx, exp_width, ofsY+starty + upperMargin+bsHeight+borderWidth+preh+borderWidth+textGap+tpos, fnlabh);
350 // redraw button set above the thumbnail
351 if (buttonSet) {
352 buttonSet->setColors (selected ? bgs : bgn, selected ? bgn : bgs);
353 buttonSet->redraw (w->get_window()->create_cairo_context());
357 void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) {
359 exp_width = w;
360 exp_height = h;
361 startx = x;
362 starty = y;
364 if (buttonSet)
365 buttonSet->arrangeButtons (ofsX+x+sideMargin, ofsY+y+upperMargin, w-2*sideMargin, -1);
368 void ThumbBrowserEntryBase::setOffset (int x, int y) {
370 ofsX = -x;
371 ofsY = -y;
373 if (buttonSet)
374 buttonSet->move (ofsX+startx+sideMargin, ofsY+starty+upperMargin);
377 bool ThumbBrowserEntryBase::inside (int x, int y) {
379 return x>ofsX+startx && x<ofsX+startx+exp_width && y>ofsY+starty && y<ofsY+starty+exp_height;
382 bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) {
384 return !(ofsX+startx>x+w || ofsX+startx+exp_width<x || ofsY+starty>y+h || ofsY+starty+exp_height<y);
387 bool ThumbBrowserEntryBase::motionNotify (int x, int y) {
389 return buttonSet ? buttonSet->motionNotify (x, y) : false;
392 bool ThumbBrowserEntryBase::pressNotify (int button, int type, int bstate, int x, int y) {
394 return buttonSet ? buttonSet->pressNotify (x, y) : false;
397 bool ThumbBrowserEntryBase::releaseNotify (int button, int type, int bstate, int x, int y) {
399 return buttonSet ? buttonSet->releaseNotify (x, y) : false;
401 Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) {
403 return buttonSet ? buttonSet->getToolTip (x, y) : "";