3 * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
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.
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.
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
21 #include "bcdisplayinfo.h"
24 #include "cwindowgui.h"
27 #include "nbodywindow.h"
29 #include "mwindowgui.h"
30 #include "pluginserver.h"
33 static const char *display_modes[] = {
38 static const int num_display_modes = sizeof(display_modes)/sizeof(*display_modes);
40 N_BodyWindow::N_BodyWindow(N_BodyMain *plugin)
41 : PluginClientWindow(plugin, xS(240), yS(200), xS(240), yS(200), 0)
43 this->plugin = plugin;
44 press_x = press_y = 0;
49 N_BodyWindow::~N_BodyWindow()
53 void N_BodyWindow::create_objects()
55 int x = xS(10), y = yS(10), pad = xS(5);
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:")));
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));
80 void N_BodyWindow::update_gui()
82 set_mode->update(_(display_modes[plugin->config.mode]));
84 sprintf(text, "%d", plugin->config.numBodies);
85 num_bodies->update(text);
89 void N_BodyWindow::send_configure_change()
92 plugin->send_configure_change();
95 int N_BodyWindow::grab_event(XEvent *event)
97 int ret = do_grab_event(event);
98 if( pending_config && !grab_event_count() )
99 send_configure_change();
103 int N_BodyWindow::do_grab_event(XEvent *event)
105 switch( event->type ) {
106 case ButtonPress: break;
107 case ButtonRelease: break;
108 case MotionNotify: break;
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);
124 if( cursor_x < 0 || cursor_x >= canvas->view_w ||
125 cursor_y < 0 || cursor_y >= canvas->view_h )
129 switch( event->type ) {
131 if( button_no ) return 0;
132 press_x = output_x; press_y = output_y;
133 button_no = event->xbutton.button;
136 if( !button_no ) return 0;
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 ) {
147 config.trans[0] += dx / 5.0f;
148 config.trans[1] -= dy / 5.0f;
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;
156 config.rot[0] += dy / 5.0f;
157 config.rot[1] += dx / 5.0f;
169 void N_BodyWindow::done_event(int result)
171 ungrab(client->server->mwindow->cwindow->gui);
174 N_BodyDrag::N_BodyDrag(N_BodyWindow *gui, int x, int y)
175 : BC_CheckBox(x, y, 0, _("Drag"))
179 int N_BodyDrag::handle_event()
181 CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
183 if( !gui->grab(cwindow_gui) ) {
189 gui->ungrab(cwindow_gui);
192 int N_BodyDrag::handle_ungrab()
194 CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
195 int ret = gui->ungrab(cwindow_gui);
196 if( ret ) update(*value = 0);
200 N_BodySetMode::N_BodySetMode(N_BodyWindow *gui, int x, int y, const char *text)
201 : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
206 void N_BodySetMode::create_objects()
208 BC_PopupTextBox::create_objects();
209 for( int i=0; i<num_display_modes; ++i )
210 mode_items.append(new BC_ListBoxItem(_(display_modes[i])));
211 update_list(&mode_items);
214 int N_BodySetMode::handle_event()
216 N_BodyMain *plugin = gui->plugin;
217 plugin->config.mode = get_number();
218 plugin->send_configure_change();
223 N_BodySetDemo::N_BodySetDemo(N_BodyWindow *gui, int x, int y, const char *text)
224 : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
229 void N_BodySetDemo::create_objects()
231 BC_PopupTextBox::create_objects();
232 for( int i=0; i<N_BodyParams::num_demos; ++i ) {
233 char text[BCSTRLEN]; sprintf(text,"%d",i);
234 demo_items.append(new BC_ListBoxItem(text));
236 update_list(&demo_items);
239 int N_BodySetDemo::handle_event()
241 N_BodyMain *plugin = gui->plugin;
242 plugin->selectDemo(get_number());
244 plugin->send_configure_change();
248 N_BodyNumBodies::N_BodyNumBodies(N_BodyWindow *gui, int x, int y, const char *text)
249 : BC_PopupTextBox(gui, 0, text, x, y, xS(100), yS(160))
254 void N_BodyNumBodies::create_objects()
256 BC_PopupTextBox::create_objects();
257 for( int i=0; i<8; ++i ) {
258 char text[BCSTRLEN]; sprintf(text,"%d",1<<(i+6));
259 num_body_items.append(new BC_ListBoxItem(text));
261 update_list(&num_body_items);
264 int N_BodyNumBodies::handle_event()
266 N_BodyMain *plugin = gui->plugin;
267 int i = get_number();
268 int n = i >= 0 ? (1 << (i+6)) : atoi(get_text());
269 bclamp(n, 0x10,0x4000);
270 plugin->config.numBodies = n;
271 plugin->send_configure_change();
275 N_BodyReset::N_BodyReset(N_BodyWindow *gui, int x, int y)
276 : BC_GenericButton(x, y, _("Reset"))
280 N_BodyReset::~N_BodyReset()
284 int N_BodyReset::handle_event()
286 N_BodyMain *plugin = gui->plugin;
287 plugin->config.reset();
289 gui->send_configure_change();