Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / imagearea.cc
blob8fbeeeda6738afdec71f8cbe53b93e29f560a3d6
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 <imagearea.h>
20 #include <time.h>
21 #include <math.h>
22 #include <options.h>
23 #include <multilangmgr.h>
24 #include <iomanip>
25 #include <cropwindow.h>
27 ImageArea::ImageArea (ImageAreaPanel* p) : parent(p) {
29 showInfo = false;
30 infotext = "";
31 cropgl = NULL;
32 pmlistener = NULL;
33 focusGrabber = NULL;
34 mainCropWindow = NULL;
35 previewHandler = NULL;
36 lastClosedX = -1;
37 showClippedH = false;
38 showClippedS = false;
39 listener = NULL;
41 zoomPanel = Gtk::manage (new ZoomPanel (this));
42 indClippedPanel = Gtk::manage (new IndicateClippedPanel (this));
44 signal_style_changed().connect( sigc::mem_fun(*this, &ImageArea::styleChanged) );
45 signal_size_allocate().connect( sigc::mem_fun(*this, &ImageArea::on_resized) );
47 dirty = false;
50 void ImageArea::on_realize()
52 Gtk::DrawingArea::on_realize();
54 add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
56 Cairo::FontOptions cfo;
57 cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
58 get_pango_context ()->set_cairo_font_options (cfo);
61 void ImageArea::on_resized (Gtk::Allocation& req) {
63 if (ipc && !mainCropWindow) {
64 mainCropWindow = new CropWindow (this, ipc);
65 mainCropWindow->setDecorated (false);
66 mainCropWindow->setFitZoomEnabled (true);
67 mainCropWindow->setPosition (0, 0);
68 mainCropWindow->setSize (get_width(), get_height());
69 mainCropWindow->addCropWindowListener (this);
70 mainCropWindow->setCropGUIListener (cropgl);
71 mainCropWindow->setPointerMotionListener (pmlistener);
73 else if (ipc) {
74 mainCropWindow->setSize (get_width(), get_height());
78 void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) {
80 ipc = ipc_;
83 void ImageArea::setPreviewHandler (PreviewHandler* ph) {
85 previewHandler = ph;
89 ImageArea::~ImageArea () {
91 for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
92 delete *i;
93 cropWins.clear ();
95 if (mainCropWindow)
96 delete mainCropWindow;
99 void ImageArea::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
101 // TODO: notify all crop windows that the style has been changed
102 queue_draw ();
105 void ImageArea::setInfoText (Glib::ustring text) {
107 infotext = text;
109 Glib::RefPtr<Pango::Context> context = get_pango_context () ;
110 Pango::FontDescription fontd = context->get_font_description ();
111 fontd.set_weight (Pango::WEIGHT_BOLD);
112 fontd.set_size (12*Pango::SCALE);
113 context->set_font_description (fontd);
114 ilayout = create_pango_layout(text);
115 int iw, ih;
116 ilayout->get_pixel_size (iw, ih);
117 ipixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, true, 8, iw+8, ih+8);
118 ipixbuf->fill (128);
121 void ImageArea::infoEnabled (bool e) {
123 if (showInfo!=e) {
124 showInfo = e;
125 queue_draw ();
129 CropWindow* ImageArea::getCropWindow (int x, int y) {
131 CropWindow* cw = mainCropWindow;
132 for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
133 if ((*i)->isInside (x, y))
134 return *i;
135 return cw;
138 bool ImageArea::on_expose_event(GdkEventExpose* event) {
139 dirty = false;
141 if (event->count)
142 return true;
144 Glib::RefPtr<Gdk::Window> window = get_window();
145 Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
147 if (mainCropWindow)
148 mainCropWindow->expose (cr);
150 if (showInfo==true && infotext!="") {
151 int fnw, fnh;
152 ilayout->get_pixel_size (fnw, fnh);
153 window->draw_pixbuf (get_style()->get_base_gc (Gtk::STATE_NORMAL), ipixbuf, 0, 0, 4, 4, fnw+8, fnh+8, Gdk::RGB_DITHER_NONE, 0, 0);
154 cr->set_source_rgb (1.0, 1.0, 1.0);
155 cr->move_to (8, 8);
156 ilayout->add_to_cairo_context (cr);
157 cr->fill ();
160 for (std::list<CropWindow*>::reverse_iterator i=cropWins.rbegin(); i!=cropWins.rend(); i++)
161 (*i)->expose (cr);
163 return true;
167 bool ImageArea::on_motion_notify_event (GdkEventMotion* event) {
169 if (focusGrabber)
170 focusGrabber->pointerMoved (event->x, event->y);
171 else {
172 CropWindow* cw = getCropWindow (event->x, event->y);
173 if (cw)
174 cw->pointerMoved (event->x, event->y);
176 return true;
179 bool ImageArea::on_button_press_event (GdkEventButton* event) {
181 if (focusGrabber)
182 focusGrabber->buttonPress (event->button, event->type, event->state, event->x, event->y);
183 else {
184 CropWindow* cw = getCropWindow (event->x, event->y);
185 if (cw)
186 cw->buttonPress (event->button, event->type, event->state, event->x, event->y);
188 return true;
191 bool ImageArea::on_scroll_event (GdkEventScroll* event) {
193 CropWindow* cw = getCropWindow (event->x, event->y);
194 if (cw) {
195 if (event->direction==GDK_SCROLL_UP)
196 cw->zoomIn ();
197 else
198 cw->zoomOut ();
199 return true;
201 return true;
204 bool ImageArea::on_button_release_event (GdkEventButton* event) {
206 if (focusGrabber)
207 focusGrabber->buttonRelease (event->button, event->type, event->state, event->x, event->y);
208 else {
209 CropWindow* cw = getCropWindow (event->x, event->y);
210 if (cw) {
211 cw->buttonRelease (event->button, event->type, event->state, event->x, event->y);
214 return true;
218 void ImageArea::grabFocus (CropWindow* cw) {
220 focusGrabber = cw;
221 if (cw && cw!=mainCropWindow)
222 cropWindowSelected (cw);
225 void ImageArea::unGrabFocus () {
227 focusGrabber = NULL;
230 void ImageArea::addCropWindow () {
232 CropWindow* cw = new CropWindow (this, ipc);
233 cw->setCropGUIListener (cropgl);
234 cw->setPointerMotionListener (pmlistener);
235 cropWins.push_front (cw);
237 if (lastClosedX<0) {
238 int K = 2;
239 int hBorder = get_width()/K/8;
240 int vBorder = get_height()/K/8;
241 int N = cropWins.size()-1;
242 int layer = N/K/K;
243 int row = K-1 - (N % (K*K)) / K;
244 int col = K-1 - (N % (K*K)) % K;
246 cw->setSize (get_width()/K - hBorder, get_height()/K - vBorder);
247 cw->setPosition (col*get_width()/K + hBorder/2 + layer*30, row*get_height()/K + vBorder/2 + layer*30);
249 else {
250 cw->setSize (lastClosedX, lastClosedY);
251 cw->setPosition (lastClosedW, lastClosedH);
254 mainCropWindow->setObservedCropWin (cropWins.front());
255 queue_draw ();
259 void ImageArea::cropWindowSelected (CropWindow* cw) {
261 std::list<CropWindow*>::iterator i = std::find (cropWins.begin(), cropWins.end(), cw);
262 if (i!=cropWins.end())
263 cropWins.erase (i);
264 cropWins.push_front (cw);
265 mainCropWindow->setObservedCropWin (cropWins.front());
268 void ImageArea::cropWindowClosed (CropWindow* cw) {
270 focusGrabber = NULL;
271 cw->getPosition (lastClosedX, lastClosedY);
272 cw->getSize (lastClosedW, lastClosedH);
273 std::list<CropWindow*>::iterator i = std::find (cropWins.begin(), cropWins.end(), cw);
274 if (i!=cropWins.end())
275 cropWins.erase (i);
276 delete cw;
277 if (!cropWins.empty())
278 mainCropWindow->setObservedCropWin (cropWins.front());
279 else
280 mainCropWindow->setObservedCropWin (NULL);
281 queue_draw ();
284 void ImageArea::straightenReady (double rotDeg) {
286 if (listener)
287 listener->rotateSelectionReady (rotDeg);
290 void ImageArea::spotWBSelected (int x, int y) {
292 if (listener)
293 listener->spotWBselected (x, y);
296 void ImageArea::redraw () {
298 if (!dirty) {
299 dirty = true;
300 queue_draw ();
304 void ImageArea::getScrollImageSize (int& w, int& h) {
306 if (mainCropWindow && ipc) {
307 double z = mainCropWindow->getZoom ();
308 w = ipc->getFullWidth() * z;
309 h = ipc->getFullHeight() * z;
311 else
312 w = h = 0;
315 void ImageArea::getScrollPosition (int& x, int& y) {
317 if (mainCropWindow) {
318 int cropX, cropY;
319 mainCropWindow->getCropPosition (cropX, cropY);
320 x = cropX*mainCropWindow->getZoom ();
321 y = cropY*mainCropWindow->getZoom ();
323 else
324 x = y = 0;
327 void ImageArea::setScrollPosition (int x, int y) {
329 if (mainCropWindow) {
330 mainCropWindow->delCropWindowListener (this);
331 mainCropWindow->setCropPosition (x/mainCropWindow->getZoom (), y/mainCropWindow->getZoom ());
332 mainCropWindow->addCropWindowListener (this);
336 void ImageArea::cropPositionChanged (CropWindow* cw) {
338 updateScrollbars ();
341 void ImageArea::cropWindowSizeChanged (CropWindow* cw) {
343 updateScrollbars ();
346 void ImageArea::cropZoomChanged (CropWindow* cw) {
348 if (cw==mainCropWindow) {
349 parent->zoomChanged ();
350 updateScrollbars ();
351 zoomPanel->refreshZoomLabel ();
355 double ImageArea::getZoom () {
357 if (mainCropWindow)
358 return mainCropWindow->getZoom ();
359 else
360 return 1.0;
363 void ImageArea::setZoom (double zoom) {
365 if (mainCropWindow)
366 mainCropWindow->setZoom (zoom);
367 zoomPanel->refreshZoomLabel ();
370 void ImageArea::initialImageArrived (CropWindow* cw) {
372 if (mainCropWindow)
373 mainCropWindow->zoomFit ();
376 void ImageArea::updateScrollbars () {
377 parent->refreshScrollBars ();
380 void ImageArea::setCropGUIListener (CropGUIListener* l) {
382 cropgl = l;
383 for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
384 (*i)->setCropGUIListener (cropgl);
385 if (mainCropWindow)
386 mainCropWindow->setCropGUIListener (cropgl);
389 void ImageArea::setPointerMotionListener (PointerMotionListener* pml) {
391 pmlistener = pml;
392 for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
393 (*i)->setPointerMotionListener (pml);
394 if (mainCropWindow)
395 mainCropWindow->setPointerMotionListener (pml);
398 ToolMode ImageArea::getToolMode () {
400 if (listener)
401 return listener->getToolBar()->getTool ();
402 else
403 return TMHand;
406 void ImageArea::setToolHand () {
408 if (listener)
409 listener->getToolBar()->setTool (TMHand);
412 int ImageArea::getSpotWBRectSize () {
414 if (listener)
415 return listener->getSpotWBRectSize ();
416 else
417 return 1;