Allolib  1.0
C++ Components For Interactive Multimedia
al_Window.hpp
1 #ifndef INCLUDE_AL_WINDOW_HPP
2 #define INCLUDE_AL_WINDOW_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  An interface to an OS window
40 
41  File author(s):
42  Lance Putnam, 2010, putnam.lance@gmail.com
43  Graham Wakefield, 2010, grrrwaaa@gmail.com
44  Wesley Smith, 2010, wesley.hoke@gmail.com
45  Keehong Youn, 2017, younkeehong@gmail.com
46 */
47 
48 #include <stdio.h>
49 
50 #include <algorithm>
51 #include <functional>
52 #include <iostream>
53 #include <memory>
54 #include <string>
55 #include <vector>
56 
57 #ifdef AL_WINDOWS
58 #undef DELETE
59 #endif
60 
61 namespace al {
62 
63 class Window;
64 
65 // can redefine, but should be at least 4
66 #ifndef AL_MOUSE_MAX_BUTTONS
67 #define AL_MOUSE_MAX_BUTTONS 4
68 #endif
69 
73 class Keyboard {
74  public:
76  enum Key {
77 
78  // Standard ASCII non-printable characters
79  ENTER = 3,
80  BACKSPACE = 8,
81  TAB = 9,
82  RETURN = 13,
83  ESCAPE = 27,
84  DELETE = 127,
86  // Non-standard, but common keys
87  F1 = 256,
88  F2,
89  F3,
90  F4,
91  F5,
92  F6,
93  F7,
94  F8,
95  F9,
96  F10,
97  F11,
98  F12,
99  INSERT,
100  LEFT,
101  UP,
102  RIGHT,
103  DOWN,
104  PAGE_DOWN,
105  PAGE_UP,
106  END,
107  HOME
108  };
109 
110  Keyboard();
111 
112  int key() const;
113  int keyAsNumber() const;
114  bool alt() const;
115  bool caps() const;
116  bool ctrl() const;
117  bool meta() const;
118  bool shift() const;
119  bool down() const;
120  bool isNumber() const;
121  bool key(int k) const;
122 
123  void alt(bool state);
124  void caps(bool state);
125  void ctrl(bool state);
126  void meta(bool state);
127  void shift(bool state);
128 
129  void print(std::ostream &stream) const;
130 
131  protected:
132  friend class WindowImpl;
133 
134  int mKeycode; // last key event key number
135  bool mDown; // last key event state (pressed or released)
136  bool
137  mModifiers[5]; // Modifier key state array (shift, alt, ctrl, caps, meta)
138 
139  void setKey(int k, bool v);
140 };
141 
145 class Mouse {
146  public:
147  enum {
148  LEFT = 0,
149  MIDDLE = 1,
150  RIGHT = 2,
151  EXTRA = 3
152  };
153 
154  Mouse();
155 
156  int x() const;
158  int y() const;
160  int dx() const;
161  int dy() const;
162  double scrollX() const;
163  double scrollY() const;
164 
165  int button() const;
166  bool down() const;
167  bool down(int button) const;
168  bool left() const;
169  bool middle() const;
170  bool right() const;
171 
172  protected:
173  friend class WindowImpl;
174 
175  int mX, mY; // x,y positions
176  int mDX, mDY; // change in x,y positions
177  double mScrollX, mScrollY; // scroll motion
178  int mButton; // most recent button changed
179  int mBX[AL_MOUSE_MAX_BUTTONS]; // button down xs
180  int mBY[AL_MOUSE_MAX_BUTTONS]; // button down ys
181  bool mB[AL_MOUSE_MAX_BUTTONS]; // button states
182 
183  void button(int b, bool v);
184  void position(int x, int y);
185  void scroll(double x, double y);
186 };
187 
189 
195  public:
197  virtual ~WindowEventHandler();
198 
200  virtual bool keyDown(const Keyboard &k) { return true; }
201 
203  virtual bool keyUp(const Keyboard &k) { return true; }
204 
206  virtual bool mouseDown(const Mouse &m) { return true; }
207 
209  virtual bool mouseDrag(const Mouse &m) { return true; }
210 
212  virtual bool mouseMove(const Mouse &m) { return true; }
213 
215  virtual bool mouseUp(const Mouse &m) { return true; }
216 
218  virtual bool mouseScroll(const Mouse &m) { return true; }
219 
221  virtual bool resize(int dw, int dh) { return true; }
222 
224  virtual bool visibility(bool v) { return true; }
225 
228 
229  bool attached() const { return NULL != mWindow; }
230  Window &window() { return *mWindow; }
231  const Window &window() const { return *mWindow; }
232 
233  Window *mWindow;
234 
235  private:
236  friend class Window;
237  WindowEventHandler &window(Window *v) {
238  mWindow = v;
239  return *this;
240  }
241  void removeFromWindow();
242 };
243 
245 
250 // class Window : public InputEventHandler, public WindowEventHandler {
251 class Window {
252  public:
253  typedef std::vector<WindowEventHandler *> WindowEventHandlers;
254 
256  enum DisplayMode : unsigned int {
257  SINGLE_BUF = 1 << 0,
258  DOUBLE_BUF = 1 << 1,
259  STEREO_BUF = 1 << 2,
260  ACCUM_BUF = 1 << 3,
261  ALPHA_BUF = 1 << 4,
262  DEPTH_BUF = 1 << 5,
263  STENCIL_BUF = 1 << 6,
264  MULTISAMPLE = 1 << 7,
265  DEFAULT_BUF =
267  };
268 
270  enum Cursor {
271  NONE = 0,
272  POINTER = 1,
273  CROSSHAIR
274  };
275 
277  struct Dim {
278  int l, t, w, h;
279  Dim(int v = 0) : l(0), t(0), w(v), h(v) {}
280  Dim(int w_, int h_) : l(0), t(0), w(w_), h(h_) {}
281  Dim(int l_, int t_, int w_, int h_) : l(l_), t(t_), w(w_), h(h_) {}
282  void set(int l_, int t_, int w_, int h_) {
283  l = l_;
284  t = t_;
285  w = w_;
286  h = h_;
287  }
288 
289  float aspect() const { return (w != 0 && h != 0) ? float(w) / h : 1; }
290  void print() const { printf("Dim: %4d x %4d @ (%4d, %4d)\n", w, h, l, t); }
291  };
292 
293  Window();
294  virtual ~Window();
295 
300  bool create(bool is_verbose = false);
301 
302  void makeCurrent();
303  // refresh window (swap buffers, poll events, etc.)
304  void refresh();
305 
306  void close();
307  bool shouldClose();
308 
310  void destroy();
311 
312  const Keyboard &keyboard() const {
313  return mKeyboard;
314  }
315  const Mouse &mouse() const { return mMouse; }
316 
317  double aspect() const;
318  bool created() const;
320  Cursor cursor() const;
321  bool cursorHide() const;
322  Dim dimensions() const;
324  bool enabled(DisplayMode v) const;
325  bool fullScreen() const;
326  const std::string &title() const;
327  bool visible() const;
328  bool vsync() const;
329 
330  int height() const;
331  int width() const;
332 
333  // get frambuffer size
334  // it will be different from window widht and height
335  // if the display is a high resolution one (ex: RETINA display)
336  int fbHeight() const;
337  int fbWidth() const;
338 
339  float highres_factor() { return mHighresFactor; }
340 
341  bool decorated() const;
342 
343  void cursor(Cursor v);
344  void cursorHide(bool v);
346  void dimensions(const Dim &v);
347  void dimensions(int w, int h);
348  void dimensions(int x, int y, int w, int h);
351 
354  void fullScreen(bool on, int monitorIndex = 0);
356  void hide();
357  void iconify();
358  // void show(); ///< Show window (if hidden)
359  void title(const std::string &v);
360  void vsync(bool v);
362  void decorated(bool b);
363 
364  // callbacks from window class, will call user event functions like `on***`
365  // return false is the event has been consumed and should not propagate
366  // further.
367 
368  std::function<bool(Keyboard const &)> onKeyDown = [](Keyboard const &) {
369  return true;
370  };
371  std::function<bool(Keyboard const &)> onKeyUp = [](Keyboard const &) {
372  return true;
373  };
374  std::function<bool(Mouse const &)> onMouseDown = [](Mouse const &) {
375  return true;
376  };
377  std::function<bool(Mouse const &)> onMouseUp = [](Mouse const &) {
378  return true;
379  };
380  std::function<bool(Mouse const &)> onMouseDrag = [](Mouse const &) {
381  return true;
382  };
383  std::function<bool(Mouse const &)> onMouseMove = [](Mouse const &) {
384  return true;
385  };
386  std::function<bool(Mouse const &)> onMouseScroll = [](Mouse const &) {
387  return true;
388  };
389  std::function<void(int, int)> onResize = [](int, int) {};
390 
391  WindowEventHandlers &windowEventHandlers() { return mWindowEventHandlers; }
392 
396 
400 
403 
405  static void destroyAll();
406 
407  Keyboard mKeyboard;
408  Mouse mMouse;
409  WindowEventHandlers mWindowEventHandlers;
410  Dim mDim{50, 50, 640, 480};
411  Dim mFullScreenDim{0};
412  DisplayMode mDisplayMode = DEFAULT_BUF;
413  std::string mTitle = "allolib";
414  Cursor mCursor = POINTER;
415  bool mCursorHide = false;
416  bool mFullScreen = false;
417  bool mVisible = false;
418  bool mVSync = true;
419  bool mDecorated = true;
420 
421  // for high pixel density monitors (RETINA, etc.)
422  float mHighresFactor = 0;
423  int mFramebufferWidth = 0;
424  int mFramebufferHeight = 0;
425 
426  protected:
427  friend class WindowImpl;
428 
429  // class WindowImpl * mImpl;
430  std::unique_ptr<class WindowImpl> mImpl;
431 
432  // Must be defined in pimpl-specific file
433  bool implCreate(bool is_verbose = false);
434  bool implCreated() const;
435  void implMakeCurrent();
436  void implRefresh();
437  void implDestroy();
438  void implSetCursor();
439  void implSetCursorHide();
440  void implSetDimensions();
441  void implSetFullScreen(int monitorIndex = 0);
442  void implSetTitle();
443  void implSetVSync();
444  void implHide();
445  void implIconify();
446  void implSetDecorated(bool decorated);
447  bool implShouldClose();
448  void implClose();
449 
450  Window &insert(WindowEventHandler &v, int i);
451 
452 #define CALL(e) \
453  { \
454  for (unsigned i = 0; i < mWindowEventHandlers.size(); ++i) { \
455  if (false == mWindowEventHandlers[i]->e) break; \
456  } \
457  }
458  void callHandlersMouseDown() {
459  CALL(mouseDown(mMouse));
460  onMouseDown(mMouse);
461  }
462  void callHandlersMouseDrag() {
463  CALL(mouseDrag(mMouse));
464  onMouseDrag(mMouse);
465  }
466  void callHandlersMouseMove() {
467  CALL(mouseMove(mMouse));
468  onMouseMove(mMouse);
469  }
470  void callHandlersMouseUp() {
471  CALL(mouseUp(mMouse));
472  onMouseUp(mMouse);
473  }
474  void callHandlersMouseScroll() {
475  CALL(mouseScroll(mMouse));
476  onMouseScroll(mMouse);
477  }
478  void callHandlersKeyDown() {
479  CALL(keyDown(mKeyboard));
480  onKeyDown(mKeyboard);
481  }
482  void callHandlersKeyUp() {
483  CALL(keyUp(mKeyboard));
484  onKeyUp(mKeyboard);
485  }
486  void callHandlersResize(int w, int h) {
487  CALL(resize(w, h));
488  onResize(w, h);
489  }
490  void callHandlersVisibility(bool v) { CALL(visibility(v)); }
491 #undef CALL
492 
493  public:
494  // [[deprecated]] Window& add(WindowEventHandler* v) { return append(*v); }
495  // [[deprecated]] Window& prepend(WindowEventHandler* v) { return
496  // prepend(*v); }
497  // [[deprecated]] Window& remove(WindowEventHandler* v) { return remove(*v);
498  // }
499 };
500 
501 inline Window::DisplayMode operator|(const Window::DisplayMode &a,
502  const Window::DisplayMode &b) {
503  return Window::DisplayMode(+a | +b);
504 }
505 
506 inline Window::DisplayMode operator&(const Window::DisplayMode &a,
507  const Window::DisplayMode &b) {
508  return Window::DisplayMode(+a & +b);
509 }
510 
511 void initializeWindowManager();
512 void terminateWindowManager();
513 float getCurrentWindowPixelDensity();
514 
515 } // namespace al
516 
517 #endif
bool down() const
Whether last event was button down.
void ctrl(bool state)
Set ctrl key state.
void caps(bool state)
Set alt key state.
void meta(bool state)
Set meta key state.
bool ctrl() const
Whether a control key is down.
void shift(bool state)
Set shift key state.
int keyAsNumber() const
Returns decimal number correlating to key code.
void alt(bool state)
Set alt key state.
Key
Non-printable keys.
Definition: al_Window.hpp:76
bool alt() const
Whether an alt key is down.
bool caps() const
Whether capslock is down.
void print(std::ostream &stream) const
Print keyboard state.
bool shift() const
Whether a shift key is down.
bool meta() const
Whether a meta (e.g. windows, apple) key is down.
bool isNumber() const
Whether key is a number key.
bool key(int k) const
Whether the last key was 'k'.
int key() const
Returns character or code of last key event.
int x() const
bool left() const
Get whether left button is down.
bool down(int button) const
Get state of a button.
int dx() const
Get change in x position, in pixels.
int button() const
Get last clicked button.
int y() const
bool down() const
Get state of last clicked button.
double scrollX() const
Get x scroll amount.
double scrollY() const
Get y scroll amount.
bool right() const
Get whether right button is down.
int dy() const
Get change in y position, in pixels.
bool middle() const
Get whether middle button is down.
Controller for handling input and window events.
Definition: al_Window.hpp:194
virtual bool keyDown(const Keyboard &k)
Called when a keyboard key is pressed.
Definition: al_Window.hpp:200
virtual bool mouseUp(const Mouse &m)
Called when a mouse button is released.
Definition: al_Window.hpp:215
virtual bool mouseMove(const Mouse &m)
Called when the mouse moves.
Definition: al_Window.hpp:212
virtual bool resize(int dw, int dh)
Called whenever window dimensions change.
Definition: al_Window.hpp:221
virtual bool mouseDown(const Mouse &m)
Called when a mouse button is pressed.
Definition: al_Window.hpp:206
virtual bool keyUp(const Keyboard &k)
Called when a keyboard key is released.
Definition: al_Window.hpp:203
virtual bool mouseScroll(const Mouse &m)
Called when mouse scrolled.
Definition: al_Window.hpp:218
virtual bool mouseDrag(const Mouse &m)
Called when the mouse moves while a button is down.
Definition: al_Window.hpp:209
virtual bool visibility(bool v)
Called when window changes from hidden to shown and vice versa.
Definition: al_Window.hpp:224
WindowEventHandler & windowEventHandler()
Return self.
Definition: al_Window.hpp:227
Window with OpenGL context.
Definition: al_Window.hpp:251
int height() const
Get window height, in pixels.
void fullScreenToggle()
Toggle fullscreen.
bool cursorHide() const
Whether the cursor is hidden.
const std::string & title() const
Get title of window.
void displayMode(DisplayMode v)
Cursor
Cursor icon types.
Definition: al_Window.hpp:270
DisplayMode displayMode() const
Get current display mode.
void hide()
Hide window (if showing)
Window & prepend(WindowEventHandler &v)
static void destroyAll()
Destroy all created windows.
const Keyboard & keyboard() const
Get current keyboard state.
Definition: al_Window.hpp:312
bool enabled(DisplayMode v) const
Get whether display mode flag is set.
void cursor(Cursor v)
Set cursor type.
double aspect() const
Get aspect ratio (width divided by height)
void dimensions(int w, int h)
Set dimensions.
Window & append(WindowEventHandler &v)
int width() const
Get window width, in pixels.
Dim dimensions() const
Get current dimensions of window.
Window & remove(WindowEventHandler &v)
Remove all window event handlers matching argument.
const Mouse & mouse() const
Get current mouse state.
Definition: al_Window.hpp:315
void dimensions(int x, int y, int w, int h)
Set dimensions.
void cursorHideToggle()
Toggle cursor hiding.
bool created() const
bool create(bool is_verbose=false)
void vsync(bool v)
void title(const std::string &v)
Set title.
void fullScreen(bool on, int monitorIndex=0)
void dimensions(const Dim &v)
Set dimensions.
bool visible() const
Get whether window is visible.
bool fullScreen() const
Get whether window is in fullscreen.
void iconify()
Iconify window.
bool vsync() const
Get whether v-sync is enabled.
DisplayMode
Window display mode bit flags.
Definition: al_Window.hpp:256
Cursor cursor() const
Get current cursor type.
void destroy()
Destroy current window and its associated graphics context.
void cursorHide(bool v)
Set cursor hiding.
Definition: al_App.hpp:23
Window pixel dimensions.
Definition: al_Window.hpp:277