initial commit
[goodguy/history.git] / cinelerra-5.0 / guicast / bcdragwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "bcdragwindow.h"
23 #include "bcpixmap.h"
24
25 #include "vframe.h"
26 #include <unistd.h>
27
28 // Icon has to be offset so the cursor isn't directly over it.
29 // The cursor has to be over the target window for X to detect the right window.
30 #define DRAG_OFFSET_X 16
31 #define DRAG_OFFSET_Y 16
32
33 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window, 
34         BC_Pixmap *pixmap /*, 
35         int icon_x, 
36         int icon_y */)
37  : BC_Popup(parent_window, 
38 //      icon_x, 
39 //      icon_y,
40         parent_window->get_abs_cursor_x(0) + DRAG_OFFSET_X,
41         parent_window->get_abs_cursor_y(0) + DRAG_OFFSET_Y,
42         pixmap->get_w(),
43         pixmap->get_h(),
44         -1,
45         0,
46         pixmap)
47 {
48         temp_frame = 0;
49 //      init_x = icon_x;
50 //      init_y = icon_y;
51         init_x = parent_window->get_abs_cursor_x(0) + DRAG_OFFSET_X;
52         init_y = parent_window->get_abs_cursor_y(0) + DRAG_OFFSET_Y;
53         end_x = BC_INFINITY;
54         end_y = BC_INFINITY;
55         icon_offset_x = init_x - parent_window->get_abs_cursor_x(0);
56         icon_offset_y = init_y - parent_window->get_abs_cursor_y(0);
57 //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y);
58         do_animation = 1;
59 }
60
61
62 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window, 
63         VFrame *frame /*, 
64         int icon_x, 
65         int icon_y */)
66  : BC_Popup(parent_window, 
67 //      icon_x, 
68 //      icon_y,
69         parent_window->get_abs_cursor_x(0) + DRAG_OFFSET_X,
70         parent_window->get_abs_cursor_y(0) + DRAG_OFFSET_Y,
71         frame->get_w(),
72         frame->get_h(),
73         -1,
74         0,
75         prepare_frame(frame, parent_window))
76 {
77         delete temp_frame;  // created in prepare_frame inside constructor
78         temp_frame = 0;
79 //      init_x = icon_x;
80 //      init_y = icon_y;
81         init_x = parent_window->get_abs_cursor_x(0) + DRAG_OFFSET_X;
82         init_y = parent_window->get_abs_cursor_y(0) + DRAG_OFFSET_Y;
83         end_x = BC_INFINITY;
84         end_y = BC_INFINITY;
85         icon_offset_x = init_x - parent_window->get_abs_cursor_x(0);
86         icon_offset_y = init_y - parent_window->get_abs_cursor_y(0);
87 //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y);
88         do_animation = 1;
89 }
90
91 BC_DragWindow::~BC_DragWindow()
92 {
93 }
94
95 int BC_DragWindow::get_init_x(BC_WindowBase *parent_window, int icon_x)
96 {
97         int output_x, temp = 0;
98         Window tempwin;
99         XTranslateCoordinates(parent_window->top_level->display, 
100                 parent_window->win, 
101                 parent_window->top_level->rootwin, 
102                 icon_x, 
103                 temp, 
104                 &output_x, 
105                 &temp, 
106                 &tempwin);
107         return output_x;
108 }
109
110 int BC_DragWindow::get_init_y(BC_WindowBase *parent_window, int icon_y)
111 {
112         int output_y, temp = 0;
113         Window tempwin;
114         XTranslateCoordinates(parent_window->top_level->display, 
115                 parent_window->win, 
116                 parent_window->top_level->rootwin, 
117                 temp, 
118                 icon_y, 
119                 &temp, 
120                 &output_y, 
121                 &tempwin);
122         return output_y;
123 }
124
125 int BC_DragWindow::cursor_motion_event()
126 {
127         reposition_window(get_abs_cursor_x(0) + icon_offset_x, 
128                 get_abs_cursor_y(0) + icon_offset_y, 
129                 get_w(), 
130                 get_h());
131         flush();
132         return 1;
133 }
134
135 int BC_DragWindow::get_offset_x()
136 {
137         return icon_offset_x;
138 }
139
140 int BC_DragWindow::get_offset_y()
141 {
142         return icon_offset_y;
143 }
144
145 int BC_DragWindow::drag_failure_event()
146 {
147         if(!do_animation) return 0;
148
149         if(end_x == BC_INFINITY)
150         {
151                 end_x = get_x();
152                 end_y = get_y();
153         }
154
155         for(int i = 0; i < 10; i++)
156         {
157                 int new_x = end_x + (init_x - end_x) * i / 10;
158                 int new_y = end_y + (init_y - end_y) * i / 10;
159
160                 reposition_window(new_x, 
161                         new_y, 
162                         get_w(), 
163                         get_h());
164                 flush();
165                 usleep(1000);
166         }
167         return 0;
168 }
169
170 void BC_DragWindow::set_animation(int value)
171 {
172         this->do_animation = value;
173 }
174
175 BC_Pixmap *BC_DragWindow::prepare_frame(VFrame *frame, BC_WindowBase *parent_window)
176 {
177         temp_frame = 0;
178         
179         if(frame->get_color_model() == BC_RGBA8888)
180         {
181                 temp_frame = new VFrame(*frame);
182         }
183         else
184         {
185                 temp_frame = new VFrame;
186                 temp_frame->set_use_shm(0);
187                 temp_frame->reallocate(0, 
188                                         -1,
189                                         0,
190                                         0,
191                                         0,
192                                         frame->get_w(), 
193                                         frame->get_h(), 
194                                         BC_RGBA8888,
195                                         -1); 
196
197                 BC_CModels::transfer(temp_frame->get_rows(), frame->get_rows(),
198                         0, 0, 0, 0, 0, 0,
199                         0, 0, frame->get_w(), frame->get_h(),
200                         0, 0, temp_frame->get_w(), temp_frame->get_h(),
201                         frame->get_color_model(), temp_frame->get_color_model(),
202                         0, frame->get_w(), temp_frame->get_w());
203         }
204         temp_frame->get_rows()[(temp_frame->get_h() / 2)][(temp_frame->get_w() / 2) * 4 + 3] = 0;
205         my_pixmap = new BC_Pixmap(parent_window,
206                         temp_frame,
207                         PIXMAP_ALPHA);
208
209         return (my_pixmap);
210 }
211
212