version update
[goodguy/cinelerra.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 "bcbitmap.h"
24 #include "bcpixmap.h"
25
26 #include "vframe.h"
27 #include <unistd.h>
28
29 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window,
30         BC_Pixmap *pixmap, int center_x, int center_y)
31  : BC_Popup(parent_window,
32         center_x - pixmap->get_w() / 2, center_y - pixmap->get_h() / 2,
33         pixmap->get_w(), pixmap->get_h(), -1, 0,
34         prepare_pixmap(pixmap, parent_window))
35 {
36         drag_pixmap = 0;
37         init_x = get_x();
38         init_y = get_y();
39         end_x = BC_INFINITY;
40         end_y = BC_INFINITY;
41         do_animation = 1;
42 }
43
44
45 BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window,
46         VFrame *frame, int center_x, int center_y)
47  : BC_Popup(parent_window,
48         center_x - frame->get_w() / 2, center_y - frame->get_h() / 2,
49         frame->get_w(), frame->get_h(), -1, 0,
50         prepare_frame(frame, parent_window))
51 {
52         init_x = get_x();
53         init_y = get_y();
54         end_x = BC_INFINITY;
55         end_y = BC_INFINITY;
56         do_animation = 1;
57 }
58
59 BC_DragWindow::~BC_DragWindow()
60 {
61         delete drag_pixmap;
62 }
63
64 int BC_DragWindow::cursor_motion_event()
65 {
66         int cx, cy;
67         get_abs_cursor(cx, cy);
68         cx -= get_w() / 2;
69         cy -= get_h() / 2;
70         reposition_window(cx, cy, get_w(), get_h());
71         flush();
72         return 1;
73 }
74 int BC_DragWindow::button_release_event()
75 {
76         cursor_motion_event();
77         sync();
78         return BC_WindowBase::button_release_event();
79 }
80
81 int BC_DragWindow::drag_failure_event()
82 {
83         if(!do_animation) return 0;
84
85         if(end_x == BC_INFINITY) {
86                 end_x = get_x();
87                 end_y = get_y();
88         }
89
90         for(int i = 0; i < 10; i++) {
91                 int new_x = end_x + (init_x - end_x) * i / 10;
92                 int new_y = end_y + (init_y - end_y) * i / 10;
93
94                 reposition_window(new_x, new_y, get_w(), get_h());
95                 flush();
96                 usleep(250000/10);
97         }
98         return 0;
99 }
100
101 void BC_DragWindow::set_animation(int value)
102 {
103         this->do_animation = value;
104 }
105
106 BC_Pixmap *BC_DragWindow::prepare_frame(VFrame *frame, BC_WindowBase *parent_window)
107 {
108         VFrame *temp_frame = frame;
109         int tw = frame->get_w(), th = frame->get_h();
110
111         if( frame->get_color_model() != BC_RGBA8888 ) {
112                 temp_frame = new VFrame(tw, th, BC_RGBA8888, 0);
113                 temp_frame->transfer_from(frame);
114         }
115
116         int tx = tw/2, ty = th/2, tx1 = tx-1, ty1 = ty-1, tx2 = tx+2, ty2 = ty+2;
117         int bpp = BC_CModels::calculate_pixelsize(temp_frame->get_color_model());
118         unsigned char **rows = temp_frame->get_rows();
119         for( int y=ty1; y<ty2; ++y ) {
120                 for( int x=tx1; x<tx2; ++x ) {
121                         unsigned char *rp = rows[y] + x*bpp;
122                         rp[3] = 0; // alpha of center pixels = 0
123                 }
124         }
125         drag_pixmap = new BC_Pixmap(parent_window, temp_frame, PIXMAP_ALPHA);
126
127         if( temp_frame != frame )
128                 delete temp_frame;
129         return drag_pixmap;
130 }
131
132 BC_Pixmap *BC_DragWindow::prepare_pixmap(BC_Pixmap *pixmap, BC_WindowBase *parent_window)
133 {
134         int pix_w = pixmap->get_w(), pix_h = pixmap->get_h();
135         BC_Bitmap bitmap(parent_window, pix_w, pix_h, BC_RGB888, 0);
136         Pixmap xpixmap = pixmap->get_pixmap();
137         VFrame frame(pix_w, pix_h, BC_RGB888);
138         bitmap.read_drawable(xpixmap, 0,0,&frame);
139         return prepare_frame(&frame, parent_window);
140 }
141