r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / setchannels.C
blob5048078f311c496b1472e121bd6c5b5eacb80432
1 #include "keys.h"
2 #include "mainundo.h"
3 #include "mwindow.h"
4 #include "mwindowgui.h"
5 #include "mainsession.h"
6 #include "setchannels.h"
8 #include <math.h>
9 #include <libintl.h>
10 #define _(String) gettext(String)
11 #define gettext_noop(String) String
12 #define N_(String) gettext_noop (String)
15 SetChannels::SetChannels(MWindow *mwindow)
16  : BC_MenuItem(_("Output channels...")), Thread() 
17 { this->mwindow = mwindow; }
19 int SetChannels::handle_event() 
20
21         old_channels = new_channels = mwindow->session->audio_channels;
22         for(int i = 0 ; i < MAXCHANNELS; i++)
23         {
24                 this->achannel_positions[i] = mwindow->session->achannel_positions[i];
25         }
26 //      mwindow->gui->disable_window();
27         start(); 
30 void SetChannels::run()
32         SetChannelsWindow window(mwindow, this);
33         window.create_objects();
34         int result = window.run_window();
35         if(!result)
36         {
37                 mwindow->undo->update_undo_audio(_("Output channels"), 0);
38                 for(int i = 0 ; i < MAXCHANNELS; i++)
39                 {
40                         mwindow->session->achannel_positions[i] = this->achannel_positions[i];
41                 }
42                 mwindow->change_channels(old_channels, new_channels);
43                 //mwindow->defaults->update("OUTCHANNELS", new_channels);
44                 mwindow->undo->update_undo_audio();
45                 mwindow->draw();
46                 mwindow->session->changes_made = 1;
47         }
48 //      mwindow->gui->enable_window();
52 SetChannelsWindow::SetChannelsWindow(MWindow *mwindow, SetChannels *setchannels)
53  : BC_Window(PROGRAM_NAME ": Output Channels", 
54         mwindow->gui->get_abs_cursor_x(), 
55         mwindow->gui->get_abs_cursor_y(), 
56         340, 
57         270)
59         this->setchannels = setchannels;
62 SetChannelsWindow::~SetChannelsWindow()
64         delete text;
65         delete canvas;
68 int SetChannelsWindow::create_objects()
70         add_subwindow(new BC_Title(5, 5, _("Enter the output channels to use:")));
71         add_subwindow(new BC_OKButton(10, get_h() - 40));
72         add_subwindow(new BC_CancelButton(get_w() - 100, get_h() - 40));
73         
74         add_subwindow(new BC_Title(5, 60, _("Position the channels in space:")));
75         add_subwindow(canvas = new SetChannelsCanvas(setchannels, 10, 80, 150, 150));
77         char string[1024];
78         sprintf(string, "%d", setchannels->old_channels);
79         add_subwindow(text = new SetChannelsTextBox(setchannels, canvas, string));
80         
81         canvas->draw();
84 SetChannelsTextBox::SetChannelsTextBox(SetChannels *setchannels, SetChannelsCanvas *canvas, char *text)
85  : BC_TextBox(10, 30, 100, 1, text)
87         this->setchannels = setchannels;
88         this->canvas = canvas;
91 int SetChannelsTextBox::handle_event()
93         int result = atol(get_text());
94         if(result > 0 && result < MAXCHANNELS)
95         {
96                 setchannels->new_channels = result;
97                 canvas->draw();
98         }
101 SetChannelsCanvas::SetChannelsCanvas(SetChannels *setchannels, int x, int y, int w, int h)
102  : BC_SubWindow(x, y, w, h, BLACK)
104         this->setchannels = setchannels;
105         active_channel = -1;
106         box_r = 10;
109 SetChannelsCanvas::~SetChannelsCanvas()
113 int SetChannelsCanvas::create_objects()
117 int SetChannelsCanvas::draw(int angle)
119         clear_box(0, 0, get_w(), get_h());
120         set_color(RED);
121         int real_w = get_w() - box_r * 2;
122         int real_h = get_h() - box_r * 2;
123         int real_x = box_r;
124         int real_y = box_r;
125 //      draw_circle(real_x, real_y, real_w, real_h);
126         
127         int x, y, w, h;
128         char string[32];
129         set_color(MEYELLOW);
130         for(int i = 0; i < setchannels->new_channels; i++)
131         {
132                 get_dimensions(setchannels->achannel_positions[i], x, y, w, h);
133                 draw_rectangle(x, y, w, h);
134                 sprintf(string, "%d", i + 1);
135                 draw_text(x + 2, y + box_r * 2 - 2, string);
136         }
137         if(angle > -1)
138         {
139                 sprintf(string, _("%d degrees"), angle);
140                 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
141         }
142         
143         flash();
146 int SetChannelsCanvas::button_press()
148 // get active channel
149         for(int i = 0; i < setchannels->new_channels; i++)
150         {
151                 int x, y, w, h;
152                 get_dimensions(setchannels->achannel_positions[i], x, y, w, h);
153                 if(get_cursor_x() > x && get_cursor_y() > y && 
154                         get_cursor_x() < x + w && get_cursor_y() < y + h)
155                 {
156                         active_channel = i;
157                         xytopol(degree_offset, get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
158                         degree_offset -= setchannels->achannel_positions[i];
159                         draw(setchannels->achannel_positions[i]);
160 //printf("degrees %d degree offset %d\n", setchannels->achannel_positions[i], degree_offset);
161                 }
162         }
163         return 1;
166 int SetChannelsCanvas::button_release()
168         active_channel = -1;
169         draw(-1);
172 int SetChannelsCanvas::cursor_motion()
174         if(active_channel > -1)
175         {
176 // get degrees of new channel
177                 int new_d;
178                 xytopol(new_d, get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
179                 new_d -= degree_offset;
180                 if(new_d < 0) new_d += 360;
181                 if(setchannels->achannel_positions[active_channel] != new_d)
182                 {
183                         setchannels->achannel_positions[active_channel] = new_d;
184                         draw(setchannels->achannel_positions[active_channel]);
185                 }
186                 return 1;
187         }
188         return 0;
191 int SetChannelsCanvas::get_dimensions(int channel_position, int &x, int &y, int &w, int &h)
193         int real_w = this->get_w() - box_r * 2;
194         int real_h = this->get_h() - box_r * 2;
195         poltoxy(x, y, real_w / 2, channel_position);
196         x += real_w / 2;
197         y += real_h / 2;
198         w = box_r * 2;
199         h = box_r * 2;
203 int SetChannelsCanvas::poltoxy(int &x, int &y, int r, int d)
205         float radians = (float)(d - 90) / 360 * 2 * M_PI;
206         y = (int)(sin(radians) * r);
207         x = (int)(cos(radians) * r);
210 int SetChannelsCanvas::xytopol(int &d, int x, int y)
212         float x1, y1;
213         float angle;
214         y *= -1;
215         x *= -1;
216         
217         if(x < 0 && y > 0){
218                 x1 = y;
219                 y1 = x;
220         }else{
221                 x1 = x;
222                 y1 = y;
223         }
225         if(!y || !x){
226                 if(x < 0) angle = .5;
227                 else
228                 if(x > 0) angle = 1.5;
229                 else
230                 if(y < 0) angle = 1;
231                 else
232                 if(y > 0) angle = 0;
233         }else{
234                 angle = atan(y1 / x1);
235                 angle /= M_PI;
236         }
238 // fix angle
240         if(x < 0 && y < 0){
241                 angle += .5;
242         }else
243         if(x > 0 && y > 0){
244                 angle += 1.5;
245         }else
246         if(x > 0 && y < 0){
247                 angle += 1.5;
248         }
250         if(x < 0 && y > 0) angle = -angle;
251         angle /= 2;
252         angle *= 360;
253         d =  (int)angle;