X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcdragbox.C;fp=cinelerra-5.1%2Fguicast%2Fbcdragbox.C;h=10a39d968474b966febfcffde6b34d8a8a19232d;hp=0000000000000000000000000000000000000000;hb=b4017f68039ef7e31eedee4a27580a28bee36fc5;hpb=c4c898707e3fdbf2979b7bc43ac0e1b0fa779663 diff --git a/cinelerra-5.1/guicast/bcdragbox.C b/cinelerra-5.1/guicast/bcdragbox.C new file mode 100644 index 00000000..10a39d96 --- /dev/null +++ b/cinelerra-5.1/guicast/bcdragbox.C @@ -0,0 +1,148 @@ +#include "bcdragbox.h" +#include "bcmenuitem.h" +#include "bctimer.h" +#include "bcwindowbase.h" +#include "colors.h" + +BC_DragBox::BC_DragBox(BC_WindowBase *parent) + : Thread(1, 0, 0) +{ + this->parent = parent; + popup = 0; + done = -1; +} +BC_DragBox::~BC_DragBox() +{ + if( running() ) { + done = 1; + cancel(); + } + join(); + delete popup; +} + +void BC_DragBox::start_drag() +{ + popup = new BC_DragBoxPopup(this); + popup->lock_window("BC_DragBox::start"); + for( int i=0; i<4; ++i ) + edge[i] = new BC_Popup(parent, 0,0, 1,1, ORANGE, 1); + parent->grab_buttons(); + parent->grab_cursor(); + popup->grab(parent); + popup->create_objects(); + popup->show_window(); + popup->unlock_window(); + done = 0; + Thread::start(); +} + +void BC_DragBox::run() +{ + popup->lock_window("BC_DragBox::run 0"); + while( !done ) { + popup->update(); + popup->unlock_window(); + enable_cancel(); + Timer::delay(200); + disable_cancel(); + popup->lock_window("BC_DragBox::run 1"); + } + int x0 = popup->lx0, y0 = popup->ly0; + int x1 = popup->lx1, y1 = popup->ly1; + parent->ungrab_cursor(); + parent->ungrab_buttons(); + popup->ungrab(parent); + for( int i=0; i<4; ++i ) delete edge[i]; + popup->unlock_window(); + delete popup; popup = 0; + handle_done_event(x0, y0, x1, y1); +} + +BC_DragBoxPopup::BC_DragBoxPopup(BC_DragBox *grab_thread) + : BC_Popup(grab_thread->parent, 0,0, 16,16, -1,1) +{ + this->grab_thread = grab_thread; + dragging = -1; + grab_color = ORANGE; + x0 = y0 = x1 = y1 = -1; + lx0 = ly0 = lx1 = ly1 = -1; +} + +BC_DragBoxPopup::~BC_DragBoxPopup() +{ +} + +int BC_DragBoxPopup::grab_event(XEvent *event) +{ + int cur_drag = dragging; + switch( event->type ) { + case ButtonPress: { + if( cur_drag > 0 ) return 1; + int x0 = event->xbutton.x_root; + int y0 = event->xbutton.y_root; + if( !cur_drag ) { + draw_selection(-1); + if( event->xbutton.button == RIGHT_BUTTON ) break; + if( x0>=get_x() && x0=get_y() && y0x0 = this->x1 = x0; + this->y0 = this->y1 = y0; + draw_selection(1); + dragging = 1; + return 1; } + case ButtonRelease: + dragging = 0; + case MotionNotify: + if( cur_drag > 0 ) { + this->x1 = event->xbutton.x_root; + this->y1 = event->xbutton.y_root; + draw_selection(0); + } + return 1; + default: + return 0; + } + + hide_window(); + sync_display(); + grab_thread->done = 1; + return 1; +} + +void BC_DragBoxPopup::update() +{ + set_color(grab_color ^= GREEN); + draw_box(0,0, get_w(),get_h()); + flash(1); +} + +void BC_DragBoxPopup::draw_selection(int show) +{ + if( show < 0 ) { + for( int i=0; i<4; ++i ) hide_window(0); + flush(); + return; + } + + int nx0 = x0 < x1 ? x0 : x1; + int nx1 = x0 < x1 ? x1 : x0; + int ny0 = y0 < y1 ? y0 : y1; + int ny1 = y0 < y1 ? y1 : y0; + lx0 = nx0; lx1 = nx1; + ly0 = ny0; ly1 = ny1; + + --nx0; --ny0; + BC_Popup **edge = grab_thread->edge; + edge[0]->reposition_window(nx0,ny0, nx1-nx0, 1); + edge[1]->reposition_window(nx1,ny0, 1, ny1-ny0); + edge[2]->reposition_window(nx0,ny1, nx1-nx0, 1); + edge[3]->reposition_window(nx0,ny0, 1, ny1-ny0); + + if( show > 0 ) { + for( int i=0; i<4; ++i ) edge[i]->show_window(0); + } + flush(); +} +