File: mouseobject.hpp

package info (click to toggle)
python-visual 1%3A5.12-1.1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 7,672 kB
  • ctags: 7,636
  • sloc: cpp: 15,593; sh: 9,615; ansic: 6,631; python: 4,737; makefile: 385
file content (212 lines) | stat: -rw-r--r-- 6,522 bytes parent folder | download | duplicates (3)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#ifndef VPYTHON_MOUSEOBJECT_HPP
#define VPYTHON_MOUSEOBJECT_HPP

// Copyright (c) 2000, 2001, 2002, 2003 by David Scherer and others.
// See the file license.txt for complete license terms.
// See the file authors.txt for a complete list of contributors.

#include "renderable.hpp"
#include "util/atomic_queue.hpp"

#include <queue>
#include <utility>
#include <bitset>

namespace cvisual {

/** This common base class implements common functionality for event and mouse.
 * It should never be used directly.
 */
class mousebase
{
 protected:
 	std::string button_name();
 	std::bitset<4> modifiers;
	std::bitset<5> eventtype;
	std::bitset<3> buttons;

 public:
	mousebase() {}
	virtual ~mousebase();
	// The position of the mouse, either currently, or when the even happened.
	vector position;
	// The position of the camera in the scene.
	vector cam;
	// The object nearest to the cursor when this event happened.
	shared_ptr<renderable> pick;
	// The position on the object that intersects with ray.
	vector pickpos;

	/* 'buttonstate' contains the following state flags as defined by 'button'.
	 */
	enum modifiers_t { shift, ctrl, alt, command };

	/* 'eventtype' contains state flags as defined by 'event'.
	 */
	enum event_t { press, release, click, drag, drop };

	enum button_t { left, right, middle };


	inline bool is_press() const { return eventtype.test( press); }
	inline bool is_release() const { return eventtype.test( release); }
	inline bool is_click() const { return eventtype.test( click); }
	inline bool is_drag() const { return eventtype.test( drag); }
	inline bool is_drop() const { return eventtype.test( drop); }
	std::string* get_buttons() const;
	inline bool is_shift() const { return modifiers.test( shift); }
	inline bool is_ctrl() const { return modifiers.test( ctrl); }
	inline bool is_alt() const { return modifiers.test( alt); } // option on Mac keyboard
	inline bool is_command() const { return modifiers.test( command); }
	inline vector get_pos() const { return position; }
	inline vector get_camera() const { return cam; }
	inline vector get_ray() const { return (position - cam).norm(); }
	inline vector get_pickpos() const { return pickpos; }
	shared_ptr<renderable> get_pick();

	inline void set_shift( bool _shift) { modifiers.set( shift, _shift); }
	inline void set_ctrl( bool _ctrl) { modifiers.set( ctrl, _ctrl); }
	inline void set_alt( bool _alt) { modifiers.set( alt,  _alt); } // option on Mac keyboard
	inline void set_command( bool _command) { modifiers.set( command,  _command); }

	inline void set_press( bool _press) { eventtype.set( press, _press); }
	inline void set_release( bool _release) { eventtype.set( release, _release); }
	inline void set_click( bool _click) { eventtype.set( click, _click); }
	inline void set_drag( bool _drag) { eventtype.set( drag, _drag); }
	inline void set_drop( bool _drop) { eventtype.set( drop, _drop); }

	inline void set_leftdown( bool _ld) { buttons.set( left, _ld); }
	inline void set_rightdown( bool _rd) { buttons.set( right, _rd); }
	inline void set_middledown( bool _md) { buttons.set( middle, _md); }

	vector project1( vector normal, double dist);
	vector project2( vector normal, vector point = vector(0,0,0));

	// These functions will return an object constructed from std::string, or None.
	std::string get_press();
	std::string get_release();
	std::string get_click();
	std::string get_drag();
	std::string get_drop();
};

/* Objects of this class represent the state of the mouse at a distinct event:
 * 	either press, release, click, drag, or drop.
 */
class event: public mousebase
{
 public:
	event(){}
};


/* A class exported to python as the single object display.mouse.
 * All of the python access for data within this class get the present value of
 * the data.
 */
class mouse_t : public mousebase
{
 private:
	// The bool tells whether or not the click was a left click or not.
	atomic_queue<shared_ptr<event> > events;
	int click_count; // number of queued events which are left clicks

 public:
	mouse_t() : click_count(0) {}
	virtual ~mouse_t();

	// The following member functions are synchronized - no additional locking
	// is requred.
	int num_events() const;
	void clear_events(int);
	int num_clicks() const;
    // Exposed as the function display.mouse.getevent()
	shared_ptr<event> pop_event();
    // Exposed as the function mouse.getclick()
	shared_ptr<event> pop_click();

	/** Push a new event onto the queue.  This function is not exposed to Python.
	 */
	void push_event( shared_ptr<event>);
};

// Convenience functions for creating event objects.
// which represents which mouse button is involved:
// 1 for left
// 2 for right
// 3 for middle
// no other number is valid.
shared_ptr<event> click_event( int which, const mouse_t& mouse);
shared_ptr<event> drop_event( int which, const mouse_t& mouse);
shared_ptr<event> press_event( int which, const mouse_t& mouse);
shared_ptr<event> drag_event( int which, const mouse_t& mouse);
shared_ptr<event> release_event( int which, const mouse_t& mouse);

// Utility object for tracking mouse press, release, clicks, drags, and drops.
struct mousebutton
{
	bool down;
	bool dragging;
	float last_down_x;
	float last_down_y;

	mousebutton()
		: down(false), dragging(false),
		last_down_x(-1.0f), last_down_y(-1.0f) {}

	// When the button is pressed, call this function with its screen
	// coordinate position.  It returns true if this is a unique event
	bool press( float x, float y)
	{
		if (down) {
			return false;
		}
		down = true;
		last_down_x = x;
		last_down_y = y;
		dragging = false;
		return true;
	}

	// Returns true when a drag event should be generated, false otherwise
	bool is_dragging()
	{
		if (down && !dragging) {
			dragging = true;
			return true;
		}
		return false;
	}

	// Returns (is_unique, is_drop)
	std::pair<bool, bool> release()
	{
		bool unique = down;
		down = false;
		last_down_x = -1;
		last_down_y = -1;
		return std::make_pair(unique, dragging);
	}
};

/*
 * A thin wrapper for buffering cursor visibility information between the python loop
 * and the rendering loop.
 */
class cursor_object
{
 public:
	//mutex mtx;

	bool visible; // whether cursor should be visible
	bool last_visible; // previous state of cursor visibility

	inline cursor_object() : visible(true), last_visible(true) {}
	void set_visible( bool vis) { visible = vis; }
	//bool get_visible() { mutex::lock L(mtx); return visible; }
	bool get_visible() { return visible; }
};

} // !namespace cvisual

#endif // !VPYTHON_MOUSEOBJECT_HPP