version update
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcdragbox.C
1 #include "bcdragbox.h"
2 #include "bcmenuitem.h"
3 #include "bctimer.h"
4 #include "bcwindowbase.h"
5 #include "colors.h"
6
7 BC_DragBox::BC_DragBox(BC_WindowBase *parent)
8  : Thread(1, 0, 0)
9 {
10         this->parent = parent;
11         popup = 0;
12         done = -1;
13 }
14 BC_DragBox::~BC_DragBox()
15 {
16         if( running() ) {
17                 done = 1;
18                 cancel();
19         }
20         join();
21         delete popup;
22 }
23
24 void BC_DragBox::start_drag()
25 {
26         popup = new BC_DragBoxPopup(this);
27         popup->lock_window("BC_DragBox::start");
28         for( int i=0; i<4; ++i )
29                 edge[i] = new BC_Popup(parent, 0,0, 1,1, ORANGE, 1);
30         parent->grab_buttons();
31         parent->grab_cursor();
32         popup->grab(parent);
33         popup->create_objects();
34         popup->show_window();
35         popup->unlock_window();
36         done = 0;
37         Thread::start();
38 }
39
40 void BC_DragBox::run()
41 {
42         popup->lock_window("BC_DragBox::run 0");
43         while( !done ) {
44                 popup->update();
45                 popup->unlock_window();
46                 enable_cancel();
47                 Timer::delay(200);
48                 disable_cancel();
49                 popup->lock_window("BC_DragBox::run 1");
50         }
51         int x0 = popup->lx0, y0 = popup->ly0;
52         int x1 = popup->lx1, y1 = popup->ly1;
53         parent->ungrab_cursor();
54         parent->ungrab_buttons();
55         popup->ungrab(parent);
56         for( int i=0; i<4; ++i ) delete edge[i];
57         popup->unlock_window();
58         delete popup;  popup = 0;
59         handle_done_event(x0, y0, x1, y1);
60 }
61
62 BC_DragBoxPopup::BC_DragBoxPopup(BC_DragBox *grab_thread)
63  : BC_Popup(grab_thread->parent, 0,0, 16,16, -1,1)
64 {
65         this->grab_thread = grab_thread;
66         dragging = -1;
67         grab_color = ORANGE;
68         x0 = y0 = x1 = y1 = -1;
69         lx0 = ly0 = lx1 = ly1 = -1;
70 }
71
72 BC_DragBoxPopup::~BC_DragBoxPopup()
73 {
74 }
75
76 int BC_DragBoxPopup::grab_event(XEvent *event)
77 {
78         int cur_drag = dragging;
79         switch( event->type ) {
80         case ButtonPress: {
81                 if( cur_drag > 0 ) return 1;
82                 int x0 = event->xbutton.x_root;
83                 int y0 = event->xbutton.y_root;
84                 if( !cur_drag ) {
85                         draw_selection(-1);
86                         if( event->xbutton.button == RIGHT_BUTTON ) break;
87                         if( x0>=get_x() && x0<get_x()+get_w() &&
88                             y0>=get_y() && y0<get_y()+get_h() ) break;
89                 }
90                 this->x0 = this->x1 = x0;
91                 this->y0 = this->y1 = y0;
92                 draw_selection(1);
93                 dragging = 1;
94                 return 1; }
95         case ButtonRelease:
96                 dragging = 0;
97         case MotionNotify:
98                 if( cur_drag > 0 ) {
99                         this->x1 = event->xbutton.x_root;
100                         this->y1 = event->xbutton.y_root;
101                         draw_selection(0);
102                 }
103                 return 1;
104         default:
105                 return 0;
106         }
107
108         hide_window();
109         sync_display();
110         grab_thread->done = 1;
111         return 1;
112 }
113
114 void BC_DragBoxPopup::update()
115 {
116         set_color(grab_color ^= GREEN);
117         draw_box(0,0, get_w(),get_h());
118         flash(1);
119 }
120
121 void BC_DragBoxPopup::draw_selection(int show)
122 {
123         if( show < 0 ) {
124                 for( int i=0; i<4; ++i ) hide_window(0);
125                 flush();
126                 return;
127         }
128
129         int nx0 = x0 < x1 ? x0 : x1;
130         int nx1 = x0 < x1 ? x1 : x0;
131         int ny0 = y0 < y1 ? y0 : y1;
132         int ny1 = y0 < y1 ? y1 : y0;
133         lx0 = nx0;  lx1 = nx1;
134         ly0 = ny0;  ly1 = ny1;
135
136         --nx0;  --ny0;
137         BC_Popup **edge = grab_thread->edge;
138         edge[0]->reposition_window(nx0,ny0, nx1-nx0, 1);
139         edge[1]->reposition_window(nx1,ny0, 1, ny1-ny0);
140         edge[2]->reposition_window(nx0,ny1, nx1-nx0, 1);
141         edge[3]->reposition_window(nx0,ny0, 1, ny1-ny0);
142
143         if( show > 0 ) {
144                 for( int i=0; i<4; ++i ) edge[i]->show_window(0);
145         }
146         flush();
147 }
148