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;
182 int value = get_value();
184 if( !gui->grab(cwindow_gui) ) {
190 gui->ungrab(cwindow_gui);
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))
200 void N_BodySetMode::create_objects()
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);
208 int N_BodySetMode::handle_event()
210 N_BodyMain *plugin = gui->plugin;
211 plugin->config.mode = get_number();
212 plugin->send_configure_change();
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))
223 void N_BodySetDemo::create_objects()
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));
230 update_list(&demo_items);
233 int N_BodySetDemo::handle_event()
235 N_BodyMain *plugin = gui->plugin;
236 plugin->selectDemo(get_number());
238 plugin->send_configure_change();
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))
248 void N_BodyNumBodies::create_objects()
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));
255 update_list(&num_body_items);
258 int N_BodyNumBodies::handle_event()
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();
269 N_BodyReset::N_BodyReset(N_BodyWindow *gui, int x, int y)
270 : BC_GenericButton(x, y, _("Reset"))
274 N_BodyReset::~N_BodyReset()
278 int N_BodyReset::handle_event()
280 N_BodyMain *plugin = gui->plugin;
281 plugin->config.reset();
283 gui->send_configure_change();