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 <previewwindow.h>
21 #include <imagearea.h>
23 PreviewWindow::PreviewWindow () : previewHandler(NULL
), mainCropWin(NULL
), isMoving(false) {
25 rconn
= signal_size_allocate().connect( sigc::mem_fun(*this, &PreviewWindow::on_resized
) );
28 PreviewWindow::~PreviewWindow () {
36 void PreviewWindow::on_realize () {
38 Gtk::DrawingArea::on_realize ();
39 add_events(Gdk::EXPOSURE_MASK
| Gdk::POINTER_MOTION_MASK
| Gdk::BUTTON_PRESS_MASK
| Gdk::BUTTON_RELEASE_MASK
| Gdk::SCROLL_MASK
);
40 cCropMoving
= new Gdk::Cursor (Gdk::FLEUR
);
42 cNormal
= new Gdk::Cursor (Gdk::LAST_CURSOR
);
44 cNormal
= new Gdk::Cursor (Gdk::ARROW
);
48 void PreviewWindow::getObservedFrameArea (int& x
, int& y
, int& w
, int& h
) {
51 int cropX
, cropY
, cropW
, cropH
;
52 mainCropWin
->getCropRectangle (cropX
, cropY
, cropW
, cropH
);
53 // translate it to screen coordinates
54 x
= imgX
+ cropX
*zoom
;
55 y
= imgY
+ cropY
*zoom
;
61 void PreviewWindow::updatePreviewImage () {
63 int W
= get_width(), H
= get_height();
64 backBuffer
= Gdk::Pixmap::create (get_window(), W
, H
, -1);
65 backBuffer
->draw_rectangle (get_style()->get_base_gc(Gtk::STATE_NORMAL
), true, 0, 0, W
, H
);
67 Glib::RefPtr
<Gdk::Pixbuf
> resPixbuf
= previewHandler
->getRoughImage (W
, H
, zoom
);
69 imgW
= resPixbuf
->get_width();
70 imgH
= resPixbuf
->get_height();
73 backBuffer
->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL
), resPixbuf
, 0, 0, imgX
, imgY
, -1, -1, Gdk::RGB_DITHER_NONE
, 0, 0);
74 Cairo::RefPtr
<Cairo::Context
> cr
= backBuffer
->create_cairo_context();
75 if (previewHandler
->getCropParams().enabled
)
76 drawCrop (cr
, imgX
, imgY
, imgW
, imgH
, 0, 0, zoom
, previewHandler
->getCropParams());
81 void PreviewWindow::setPreviewHandler (PreviewHandler
* ph
) {
84 previewHandler
->addPreviewImageListener (this);
87 void PreviewWindow::on_resized (Gtk::Allocation
& req
) {
89 updatePreviewImage ();
93 bool PreviewWindow::on_expose_event (GdkEventExpose
* event
) {
96 Glib::RefPtr
<Gdk::Window
> window
= get_window();
99 backBuffer
->get_size (bufferW
, bufferH
);
102 mainCropWin
= imageArea
->getMainCropWindow ();
104 mainCropWin
->addCropWindowListener (this);
107 if (get_width()!=bufferW
&& get_height()!=bufferH
)
108 updatePreviewImage ();
110 window
->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL
), backBuffer
, 0, 0, 0, 0, -1, -1);
113 Cairo::RefPtr
<Cairo::Context
> cr
= get_window()->create_cairo_context();
115 getObservedFrameArea (x
, y
, w
, h
);
116 cr
->set_source_rgb (1.0, 1.0, 1.0);
117 cr
->set_line_width (3);
118 cr
->rectangle (x
-1.5, y
-1.5, w
+2, h
+2);
120 cr
->set_source_rgb (1.0, 0.0, 0.0);
121 cr
->set_line_width (1);
122 cr
->rectangle (x
-1.5, y
-1.5, w
+2, h
+2);
129 void PreviewWindow::previewImageChanged () {
131 updatePreviewImage ();
135 void PreviewWindow::setImageArea (ImageArea
* ia
) {
138 mainCropWin
= ia
->getMainCropWindow ();
140 mainCropWin
->addCropWindowListener (this);
143 void PreviewWindow::cropPositionChanged (CropWindow
* w
) {
148 void PreviewWindow::cropWindowSizeChanged (CropWindow
* w
) {
153 void PreviewWindow::cropZoomChanged (CropWindow
* w
) {
158 bool PreviewWindow::on_motion_notify_event (GdkEventMotion
* event
) {
164 getObservedFrameArea (x
, y
, w
, h
);
165 bool inside
= event
->x
> x
-6 && event
->x
< x
+w
-1+6 && event
->y
> y
-6 && event
->y
< y
+h
-1+6;
166 bool moreInside
= event
->x
> x
+6 && event
->x
< x
+w
-1-6 && event
->y
> y
+6 && event
->y
< y
+h
-1-6;
169 mainCropWin
->remoteMove ((event
->x
- press_x
)/zoom
, (event
->y
- press_y
)/zoom
);
170 else if (inside
&& !moreInside
)
171 get_window()->set_cursor (*cCropMoving
);
173 get_window()->set_cursor (*cNormal
);
177 bool PreviewWindow::on_button_press_event (GdkEventButton
* event
) {
183 getObservedFrameArea (x
, y
, w
, h
);
184 bool inside
= event
->x
> x
-6 && event
->x
< x
+w
-1+6 && event
->y
> y
-6 && event
->y
< y
+h
-1+6;
185 bool moreInside
= event
->x
> x
+6 && event
->x
< x
+w
-1-6 && event
->y
> y
+6 && event
->y
< y
+h
-1-6;
189 if (!inside
|| moreInside
) {
190 mainCropWin
->remoteMove ((event
->x
- (x
+w
/2))/zoom
, (event
->y
- (y
+h
/2))/zoom
);
198 get_window()->set_cursor (*cCropMoving
);
202 bool PreviewWindow::on_button_release_event (GdkEventButton
* event
) {
209 get_window()->set_cursor (*cNormal
);
210 mainCropWin
->remoteMoveReady ();