8d70fb8f99e30355a8ad633f9b44b7c71e4bd8cf
[goodguy/history.git] / cinelerra-5.1 / 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 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window,
29         BC_Pixmap *pixmap, int icon_x, int icon_y)
30  : BC_Popup(parent_window, icon_x, icon_y, pixmap->get_w(), pixmap->get_h(),
31         -1, 0, pixmap)
32 {
33         drag_pixmap = 0;
34         init_x = icon_x;
35         init_y = icon_y;
36         end_x = BC_INFINITY;
37         end_y = BC_INFINITY;
38         icon_offset_x = init_x - parent_window->get_abs_cursor_x(0);
39         icon_offset_y = init_y - parent_window->get_abs_cursor_y(0);
40 //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y);
41         do_animation = 1;
42 }
43
44
45 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window,
46         VFrame *frame, int icon_x, int icon_y)
47  : BC_Popup(parent_window, icon_x, icon_y, frame->get_w(), frame->get_h(),
48         -1, 0, prepare_frame(frame, parent_window))
49 {
50         init_x = icon_x;
51         init_y = icon_y;
52         end_x = BC_INFINITY;
53         end_y = BC_INFINITY;
54         icon_offset_x = init_x - parent_window->get_abs_cursor_x(0);
55         icon_offset_y = init_y - parent_window->get_abs_cursor_y(0);
56 //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y);
57         do_animation = 1;
58 }
59
60 BC_DragWindow::~BC_DragWindow()
61 {
62         delete drag_pixmap;
63 }
64
65 int BC_DragWindow::get_init_x(BC_WindowBase *parent_window, int icon_x)
66 {
67         int output_x, temp = 0;
68         Window tempwin;
69         XTranslateCoordinates(parent_window->top_level->display,
70                 parent_window->win, parent_window->top_level->rootwin,
71                 icon_x, temp, &output_x, &temp, &tempwin);
72         return output_x;
73 }
74
75 int BC_DragWindow::get_init_y(BC_WindowBase *parent_window, int icon_y)
76 {
77         int output_y, temp = 0;
78         Window tempwin;
79         XTranslateCoordinates(parent_window->top_level->display,
80                 parent_window->win, parent_window->top_level->rootwin,
81                 temp, icon_y, &temp, &output_y, &tempwin);
82         return output_y;
83 }
84
85 int BC_DragWindow::cursor_motion_event()
86 {
87         int cx, cy;
88         get_abs_cursor(cx, cy);
89         reposition_window(cx + icon_offset_x, cy + icon_offset_y, get_w(), get_h());
90         flush();
91         return 1;
92 }
93 int BC_DragWindow::button_release_event()
94 {
95         cursor_motion_event();
96         sync();
97         return BC_WindowBase::button_release_event();
98 }
99
100 int BC_DragWindow::get_offset_x()
101 {
102         return icon_offset_x;
103 }
104
105 int BC_DragWindow::get_offset_y()
106 {
107         return icon_offset_y;
108 }
109
110 int BC_DragWindow::drag_failure_event()
111 {
112         if(!do_animation) return 0;
113
114         if(end_x == BC_INFINITY) {
115                 end_x = get_x();
116                 end_y = get_y();
117         }
118
119         for(int i = 0; i < 10; i++) {
120                 int new_x = end_x + (init_x - end_x) * i / 10;
121                 int new_y = end_y + (init_y - end_y) * i / 10;
122
123                 reposition_window(new_x, new_y, get_w(), get_h());
124                 flush();
125                 usleep(1000);
126         }
127         return 0;
128 }
129
130 void BC_DragWindow::set_animation(int value)
131 {
132         this->do_animation = value;
133 }
134
135 BC_Pixmap *BC_DragWindow::prepare_frame(VFrame *frame, BC_WindowBase *parent_window)
136 {
137         VFrame *temp_frame = 0;
138         int tw = frame->get_w(), th = frame->get_h();
139
140         if( frame->get_color_model() != BC_RGBA8888 ) {
141                 temp_frame = new VFrame(tw, th, BC_RGBA8888);
142                 temp_frame->transfer_from(frame);
143         }
144         else
145                 temp_frame = new VFrame(*frame);
146
147         int tx = tw/2, ty = th/2, tx1 = tx-1, ty1 = ty-1, tx2 = tx+2, ty2 = ty+2;
148         int bpp = BC_CModels::calculate_pixelsize(temp_frame->get_color_model());
149         unsigned char **rows = temp_frame->get_rows();
150         for( int y=ty1; y<ty2; ++y ) {
151                 for( int x=tx1; x<tx2; ++x ) {
152                         unsigned char *rp = rows[y] + x*bpp;
153                         rp[3] = 0; // alpha of center pixels = 0
154                 }
155         }
156         drag_pixmap = new BC_Pixmap(parent_window, temp_frame, PIXMAP_ALPHA);
157
158         delete temp_frame;
159         return drag_pixmap;
160 }
161
162