Milo  0.1
Milo:EquationManipulationProgram
ui.h
Go to the documentation of this file.
1 #ifndef __UI_H
2 #define __UI_H
3 
4 /* Copyright (C) 2018 - James Terman
5  *
6  * milo is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * milo is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
28 #include <iostream>
29 #include <unordered_map>
30 #include <string>
31 #include <memory>
32 #include "util.h"
33 #include "milo.h"
34 
39 namespace UI {
40  // Forward class declerations
41  class Graphics;
42  class MiloApp;
43  class MiloWindow;
44  class MiloPanel;
45 
54 
59  using menu_handler = void (*)(void);
61 
62  namespace Keys {
67  enum Key_Values {
68  NONE, CTRL_A, CTRL_B, CTRL_C, CTRL_D, CTRL_E, CTRL_F, CTRL_G, CTRL_H,
69  TAB, ENTER, CTRL_K, CTRL_L, CTRL_M, CTRL_N, CTRL_O, CTRL_P, CTRL_Q,
70  CTRL_R, CTRL_S, CTRL_T, CTRL_U, CTRL_V, CTRL_W, CTRL_X, CTRL_Y, CTRL_Z, ESC,
71  SPACE = 32, BANG, DBL_QUOTE, HASH, DOLLAR, PERCENT, AMP, QUOTE, L_PAR, R_PAR,
72  STAR, PLUS, COMMA, MINUS, DOT, DIVIDE, K0, K1, K2, K3, K4, K5, K6, K7, K8, K9,
73  COLON, SEMI, LESS, EQUAL, GREATER, QUESTION, AT, A, B, C, D, E, F, G, H, I, J, K,
74  L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, L_BRACKET, B_SLASH, R_BRACKET,
75  POWER, U_SCORE, ACCENT, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r,
76  s, t, u, v, w, x, y, z, L_BRACE, PIPE, R_BRACE, TILDE,
77  F1 = 0x80, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
78  INS, DEL, HOME, END, PAGE_UP, PAGE_DOWN, UP, DOWN, LEFT, RIGHT, BSPACE
79  };
80  }
81 
82  using Keyboard = Keys::Key_Values;
83 
87  enum Mouse {
88  NO_MOUSE, POSITION, PRESSED, RELEASED, CLICKED, DOUBLE
89  };
90 
94  enum Modifiers {
95  NO_MOD, ALT, SHIFT, ALT_SHIFT, CTRL, CRL_ALT, CTRL_SHIFT, CTRL_ALT_SHIFT
96  };
97 
105  {
106  public:
117  MouseEvent(enum Mouse t, int b, enum Modifiers md = NO_MOD, int mouse_x = -1, int mouse_y = -1) :
118  m_type{t}, m_button{b}, m_mod{md}, m_x{mouse_x}, m_y{mouse_y} {}
120 
126  void setCoords(int mouse_x, int mouse_y) { m_x = mouse_x; m_y = mouse_y; }
127 
130  enum Mouse getMouse() const { return m_type; }
131  int getButton() const { return m_button; }
132  enum Modifiers getModifiers() const { return m_mod; }
133 
139  void getCoords(int& mouse_x, int& mouse_y) const { mouse_x = m_x; mouse_y = m_y; }
140 
145  bool noMod() const { return (m_mod == 0) ? true : false; }
146 
151  bool shiftMod() const { return (m_mod && Modifiers::SHIFT != 0) ? true : false; }
152 
157  bool altMod() const { return (m_mod && Modifiers::ALT != 0) ? true : false; }
158 
162  operator bool() const { return m_type !=NO_MOUSE; }
164 
171  std::size_t hash() const
172  {
173  return hash_calculate<int>({(int) m_type, m_button, (int) m_mod});
174  }
175 
181  bool equals(const MouseEvent& e) const
182  {
183  return e.m_type == m_type &&
184  e.m_button == m_button &&
185  e.m_mod == m_mod;
186  }
187 
194  {
195  m_type = e.m_type;
196  m_button = e.m_button;
197  m_mod = e.m_mod;
198  m_x = e.m_x;
199  m_y = e.m_y;
200  return *this;
201  }
202 
207  std::string toString() const;
209 
210  private:
211  enum Mouse m_type;
212  int m_button;
213  enum Modifiers m_mod;
214  int m_x;
215  int m_y;
216  };
217 
224  inline bool operator==(const MouseEvent& m1, const MouseEvent& m2)
225  {
226  return m1.equals(m2);
227  }
228 
235  class KeyEvent
236  {
237  public:
245  KeyEvent(Keyboard key, enum Modifiers md = NO_MOD) : m_key{key}, m_mod{md} {}
246 
252  KeyEvent(char key, enum Modifiers md = NO_MOD) : KeyEvent((Keyboard) key, md) {}
253 
258  KeyEvent(const std::string& key);
259 
263  constexpr KeyEvent(const KeyEvent& e) : m_key(e.m_key), m_mod(e.m_mod) {}
265 
268  Keyboard getKey() const { return m_key; }
269  enum Modifiers getModifiers() const { return m_mod; }
270 
275  bool noMod() const { return (m_mod == 0) ? true : false; }
276 
281  bool shiftMod() const { return (m_mod && Modifiers::SHIFT != 0) ? true : false; }
282 
287  bool altMod() const { return (m_mod && Modifiers::ALT != 0) ? true : false; }
288 
292  operator bool() const { return m_key != Keys::NONE; }
294 
301  std::size_t hash() const
302  {
303  return hash_calculate<int>({(int) m_key, (int) m_mod});
304  }
305 
311  bool equals(const KeyEvent e) const
312  {
313  return e.m_key == m_key &&
314  e.m_mod == m_mod;
315  }
316 
323  {
324  m_key = e.m_key;
325  m_mod = e.m_mod;
326  return *this;
327  }
328 
333  std::string toString() const;
335 
336  private:
338  enum Modifiers m_mod;
339  };
340 
347  inline bool operator==(const KeyEvent& k1, const KeyEvent& k2)
348  {
349  return k1.equals(k2);
350  }
351 
357  class Graphics {
358  public:
364  Graphics() {}
365 
369  virtual ~Graphics() {}
371 
375  enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
376 
380  enum Attributes { NONE=0, BOLD=1, ITALIC=2, BOLD_ITALIC=3 };
381 
390  virtual void differential(int x0, int y0, char variable)=0;
391 
399  virtual void parenthesis(int x_size, int y_size, int x0, int y0)=0;
400 
407  virtual void horiz_line(int x_size, int x0, int y0)=0;
408 
417  virtual void at(int x0, int y0, int c, Attributes chrAttr, Color color = BLACK)=0;
418 
427  virtual void at(int x0, int y0, const std::string& s, Attributes chrAttr, Color color = BLACK)=0;
428 
432  virtual void clear_screen()=0;
433 
437  virtual void out()=0;
438 
443  virtual int getTextHeight()=0;
444 
449  virtual int getTextLength(const std::string& s)=0;
450 
455  virtual int getCharLength(char c)=0;
456 
461  virtual int getParenthesisWidth(int height = 1)=0;
462 
467  virtual int getDivideLineHeight()=0;
468 
474  virtual int getDifferentialHeight(char c)=0;
475 
481  virtual int getDifferentialWidth(char c)=0;
482 
488  virtual int getDifferentialBase(char c)=0;
489 
497  virtual void set(int x, int y, int x0 = 0, int y0 = 0) {
498  m_xSize = x; m_ySize = y; m_xOrig = x0, m_yOrig = y0;
499  }
500 
508  virtual void setSelect(int x, int y, int x0, int y0) { m_select.set(x, y, x0, y0); }
510 
517  void set(const Box& box) {
518  set(box.width(), box.height(), box.x0(), box.y0());
519  }
520 
525  void setSelect(const Box& box) {
526  setSelect(box.width(), box.height(), box.x0(), box.y0());
527  }
528 
533  void parenthesis(const Box& box) {
534  parenthesis(box.width(), box.height(), box.x0(), box.y0());
535  }
536 
542  void relativeOrig(int& x, int& y) { x -= m_xOrig; y -= m_yOrig; }
544 
545  protected:
546  int m_xSize;
547  int m_ySize;
548  int m_xOrig;
549  int m_yOrig;
551  };
552 
559  template <class T> MiloPanelPtr createPanel(const std::string& init)
560  {
561  return MiloPanelPtr(new T(init));
562  }
563 
564  using panel_factory = MiloPanelPtr (*)(const std::string&);
565 
569  class MiloPanel
570  {
571  public:
577 
582 
589  virtual void doKey(const UI::KeyEvent& key) = 0;
590 
595  virtual void doMouse(const UI::MouseEvent& mouse) = 0;
596 
602  virtual bool doMenu(const std::string& menuFunctionName) = 0;
603 
606  virtual void doDraw() = 0;
607 
611  virtual void pushUndo()=0;
612 
616  virtual void popUndo()=0;
617 
622  virtual void saveState(std::ostream& fs) = 0;
623 
628  virtual void loadState(std::istream& is) = 0;
629 
634  void saveState(const std::string& filename) {
635  std::fstream out(filename, std::fstream::out | std::fstream::trunc);
636  saveState(out);
637  }
638 
643  void loadState(const std::string& filename) {
644  std::ifstream ifs(filename);
645  loadState(ifs);
646  }
647 
652  virtual bool blink() = 0;
653 
659  virtual void getCursorOrig(int& x, int& y) = 0;
661 
668  static MiloPanelPtr makePanel(const std::string& name, const std::string& init);
669 
670  protected:
671  static std::unordered_map<std::string, panel_factory> panel_map;
672  };
673 
678  {
679  public:
682 
687  m_panels({panel}), m_current_panel(m_panels.begin()) {}
688 
689  MiloWindow();
690 
694  virtual ~MiloWindow() {}
696 
703  MiloPanel& getPanel() { return *(m_current_panel->get()); }
704 
710  m_current_panel = AddAfter(m_panels, m_current_panel, panel);
711  }
712 
718  m_current_panel = m_panels.erase(it);
719  }
720 
724  void deletePanel() {
725  m_current_panel = m_panels.erase(m_current_panel);
726  }
728 
734  virtual void makeTopWindow()=0;
736 
737  protected:
740  };
741 
745  class MiloApp
746  {
747  public:
753  virtual void redraw_screen()=0;
754 
759  virtual Graphics& getGraphics()=0;
761 
767  void doMenu(const std::string& menuFunctionName);
768 
773  static bool isRunning();
774 
779  MiloWindow& getWindow() { return *(m_current_window->get()); }
780 
786  m_current_window = AddAfter(m_windows, m_current_window, win);
787  }
788 
792  void closeWindow() {
793  m_current_window = m_windows.erase(m_current_window);
794  }
795 
801  m_current_window = m_windows.erase(it);
802  }
804 
809  static MiloApp& getGlobal() { return m_current; }
810 
811  protected:
814 
818  MiloApp() {}
819 
825  m_windows({win}), m_current_window(m_windows.begin()) {}
826 
830  ~MiloApp() {}
832 
835 
836  static MiloApp& m_current;
837 
838  private:
839 
843  static std::unordered_map<std::string, menu_handler> menu_map;
844  };
845 
849  class MenuXML
850  {
851  public:
858  virtual void define_menu(const StringMap& attributes)=0;
859 
864  virtual void define_menu_end(const std::string& name)=0;
865 
870  virtual void define_menu_item(const StringMap& attributes)=0;
871 
875  virtual void define_menu_line()=0;
877 
885  void parse_menu(XML::Parser& in);
887  };
888 }
889 
890 namespace std
891 {
895  template<> struct hash<UI::KeyEvent>
896  {
897  size_t operator()(UI::KeyEvent const& key) const
898  {
899  return key.hash();
900  }
901  };
902 
906  template<> struct hash<UI::MouseEvent>
907  {
908  size_t operator()(UI::MouseEvent const& key) const
909  {
910  return key.hash();
911  }
912  };
913 }
914 
915 #endif // __UI_H
bool equals(const KeyEvent e) const
Definition: ui.h:311
bool shiftMod() const
Definition: ui.h:281
static MiloApp & getGlobal()
Definition: ui.h:809
void closeWindow()
Definition: ui.h:792
Definition: smart.h:38
static std::unordered_map< std::string, menu_handler > menu_map
Definition: ui.h:843
void saveState(const std::string &filename)
Definition: ui.h:634
int m_ySize
Vertical size of graphic window.
Definition: ui.h:547
Definition: ui.h:569
int & x0()
Definition: util.h:237
int m_xSize
Horizontal size of graphic window.
Definition: ui.h:546
static std::unordered_map< std::string, panel_factory > panel_map
Map of name to panel create functions.
Definition: ui.h:671
virtual void setSelect(int x, int y, int x0, int y0)
Definition: ui.h:508
Definition: milo.h:45
void setSelect(const Box &box)
Definition: ui.h:525
MiloWindowIter m_current_window
Current active window.
Definition: ui.h:834
void addPanel(MiloPanelPtr panel)
Definition: ui.h:709
MiloWindow & getWindow()
Definition: ui.h:779
MiloWindow(MiloPanelPtr panel)
Definition: ui.h:686
bool equals(const MouseEvent &e) const
Definition: ui.h:181
int & y0()
Definition: util.h:243
KeyEvent & operator=(const KeyEvent &e)
Definition: ui.h:322
typename std::vector< SmartPtr< MiloWindow > >::iterator iterator
Definition: smart.h:88
Definition: test.cpp:48
MouseEvent & operator=(const MouseEvent &e)
Definition: ui.h:193
Mouse
Definition: ui.h:87
enum Modifiers m_mod
Modifiers state.
Definition: ui.h:213
int getButton() const
Definition: ui.h:131
void setCoords(int mouse_x, int mouse_y)
Definition: ui.h:126
MiloWindowVector::iterator MiloWindowIter
Iterator of MiloWindow pointers vector.
Definition: ui.h:50
MiloPanelIter m_current_panel
Current active panel.
Definition: ui.h:739
int m_button
Number of button pressed.
Definition: ui.h:212
Definition: ui.h:104
KeyEvent(Keyboard key, enum Modifiers md=NO_MOD)
Definition: ui.h:245
bool noMod() const
Definition: ui.h:275
Modifiers
Definition: ui.h:94
Graphics()
Definition: ui.h:364
int m_y
mouse y-coordinate.
Definition: ui.h:215
EqnPanel panel
Asciigraphics class objects.
Definition: milo_test.cpp:265
std::size_t hash() const
Definition: ui.h:301
Definition: ui.h:677
std::size_t hash() const
Definition: ui.h:171
void deletePanel(MiloPanelIter it)
Definition: ui.h:717
bool noMod() const
Definition: ui.h:145
void(*)(void) menu_handler
Definition: ui.h:59
MiloPanelVector::iterator MiloPanelIter
Iterator of MiloPanel pointers vector.
Definition: ui.h:53
Keyboard getKey() const
Definition: ui.h:268
Definition: ui.h:235
void getCoords(int &mouse_x, int &mouse_y) const
Definition: ui.h:139
std::unordered_map< std::string, std::string > StringMap
hash map for string => string
Definition: util.h:363
Definition: ui.h:745
int & height()
Definition: util.h:255
Keyboard m_key
Key code.
Definition: ui.h:337
void closeWindow(MiloWindowIter it)
Definition: ui.h:800
enum Modifiers m_mod
Modifiers state.
Definition: ui.h:338
KeyEvent(char key, enum Modifiers md=NO_MOD)
Definition: ui.h:252
enum Mouse m_type
Mouse click type.
Definition: ui.h:211
void addWindow(MiloWindowPtr win)
Definition: ui.h:785
Attributes
Definition: ui.h:380
Definition: xml.h:235
bool altMod() const
Definition: ui.h:287
Definition: ui.h:357
MiloApp(MiloWindowPtr win)
Definition: ui.h:824
MiloPanelVector m_panels
List of panels for this window.
Definition: ui.h:738
static MiloApp & m_current
Reference to current application singleton.
Definition: ui.h:836
Box m_select
Currently selected area.
Definition: ui.h:550
SmartPtr< MiloPanel > MiloPanelPtr
Smart pointer for MiloPanel.
Definition: ui.h:51
MiloPanel & getPanel()
Definition: ui.h:703
int m_xOrig
Horizontal origin of graphic window.
Definition: ui.h:548
int m_x
mouse x-coordinate.
Definition: ui.h:214
void relativeOrig(int &x, int &y)
Definition: ui.h:542
int m_yOrig
Vertical origin of graphic window.
Definition: ui.h:549
~MiloPanel()
Definition: ui.h:580
void deletePanel()
Definition: ui.h:724
virtual ~MiloWindow()
Definition: ui.h:694
MiloPanel()
Definition: ui.h:576
MouseEvent(enum Mouse t, int b, enum Modifiers md=NO_MOD, int mouse_x=-1, int mouse_y=-1)
Definition: ui.h:117
int & width()
Definition: util.h:249
MiloPanelPtr createPanel(const std::string &init)
Definition: ui.h:559
MiloWindowVector m_windows
List of windows for this application.
Definition: ui.h:833
bool operator==(const MouseEvent &m1, const MouseEvent &m2)
Definition: ui.h:224
void loadState(const std::string &filename)
Definition: ui.h:643
~MiloApp()
Definition: ui.h:830
auto AddAfter(std::vector< T > &v, decltype(v.begin()) it, const T &elem) -> decltype(v.begin())
Definition: util.h:147
void parenthesis(const Box &box)
Definition: ui.h:533
constexpr KeyEvent(const KeyEvent &e)
Definition: ui.h:263
bool altMod() const
Definition: ui.h:157
Key_Values
Definition: ui.h:67
Color
Definition: ui.h:375
bool shiftMod() const
Definition: ui.h:151
MiloApp()
Definition: ui.h:818
Definition: ui.h:849
virtual ~Graphics()
Definition: ui.h:369