add BC_SCALE env var for hi def monitors, cleanup theme data
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / nbodycuda / nbodywindow.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * 
19  */
20
21 #include "bcdisplayinfo.h"
22 #include "clip.h"
23 #include "cwindow.h"
24 #include "cwindowgui.h"
25 #include "language.h"
26 #include "nbody.h"
27 #include "nbodywindow.h"
28 #include "mwindow.h"
29 #include "mwindowgui.h"
30 #include "pluginserver.h"
31 #include "theme.h"
32
33 static const char *display_modes[] = {
34         N_("point"),
35         N_("sprite"),
36         N_("color"),
37 };
38 static const int num_display_modes = sizeof(display_modes)/sizeof(*display_modes);
39
40 N_BodyWindow::N_BodyWindow(N_BodyMain *plugin)
41  : PluginClientWindow(plugin, xS(240), yS(200), xS(240), yS(200), 0)
42 {
43         this->plugin = plugin; 
44         press_x = press_y = 0;
45         button_no = 0;
46         pending_config = 0;
47 }
48
49 N_BodyWindow::~N_BodyWindow()
50 {
51 }
52
53 void N_BodyWindow::create_objects()
54 {
55         int x = xS(10), y = yS(10), pad = xS(5);
56         int x1 = xS(100);
57         BC_Title *title;
58         add_subwindow(title = new BC_Title(x,y, _("NBody"), MEDIUMFONT, YELLOW));
59         y += title->get_h() + 2*pad;
60         add_subwindow(title = new BC_Title(x,y, _("set demo:")));
61         set_demo = new N_BodySetDemo(this, x1,y, "0");
62         set_demo->create_objects();
63         y += set_demo->get_h() + pad;
64         add_subwindow(title = new BC_Title(x,y, _("draw mode:")));
65         set_mode = new N_BodySetMode(this, x1,y, _(display_modes[plugin->config.mode]));
66         set_mode->create_objects();
67         y += set_mode->get_h() + pad;
68         add_subwindow(title = new BC_Title(x,y, _("numBodies:")));
69         char text[BCSTRLEN];
70         sprintf(text, "%d", plugin->config.numBodies);
71         num_bodies = new N_BodyNumBodies(this, x1,y, text);
72         num_bodies->create_objects();
73         y += num_bodies->get_h() + pad;
74         add_subwindow(drag = new N_BodyDrag(this, x, y));
75         y += drag->get_h() + pad;
76         add_subwindow(reset = new N_BodyReset(this, x, y));
77         show_window();
78 }
79
80 void N_BodyWindow::update_gui()
81 {
82         set_mode->update(_(display_modes[plugin->config.mode]));
83         char text[BCSTRLEN];
84         sprintf(text, "%d", plugin->config.numBodies);
85         num_bodies->update(text);
86 }
87
88
89 void N_BodyWindow::send_configure_change()
90 {
91         pending_config = 0;
92         plugin->send_configure_change();
93 }
94
95 int N_BodyWindow::grab_event(XEvent *event)
96 {
97         int ret = do_grab_event(event);
98         if( pending_config && !grab_event_count() )
99                 send_configure_change();
100         return ret;
101 }
102
103 int N_BodyWindow::do_grab_event(XEvent *event)
104 {
105         switch( event->type ) {
106         case ButtonPress: break;
107         case ButtonRelease: break;
108         case MotionNotify: break;
109         default:
110                 return 0;
111         }
112
113         MWindow *mwindow = plugin->server->mwindow;
114         CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
115         CWindowCanvas *canvas = cwindow_gui->canvas;
116         int cursor_x, cursor_y;
117         cwindow_gui->get_relative_cursor(cursor_x, cursor_y);
118         cursor_x -= canvas->view_x;
119         cursor_y -= canvas->view_y;
120         float output_x = cursor_x, output_y = cursor_y;
121         canvas->canvas_to_output(mwindow->edl, 0, output_x, output_y);
122
123         if( !button_no ) {
124                 if( cursor_x < 0 || cursor_x >= canvas->view_w ||
125                     cursor_y < 0 || cursor_y >= canvas->view_h )
126                         return 0;
127         }
128
129         switch( event->type ) {
130         case ButtonPress:
131                 if( button_no ) return 0;
132                 press_x = output_x;  press_y = output_y;
133                 button_no = event->xbutton.button;
134                 break;
135         case ButtonRelease:
136                 if( !button_no ) return 0;
137                 button_no = 0;
138                 return 1;
139         case MotionNotify: {
140                 if( !button_no ) return 0;
141                 N_BodyConfig &config = plugin->config;
142                 double dx = (double)(press_x - output_x);
143                 double dy = (double)(press_y - output_y);
144                 press_x = output_x;  press_y = output_y;
145                 switch( button_no ) {
146                 case LEFT_BUTTON: {
147                         config.trans[0] += dx / 5.0f;
148                         config.trans[1] -= dy / 5.0f;
149                         break; }
150                 case MIDDLE_BUTTON: {
151                         double s = 0.5f * fabs(config.trans[2]);
152                         if( s < 0.1 ) s = 0.1;
153                         config.trans[2] += (dy / 100.0f) * s;
154                         break; }
155                 case RIGHT_BUTTON: {
156                         config.rot[0] += dy / 5.0f;
157                         config.rot[1] += dx / 5.0f;
158                         break; }
159                 }
160                 pending_config = 1;
161                 break; }
162         default:
163                 return 0;
164         }
165
166         return 1;
167 }
168
169 void N_BodyWindow::done_event(int result)
170 {
171         ungrab(client->server->mwindow->cwindow->gui);
172 }
173
174 N_BodyDrag::N_BodyDrag(N_BodyWindow *gui, int x, int y)
175  : BC_CheckBox(x, y, 0, _("Drag"))
176 {
177         this->gui = gui;
178 }
179 int N_BodyDrag::handle_event()
180 {
181         CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
182         int value = get_value();
183         if( value ) {
184                 if( !gui->grab(cwindow_gui) ) {
185                         update(value = 0);
186                         flicker(10,50);
187                 }
188         }
189         else
190                 gui->ungrab(cwindow_gui);
191         return 1;
192 }
193
194 N_BodySetMode::N_BodySetMode(N_BodyWindow *gui, int x, int y, const char *text)
195  : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
196 {
197         this->gui = gui;
198 }
199
200 void N_BodySetMode::create_objects()
201 {
202         BC_PopupTextBox::create_objects();
203         for( int i=0; i<num_display_modes; ++i )
204                 mode_items.append(new BC_ListBoxItem(_(display_modes[i])));
205         update_list(&mode_items);
206 }
207
208 int N_BodySetMode::handle_event()
209 {
210         N_BodyMain *plugin = gui->plugin;
211         plugin->config.mode = get_number();
212         plugin->send_configure_change();
213         return 1;
214 }
215
216
217 N_BodySetDemo::N_BodySetDemo(N_BodyWindow *gui, int x, int y, const char *text)
218  : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
219 {
220         this->gui = gui;
221 }
222
223 void N_BodySetDemo::create_objects()
224 {
225         BC_PopupTextBox::create_objects();
226         for( int i=0; i<N_BodyParams::num_demos; ++i ) {
227                 char text[BCSTRLEN];  sprintf(text,"%d",i);
228                 demo_items.append(new BC_ListBoxItem(text));
229         }
230         update_list(&demo_items);
231 }
232
233 int N_BodySetDemo::handle_event()
234 {
235         N_BodyMain *plugin = gui->plugin;
236         plugin->selectDemo(get_number());
237         gui->update_gui();
238         plugin->send_configure_change();
239         return 1;
240 }
241
242 N_BodyNumBodies::N_BodyNumBodies(N_BodyWindow *gui, int x, int y, const char *text)
243  : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
244 {
245         this->gui = gui;
246 }
247
248 void N_BodyNumBodies::create_objects()
249 {
250         BC_PopupTextBox::create_objects();
251         for( int i=0; i<8; ++i ) {
252                 char text[BCSTRLEN];  sprintf(text,"%d",1<<(i+6));
253                 num_body_items.append(new BC_ListBoxItem(text));
254         }
255         update_list(&num_body_items);
256 }
257
258 int N_BodyNumBodies::handle_event()
259 {
260         N_BodyMain *plugin = gui->plugin;
261         int i = get_number();
262         int n = i >= 0 ? (1 << (i+6)) : atoi(get_text());
263         bclamp(n, 0x10,0x4000);
264         plugin->config.numBodies = n;
265         plugin->send_configure_change();
266         return 1;
267 }
268
269 N_BodyReset::N_BodyReset(N_BodyWindow *gui, int x, int y)
270  : BC_GenericButton(x, y, _("Reset"))
271 {
272         this->gui = gui;
273 }
274 N_BodyReset::~N_BodyReset()
275 {
276 }
277
278 int N_BodyReset::handle_event()
279 {
280         N_BodyMain *plugin = gui->plugin;
281         plugin->config.reset();
282         gui->update_gui();
283         gui->send_configure_change();
284         return 1;
285 }
286