~cypheon/elfelli

ref: 6e670cf52ccbaec48d0630b96c51a6f936397c54 elfelli/src/SimulationCanvas.h -rw-r--r-- 2.9 KiB
6e670cf5 — Johann Rudloff Now changing a body's charge is possible. 14 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// -*- C++ -*-
/*
 * SimulationCanvas.h
 * Copyright (C) 2006  Johann Rudloff
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _SIMULATIONCANVAS_H_
#define _SIMULATIONCANVAS_H_

#include <vector>

#include "Simulation.h"
#include "Canvas.h"

namespace Elfelli
{

enum BodyState
  {
    BODY_STATE_NORMAL = 0,
    BODY_STATE_HIGHLIGHT,
    BODY_STATE_SELECTED,
    BODY_STATES_NUM
  };

enum DragState
  {
    DRAG_STATE_NONE = 0,
    DRAG_STATE_BODY,
    DRAG_STATE_PLATE,
    DRAG_STATE_PLATE_A,
    DRAG_STATE_PLATE_B
  };

class SimulationCanvas : public Simulation, public Canvas
{
public:
  SimulationCanvas();
  ~SimulationCanvas();

  void operator=(const Simulation& sim);

  void refresh();
  void clear();
  bool delete_body(int n);
  bool delete_plate(int n);
  bool delete_selected();

  bool change_selected_charge(float delta);
  bool increase_selected_charge(){return change_selected_charge(1);};
  bool decrease_selected_charge(){return change_selected_charge(-1);};

private:
  void draw_flux_lines();
  void draw_bodies(bool draw_selected=true);
  inline void draw_body(int n);
  void draw_plates(bool draw_selected=true);
  inline void draw_plate(int n);

  bool point_hits_body(Body& b, int x, int y);
  bool point_hits_plate_a(PlateBody& p, int x, int y);
  bool point_hits_plate_b(PlateBody& p, int x, int y);
  bool point_hits_plate(PlateBody& p, int x, int y);
  int object_at(int x, int y);

  static char *color_names[];
  static const float MAX_CHARGE;

  int body_radius, plate_radius;

  DragState drag_state; 
  int active;

  bool mouse_pressed;
  int mouse_over;
  Gdk::Point last_click, drag_offset;

  Glib::RefPtr<Gdk::GC> gc, gc_black, gc_white, gc_selection, gc_platebody;
  Gdk::Color colors[BODY_STATES_NUM * 2];
  Glib::RefPtr<Gdk::Pixmap> lines_pixmap;
  std::vector<Path> paths;

protected:
  virtual void run();
  void plot();

  virtual void after_realize_event();
  virtual bool on_configure_event(GdkEventConfigure *event);

  virtual bool on_motion_notify_event(GdkEventMotion *event);
  virtual bool on_button_press_event(GdkEventButton *event);
  virtual bool on_button_release_event(GdkEventButton *event);

  virtual bool on_key_press_event(GdkEventKey *event);
};

}

#endif // _SIMULATIONCANVAS_H_