move grab dragbox to guicast, add tile_mixers region to session/layout, change menu...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcdragbox.C
diff --git a/cinelerra-5.1/guicast/bcdragbox.C b/cinelerra-5.1/guicast/bcdragbox.C
new file mode 100644 (file)
index 0000000..10a39d9
--- /dev/null
@@ -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_x()+get_w() &&
+                           y0>=get_y() && y0<get_y()+get_h() ) break;
+               }
+               this->x0 = 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();
+}
+