Skip to content
Joel de Guzman edited this page Feb 18, 2020 · 18 revisions

The view is the class that represents the content of a window and handles events related to presentation and user interaction. This is the main class that directly deals with the operating system's graphical user interface. The view is cross platform. The view inherits from base_view which implements necessary platform specific code for each supported environment.

We do not normally deal with the base_view class. It is our hook to the operating system. Its interaction is solely with the view and the OS. As such, we will not document the base_view here as it is not part of the client public interface. There are also a number of view member functions that interact with the base_view that the client does not care about. These will not be documented here. (Note to self: these should probably just be private).

The View Class

struct context;
class window;
class idle_tasks;

class view : public base_view
{
public:
                        view(window& win);
                        ~view();

   /***/

   virtual void         refresh() override;
   virtual void         refresh(rect area) override;
   void                 refresh(element& element);
   void                 refresh(context const& ctx);
   rect                 dirty() const;

   struct undo_redo_task
   {
      std::function<void()> undo;
      std::function<void()> redo;
   };

   void                 add_undo(undo_redo_task t);
   bool                 has_undo();
   bool                 has_redo();
   bool                 undo();
   bool                 redo();

   using content_type = layer_composite;
   using layers_type = layer_composite::container_type;

   content_type&        content();
   content_type const&  content() const;
   void                 content(layers_type&& layers);
   void                 add(element_ptr e);
   void                 remove(element_ptr e);

   view_limits          limits() const;

   using change_limits_function = std::function<void(view_limits limits_)>;
   change_limits_function on_change_limits;

   mouse_button         current_button() const;

   using io_context = boost::asio::io_context;
   io_context&          io();

                        template <typename T, typename F>
   void                 post(T duration, F f);

                        template <typename F>
   void                 post(F f);
};

View Member Functions

Constructor

view(window& win);

Construct a view from a window. The view created will be the window's main content view.

refresh

Refresh the entire view:

virtual void         refresh() override;

Refresh an area in the view:

virtual void         refresh(rect area) override;

Refresh a particular element in the view:

void                 refresh(element& element);

Refresh the bounds specified in the given context:

void                 refresh(context const& ctx);

dirty

Check if a view needs to be refreshed:

rect                 dirty() const;

Undo, Redo Functions

The view maintains Undo and Redo stacks. Undo and Redo tasks are generic c++ lambda functions that can be called in order to rewind an element to a prior state or redo what was previously undone. These tasks are captured in the undo_redo_task structure:

struct undo_redo_task
{
   std::function<void()> undo;
   std::function<void()> redo;
};

add_undo

Add Undo and Redo tasks:

void                 add_undo(undo_redo_task t);

has_undo

Check if there's a pending Undo task (i.e. if the Undo stack is not empty):

bool                 has_undo();

has_redo

Check if there's a pending Redo task (i.e. if the Redo stack is not empty):

bool                 has_redo();

undo

Apply the latest Undo task. After application, this Undo task is then added to the top of the Redo stack:

bool                 undo();

redo

Apply the latest Redo task. After application, this Redo task is then added to the top of the Undo stack:

bool                 redo();

Content management

These functions manage the elements contained in the view. The content of the view typically contains multiple layers, much like typical graphics applications. The content is a vector or array like container that holds the layers. The element at index 0 is the bottom-most layer.

content

Get the view's content:

content_type&        content();
content_type const&  content() const;

Set the view's content:

void                 content(layers_type&& layers);

Note that the content is taken by rvalue reference. The typical usage makes use of initializer-lists as shown in this example:

   view_.content(
      {
         share(main_content), // The main content element
         share(background).   // The background element
      }
   );

Take note that the initializer list is taken in reverse, such as the top element is intuitively at the top of the list. Recall that actually, the element at index 0 is the bottom-most layer. The elements in the list are reversed before placing them in the layers' container.

Add or remove elements:

add, remove

void                 add(element_ptr e);
void                 remove(element_ptr e);

When an element is added, it will become the top-most layer. Dynamically adding and removing elements makes it possible to have temporary elements such as pop-up menus.

limits

Get the current view limits. The limits determine the minimum and maximum extents of the view. view_limits is a struct containing the minimum and maximum information.

struct view_limits
{
   point    min;
   point    max;
};

The view has a fixed size if min == max. The view is infinitely resizable if max == full_extent, where full_extent is a constexpr defined by the library.

view_limits          limits() const;

on_change_limits

To get notified when the view limits change, assign a callback function to the view's on_change_limits member:

using change_limits_function = std::function<void(view_limits limits_)>;
change_limits_function on_change_limits;

current_button

Get information about the current mouse button:

mouse_button         current_button() const;

mouse_button is a struct that provides the relevant information.

struct mouse_button
{
   enum what { left, middle, right };

   bool     down;
   int      num_clicks;
   what     state;
   int      modifiers;
   point    pos;
};
  • down: True if the mouse button is pressed, otherwise it is released.
  • num_clicks: The number of clicks (single click, double click, etc.)
  • state: Indicates whether the left, middle or right button is clicked.
  • modifiers: A bit mask that specifies which relevant keys are being pressed at the same time (see below).
  • pos: The current mouse position

The modifiers member is a bit mask with these possible values:

enum : uint16_t
{
   mod_shift         = 0x0001,
   mod_control       = 0x0002,

   // mod_alt maps to the Alt key on PC keyboards
   // and maps to the Option key on MacOS
   mod_alt           = 0x0004,

   // mod_super maps to the Windows key on PC keyboards
   // and maps to the Command key on MacOS
   mod_super         = 0x0008,

   // mod_action maps to mod_control on Windows and Linux
   // and maps to mod_super on MacOS
   mod_action        = 0x0010,
};