X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fdragcheckbox.C;fp=cinelerra-5.1%2Fcinelerra%2Fdragcheckbox.C;h=559851eb9a90754afef92c06c863f19f24008e53;hb=9a16c85641dee9f15136f40c8a3195d88d45513f;hp=0000000000000000000000000000000000000000;hpb=38781123230e8017af7b11621a78f63fa33a764e;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/dragcheckbox.C b/cinelerra-5.1/cinelerra/dragcheckbox.C new file mode 100644 index 00000000..559851eb --- /dev/null +++ b/cinelerra-5.1/cinelerra/dragcheckbox.C @@ -0,0 +1,276 @@ +#include "automation.h" +#include "bctoggle.h" +#include "canvas.h" +#include "cwindow.h" +#include "cwindowgui.h" +#include "dragcheckbox.h" +#include "edl.h" +#include "edlsession.h" +#include "mwindow.h" +#include "theme.h" +#include "track.h" +#include "vframe.h" + +DragCheckBox::DragCheckBox(MWindow *mwindow, + int x, int y, const char *text, int *value, + float drag_x, float drag_y, float drag_w, float drag_h) + : BC_CheckBox(x, y, value, text) +{ + this->mwindow = mwindow; + this->drag_x = drag_x; this->drag_y = drag_y; + this->drag_w = drag_w; this->drag_h = drag_h; + drag_dx = drag_dy = 0; + grabbed = 0; + dragging = 0; + pending = 0; +} + +DragCheckBox::~DragCheckBox() +{ + drag_deactivate(); +} + +void DragCheckBox::create_objects() +{ + if( !drag_w ) drag_w = get_drag_track()->track_w; + if( !drag_h ) drag_h = get_drag_track()->track_h; + if( get_value() ) + drag_activate(); +} + +int DragCheckBox::handle_event() +{ + int ret = BC_CheckBox::handle_event(); + if( get_value() ) { + if( drag_activate() ) { + update(*value=0); + flicker(10,50); + } + } + else + drag_deactivate(); + return ret; +} + +int DragCheckBox::drag_activate() +{ + int ret = 0; + if( !grabbed && !(grabbed = grab(mwindow->cwindow->gui)) ) { + ret = 1; + } + pending = 0; + dragging = 0; + return ret; +} + +void DragCheckBox::drag_deactivate() +{ + if( grabbed ) { + ungrab(mwindow->cwindow->gui); + grabbed = 0; + } + pending = 0; + dragging = 0; +} + +int DragCheckBox::check_pending() +{ + if( pending && !grab_event_count() ) { + pending = 0; + update_gui(); + } + return 0; +} + +int DragCheckBox::grab_event(XEvent *event) +{ + switch( event->type ) { + case ButtonPress: break; + case ButtonRelease: break; + case MotionNotify: break; + default: + return check_pending(); + } + + CWindowGUI *cwindow_gui = mwindow->cwindow->gui; + CWindowCanvas *canvas = cwindow_gui->canvas; + int cx, cy; cwindow_gui->get_relative_cursor(cx, cy); + cx -= mwindow->theme->ccanvas_x; + cy -= mwindow->theme->ccanvas_y; + + if( !dragging ) { + if( cx < 0 || cx >= mwindow->theme->ccanvas_w || + cy < 0 || cy >= mwindow->theme->ccanvas_h ) + return check_pending(); + } + + switch( event->type ) { + case ButtonPress: + if( !dragging ) break; + return 1; + case ButtonRelease: + if( !dragging ) return check_pending(); + dragging = 0; + return 1; + case MotionNotify: + if( !dragging ) return check_pending(); + break; + default: + return check_pending(); + } + + Track *track = get_drag_track(); + if( !track ) return 0; + if( !drag_w ) drag_w = track->track_w; + if( !drag_h ) drag_h = track->track_h; + + int64_t position = get_drag_position(); + + float cursor_x = cx, cursor_y = cy; + canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y); + float projector_x, projector_y, projector_z; + int track_w = track->track_w, track_h = track->track_h; + track->automation->get_projector( + &projector_x, &projector_y, &projector_z, + position, PLAY_FORWARD); + projector_x += mwindow->edl->session->output_w / 2; + projector_y += mwindow->edl->session->output_h / 2; + cursor_x = (cursor_x - projector_x) / projector_z + track_w / 2; + cursor_y = (cursor_y - projector_y) / projector_z + track_h / 2; + float r = MIN(track_w, track_h)/100.f + 2; + float x0 = drag_x, x1 = drag_x+(drag_w+1)/2, x2 = drag_x+drag_w; + float y0 = drag_y, y1 = drag_y+(drag_h+1)/2, y2 = drag_y+drag_h; + if( !dragging ) { // clockwise + if( fabs(drag_dx = cursor_x-x0) < r && // x0,y0 + fabs(drag_dy = cursor_y-y0) < r ) dragging = 1; + else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y0 + fabs(drag_dy = cursor_y-y0) < r ) dragging = 2; + else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y0 + fabs(drag_dy = cursor_y-y0) < r ) dragging = 3; + else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y1 + fabs(drag_dy = cursor_y-y1) < r ) dragging = 4; + else if( fabs(drag_dx = cursor_x-x2) < r && // x2,y2 + fabs(drag_dy = cursor_y-y2) < r ) dragging = 5; + else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y2 + fabs(drag_dy = cursor_y-y2) < r ) dragging = 6; + else if( fabs(drag_dx = cursor_x-x0) < r && // x0,y2 + fabs(drag_dy = cursor_y-y2) < r ) dragging = 7; + else if( fabs(drag_dx = cursor_x-x0) < r && // x0,y1 + fabs(drag_dy = cursor_y-y1) < r ) dragging = 8; + else if( fabs(drag_dx = cursor_x-x1) < r && // x1,y1 + fabs(drag_dy = cursor_y-y1) < r ) dragging = 9; + return 0; + } + int cur_x = cursor_x - drag_dx; + int cur_y = cursor_y - drag_dy; + switch( dragging ) { + case 1: { // x0,y0 + float dx = cur_x - x0; + float dy = cur_y - y0; + if( !dx && !dy ) return 1; + if( (drag_w-=dx) < 1 ) drag_w = 1; + if( (drag_h-=dy) < 1 ) drag_h = 1; + drag_x = cur_x; drag_y = cur_y; + break; } + case 2: { // x1,y0 + float dy = cur_y - y0; + if( !dy ) return 1; + drag_y = cur_y; + if( (drag_h-=dy) < 1 ) drag_h = 1; + break; } + case 3: { // x2,y0 + float dx = cur_x - x2; + float dy = cur_y - y0; + if( (drag_w+=dx) < 1 ) drag_w = 1; + if( (drag_h-=dy) < 1 ) drag_h = 1; + drag_y = cur_y; + break; } + case 4: { // x2,y1 + float dx = cur_x - x2; + if( !dx ) return 1; + if( (drag_w+=dx) < 1 ) drag_w = 1; + break; } + case 5: { // x2,y2 + float dx = cur_x - x2; + float dy = cur_y - y2; + if( (drag_w+=dx) < 1 ) drag_w = 1; + if( (drag_h+=dy) < 1 ) drag_h = 1; + break; } + case 6: { // x1,y2 + float dy = cur_y - y2; + if( !dy ) return 1; + if( (drag_h+=dy) < 1 ) drag_h = 1; + break; } + case 7: { // x0,y2 + float dx = cur_x - x0; + float dy = cur_y - y2; + if( (drag_w-=dx) < 1 ) drag_w = 1; + if( (drag_h+=dy) < 1 ) drag_h = 1; + drag_x = cur_x; + break; } + case 8: { // x0,y1 + float dx = cur_x - x0; + if( !dx ) return 1; + if( (drag_w-=dx) < 1 ) drag_w = 1; + drag_x = cur_x; + break; } + case 9: { // x1,y1 + float dx = cur_x - x1; + float dy = cur_y - y1; + if( !dx && !dy ) return 1; + drag_x += dx; + drag_y += dy; + } + } + if( grab_event_count() ) + pending = 1; + else if( dragging ) { + pending = 0; + update_gui(); + } + return 1; +} + +void DragCheckBox::draw_boundary(VFrame *out, + int x, int y, int w, int h) +{ + int iw = out->get_w(), ih = out->get_h(); + int mr = MIN(iw, ih)/200 + 2, rr = 2*mr; + int r2 = (rr+1)/2; + int x0 = x-r2, x1 = x+(w+1)/2, x2 = x+w+r2; + int y0 = y-r2, y1 = y+(h+1)/2, y2 = y+h+r2; + int st = 1; + for( int r=2; rset_stiple(st); + + for( int r=mr/2; --r>=0; ) { // bbox + int lft = x+r, rgt = x+w-1-r; + int top = y+r, bot = y+h-1-r; + out->draw_line(lft,top, rgt,top); + out->draw_line(rgt,top, rgt,bot); + out->draw_line(rgt,bot, lft,bot); + out->draw_line(lft,bot, lft,top); + } + + for( int r=mr; rdraw_smooth(x1-r,y1, x1-r,y1+r, x1,y1+r); + out->draw_smooth(x1,y1+r, x1+r,y1+r, x1+r,y1); + out->draw_smooth(x1+r,y1, x1+r,y1-r, x1,y1-r); + out->draw_smooth(x1,y1-r, x1-r,y1-r, x1-r,y1); + } + + for( int r=rr; --r>=0; ) { // edge arrows + out->draw_line(x1-r,y0+r, x1+r,y0+r); + out->draw_line(x2-r,y1-r, x2-r,y1+r); + out->draw_line(x1-r,y2-r, x1+r,y2-r); + out->draw_line(x0+r,y1+r, x0+r,y1-r); + } + x0 += r2; y0 += r2; x2 -= r2; y2 -= r2; + for( int r=2*mr; --r>=0; ) { // corner arrows + out->draw_line(x0,y0+r, x0+r,y0); + out->draw_line(x2,y0+r, x2-r,y0); + out->draw_line(x2,y2-r, x2-r,y2); + out->draw_line(x0,y2-r, x0+r,y2); + } +} +