#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(); }