2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published
4 * by the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public
13 * License along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 #include "automation.h"
22 #include "cwindowgui.h"
23 #include "dragcheckbox.h"
25 #include "edlsession.h"
31 DragCheckBox::DragCheckBox(MWindow *mwindow,
32 int x, int y, const char *text, int *value,
33 float drag_x, float drag_y, float drag_w, float drag_h)
34 : BC_CheckBox(x, y, value, text)
36 this->mwindow = mwindow;
37 this->drag_x = drag_x; this->drag_y = drag_y;
38 this->drag_w = drag_w; this->drag_h = drag_h;
39 drag_dx = drag_dy = 0;
45 DragCheckBox::~DragCheckBox()
50 int DragCheckBox::get_track_w()
52 Track *track = get_drag_track();
53 return track ? track->track_w : mwindow->edl->session->output_w;
55 int DragCheckBox::get_track_h()
57 Track *track = get_drag_track();
58 return track ? track->track_h : mwindow->edl->session->output_h;
61 void DragCheckBox::create_objects()
63 if( !drag_w ) drag_w = get_track_w();
64 if( !drag_h ) drag_h = get_track_h();
69 int DragCheckBox::handle_event()
71 int ret = BC_CheckBox::handle_event();
73 if( drag_activate() ) {
83 int DragCheckBox::drag_activate()
86 if( !grabbed && !(grabbed = grab(mwindow->cwindow->gui)) ) {
94 void DragCheckBox::drag_deactivate()
97 ungrab(mwindow->cwindow->gui);
104 int DragCheckBox::handle_ungrab()
112 int DragCheckBox::check_pending()
114 if( pending && !grab_event_count() ) {
121 int DragCheckBox::grab_event(XEvent *event)
123 switch( event->type ) {
124 case ButtonPress: break;
125 case ButtonRelease: break;
126 case MotionNotify: break;
128 return check_pending();
131 CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
132 CWindowCanvas *canvas = cwindow_gui->canvas;
133 int cx, cy; cwindow_gui->get_relative_cursor(cx, cy);
134 cx -= mwindow->theme->ccanvas_x;
135 cy -= mwindow->theme->ccanvas_y;
138 if( cx < 0 || cx >= mwindow->theme->ccanvas_w ||
139 cy < 0 || cy >= mwindow->theme->ccanvas_h )
140 return check_pending();
143 switch( event->type ) {
145 if( !dragging ) break;
148 if( !dragging ) return check_pending();
152 if( !dragging ) return check_pending();
155 return check_pending();
158 int track_w = get_track_w(), track_h = get_track_h();
159 if( !drag_w ) drag_w = track_w;
160 if( !drag_h ) drag_h = track_h;
162 int64_t position = get_drag_position();
163 float cursor_x = cx, cursor_y = cy;
164 canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
165 float projector_x, projector_y, projector_z;
166 Track *track = get_drag_track();
168 track->automation->get_projector(
169 &projector_x, &projector_y, &projector_z,
170 position, PLAY_FORWARD);
171 projector_x += mwindow->edl->session->output_w / 2;
172 projector_y += mwindow->edl->session->output_h / 2;
173 cursor_x = (cursor_x - projector_x) / projector_z + track_w / 2;
174 cursor_y = (cursor_y - projector_y) / projector_z + track_h / 2;
176 float r = MIN(track_w, track_h)/100.f + 2;
177 float x0 = drag_x, x1 = drag_x+(drag_w+1)/2, x2 = drag_x+drag_w;
178 float y0 = drag_y, y1 = drag_y+(drag_h+1)/2, y2 = drag_y+drag_h;
179 if( !dragging ) { // clockwise
180 if( fabs(drag_dx = cursor_x-x0) < r && // x0,y0
181 fabs(drag_dy = cursor_y-y0) < r ) dragging = 1;
182 else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y0
183 fabs(drag_dy = cursor_y-y0) < r ) dragging = 2;
184 else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y0
185 fabs(drag_dy = cursor_y-y0) < r ) dragging = 3;
186 else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y1
187 fabs(drag_dy = cursor_y-y1) < r ) dragging = 4;
188 else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y2
189 fabs(drag_dy = cursor_y-y2) < r ) dragging = 5;
190 else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y2
191 fabs(drag_dy = cursor_y-y2) < r ) dragging = 6;
192 else if( fabs(drag_dx = cursor_x-x0) < r && // x0,y2
193 fabs(drag_dy = cursor_y-y2) < r ) dragging = 7;
194 else if( fabs(drag_dx = cursor_x-x0) < r && // x0,y1
195 fabs(drag_dy = cursor_y-y1) < r ) dragging = 8;
196 else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y1
197 fabs(drag_dy = cursor_y-y1) < r ) dragging = 9;
202 int cur_x = cursor_x - drag_dx;
203 int cur_y = cursor_y - drag_dy;
206 float dx = cur_x - x0;
207 float dy = cur_y - y0;
208 if( !dx && !dy ) return 1;
209 if( (drag_w-=dx) < 1 ) drag_w = 1;
210 if( (drag_h-=dy) < 1 ) drag_h = 1;
211 drag_x = cur_x; drag_y = cur_y;
214 float dy = cur_y - y0;
217 if( (drag_h-=dy) < 1 ) drag_h = 1;
220 float dx = cur_x - x2;
221 float dy = cur_y - y0;
222 if( (drag_w+=dx) < 1 ) drag_w = 1;
223 if( (drag_h-=dy) < 1 ) drag_h = 1;
227 float dx = cur_x - x2;
229 if( (drag_w+=dx) < 1 ) drag_w = 1;
232 float dx = cur_x - x2;
233 float dy = cur_y - y2;
234 if( (drag_w+=dx) < 1 ) drag_w = 1;
235 if( (drag_h+=dy) < 1 ) drag_h = 1;
238 float dy = cur_y - y2;
240 if( (drag_h+=dy) < 1 ) drag_h = 1;
243 float dx = cur_x - x0;
244 float dy = cur_y - y2;
245 if( (drag_w-=dx) < 1 ) drag_w = 1;
246 if( (drag_h+=dy) < 1 ) drag_h = 1;
250 float dx = cur_x - x0;
252 if( (drag_w-=dx) < 1 ) drag_w = 1;
256 float dx = cur_x - x1;
257 float dy = cur_y - y1;
258 if( !dx && !dy ) return 1;
263 if( grab_event_count() )
265 else if( dragging ) {
273 void DragCheckBox::bound()
275 int trk_w = get_track_w(), trk_h = get_track_h();
276 float x1 = drag_x, x2 = x1 + drag_w;
277 float y1 = drag_y, y2 = y1 + drag_h;
278 bclamp(x1, 0, trk_w); bclamp(x2, 0, trk_w);
279 bclamp(y1, 0, trk_h); bclamp(y2, 0, trk_h);
280 if( x1 >= x2 ) { if( x2 > 0 ) x1 = x2-1; else x2 = (x1=0)+1; }
281 if( y1 >= y2 ) { if( x2 > 0 ) y1 = y2-1; else y2 = (y1=0)+1; }
282 drag_x = x1; drag_y = y1; drag_w = x2-x1; drag_h = y2-y1;
285 void DragCheckBox::draw_boundary(VFrame *out,
286 int x, int y, int w, int h)
288 int iw = out->get_w(), ih = out->get_h();
289 int mr = MIN(iw, ih)/200 + 2, rr = 2*mr;
291 int x0 = x-r2, x1 = x+(w+1)/2, x2 = x+w+r2;
292 int y0 = y-r2, y1 = y+(h+1)/2, y2 = y+h+r2;
294 for( int r=2; r<mr; r<<=1 ) st = r;
297 for( int r=mr/2; --r>=0; ) { // bbox
298 int lft = x+r, rgt = x+w-1-r;
299 int top = y+r, bot = y+h-1-r;
300 out->draw_line(lft,top, rgt,top);
301 out->draw_line(rgt,top, rgt,bot);
302 out->draw_line(rgt,bot, lft,bot);
303 out->draw_line(lft,bot, lft,top);
306 for( int r=mr; r<rr; ++r ) { // center
307 out->draw_smooth(x1-r,y1, x1-r,y1+r, x1,y1+r);
308 out->draw_smooth(x1,y1+r, x1+r,y1+r, x1+r,y1);
309 out->draw_smooth(x1+r,y1, x1+r,y1-r, x1,y1-r);
310 out->draw_smooth(x1,y1-r, x1-r,y1-r, x1-r,y1);
313 for( int r=rr; --r>=0; ) { // edge arrows
314 out->draw_line(x1-r,y0+r, x1+r,y0+r);
315 out->draw_line(x2-r,y1-r, x2-r,y1+r);
316 out->draw_line(x1-r,y2-r, x1+r,y2-r);
317 out->draw_line(x0+r,y1+r, x0+r,y1-r);
319 x0 += r2; y0 += r2; x2 -= r2; y2 -= r2;
320 for( int r=2*mr; --r>=0; ) { // corner arrows
321 out->draw_line(x0,y0+r, x0+r,y0);
322 out->draw_line(x2,y0+r, x2-r,y0);
323 out->draw_line(x2,y2-r, x2-r,y2);
324 out->draw_line(x0,y2-r, x0+r,y2);