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>
23 #include <multilangmgr.h>
25 #include <cropwindow.h>
27 ImageArea::ImageArea (ImageAreaPanel
* p
) : parent(p
) {
34 mainCropWindow
= NULL
;
35 previewHandler
= 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
) );
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
);
74 mainCropWindow
->setSize (get_width(), get_height());
78 void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor
* ipc_
) {
83 void ImageArea::setPreviewHandler (PreviewHandler
* ph
) {
89 ImageArea::~ImageArea () {
91 for (std::list
<CropWindow
*>::iterator i
=cropWins
.begin(); i
!=cropWins
.end(); i
++)
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
105 void ImageArea::setInfoText (Glib::ustring 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
);
116 ilayout
->get_pixel_size (iw
, ih
);
117 ipixbuf
= Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB
, true, 8, iw
+8, ih
+8);
121 void ImageArea::infoEnabled (bool e
) {
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
))
138 bool ImageArea::on_expose_event(GdkEventExpose
* event
) {
144 Glib::RefPtr
<Gdk::Window
> window
= get_window();
145 Cairo::RefPtr
<Cairo::Context
> cr
= get_window()->create_cairo_context();
148 mainCropWindow
->expose (cr
);
150 if (showInfo
==true && infotext
!="") {
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);
156 ilayout
->add_to_cairo_context (cr
);
160 for (std::list
<CropWindow
*>::reverse_iterator i
=cropWins
.rbegin(); i
!=cropWins
.rend(); i
++)
167 bool ImageArea::on_motion_notify_event (GdkEventMotion
* event
) {
170 focusGrabber
->pointerMoved (event
->x
, event
->y
);
172 CropWindow
* cw
= getCropWindow (event
->x
, event
->y
);
174 cw
->pointerMoved (event
->x
, event
->y
);
179 bool ImageArea::on_button_press_event (GdkEventButton
* event
) {
182 focusGrabber
->buttonPress (event
->button
, event
->type
, event
->state
, event
->x
, event
->y
);
184 CropWindow
* cw
= getCropWindow (event
->x
, event
->y
);
186 cw
->buttonPress (event
->button
, event
->type
, event
->state
, event
->x
, event
->y
);
191 bool ImageArea::on_scroll_event (GdkEventScroll
* event
) {
193 CropWindow
* cw
= getCropWindow (event
->x
, event
->y
);
195 if (event
->direction
==GDK_SCROLL_UP
)
204 bool ImageArea::on_button_release_event (GdkEventButton
* event
) {
207 focusGrabber
->buttonRelease (event
->button
, event
->type
, event
->state
, event
->x
, event
->y
);
209 CropWindow
* cw
= getCropWindow (event
->x
, event
->y
);
211 cw
->buttonRelease (event
->button
, event
->type
, event
->state
, event
->x
, event
->y
);
218 void ImageArea::grabFocus (CropWindow
* cw
) {
221 if (cw
&& cw
!=mainCropWindow
)
222 cropWindowSelected (cw
);
225 void ImageArea::unGrabFocus () {
230 void ImageArea::addCropWindow () {
232 CropWindow
* cw
= new CropWindow (this, ipc
);
233 cw
->setCropGUIListener (cropgl
);
234 cw
->setPointerMotionListener (pmlistener
);
235 cropWins
.push_front (cw
);
239 int hBorder
= get_width()/K
/8;
240 int vBorder
= get_height()/K
/8;
241 int N
= cropWins
.size()-1;
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);
250 cw
->setSize (lastClosedX
, lastClosedY
);
251 cw
->setPosition (lastClosedW
, lastClosedH
);
254 mainCropWindow
->setObservedCropWin (cropWins
.front());
259 void ImageArea::cropWindowSelected (CropWindow
* cw
) {
261 std::list
<CropWindow
*>::iterator i
= std::find (cropWins
.begin(), cropWins
.end(), cw
);
262 if (i
!=cropWins
.end())
264 cropWins
.push_front (cw
);
265 mainCropWindow
->setObservedCropWin (cropWins
.front());
268 void ImageArea::cropWindowClosed (CropWindow
* cw
) {
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())
277 if (!cropWins
.empty())
278 mainCropWindow
->setObservedCropWin (cropWins
.front());
280 mainCropWindow
->setObservedCropWin (NULL
);
284 void ImageArea::straightenReady (double rotDeg
) {
287 listener
->rotateSelectionReady (rotDeg
);
290 void ImageArea::spotWBSelected (int x
, int y
) {
293 listener
->spotWBselected (x
, y
);
296 void ImageArea::redraw () {
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
;
315 void ImageArea::getScrollPosition (int& x
, int& y
) {
317 if (mainCropWindow
) {
319 mainCropWindow
->getCropPosition (cropX
, cropY
);
320 x
= cropX
*mainCropWindow
->getZoom ();
321 y
= cropY
*mainCropWindow
->getZoom ();
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
) {
341 void ImageArea::cropWindowSizeChanged (CropWindow
* cw
) {
346 void ImageArea::cropZoomChanged (CropWindow
* cw
) {
348 if (cw
==mainCropWindow
) {
349 parent
->zoomChanged ();
351 zoomPanel
->refreshZoomLabel ();
355 double ImageArea::getZoom () {
358 return mainCropWindow
->getZoom ();
363 void ImageArea::setZoom (double zoom
) {
366 mainCropWindow
->setZoom (zoom
);
367 zoomPanel
->refreshZoomLabel ();
370 void ImageArea::initialImageArrived (CropWindow
* cw
) {
373 mainCropWindow
->zoomFit ();
376 void ImageArea::updateScrollbars () {
377 parent
->refreshScrollBars ();
380 void ImageArea::setCropGUIListener (CropGUIListener
* l
) {
383 for (std::list
<CropWindow
*>::iterator i
=cropWins
.begin(); i
!=cropWins
.end(); i
++)
384 (*i
)->setCropGUIListener (cropgl
);
386 mainCropWindow
->setCropGUIListener (cropgl
);
389 void ImageArea::setPointerMotionListener (PointerMotionListener
* pml
) {
392 for (std::list
<CropWindow
*>::iterator i
=cropWins
.begin(); i
!=cropWins
.end(); i
++)
393 (*i
)->setPointerMotionListener (pml
);
395 mainCropWindow
->setPointerMotionListener (pml
);
398 ToolMode
ImageArea::getToolMode () {
401 return listener
->getToolBar()->getTool ();
406 void ImageArea::setToolHand () {
409 listener
->getToolBar()->setTool (TMHand
);
412 int ImageArea::getSpotWBRectSize () {
415 return listener
->getSpotWBRectSize ();