summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2017-09-10 17:52:32 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2018-06-08 19:29:07 +0200
commit0531409611867ae8dad711e52d6534fa634d40cc (patch)
treeac2bf00c7db33eb15ef98e6a63bf3ff7c03d073e /plugingui
parentd866740fee61bdf1bbbb539bf9856b99e8152d89 (diff)
Initial steps towards pugl domination!
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/Makefile.am38
-rw-r--r--plugingui/nativewindow.h4
-rw-r--r--plugingui/nativewindow_pugl.cc372
-rw-r--r--plugingui/nativewindow_pugl.h45
-rw-r--r--plugingui/nativewindow_win32.cc4
-rw-r--r--plugingui/nativewindow_win32.h4
-rw-r--r--plugingui/nativewindow_x11.cc29
-rw-r--r--plugingui/nativewindow_x11.h4
8 files changed, 327 insertions, 173 deletions
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index 714b21c..f9d9c09 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -42,6 +42,8 @@ libdggui_la_CPPFLAGS = \
-DLODEPNG_NO_COMPILE_ERROR_TEXT \
-DLODEPNG_NO_COMPILE_CPP
+libdggui_la_CFLAGS =
+
libdggui_la_LIBADD = \
$(GUI_LIBS) $(PTHREAD_LIBS)
@@ -110,18 +112,42 @@ nodist_libdggui_la_SOURCES += \
nativewindow_win32.cc
endif
-if ENABLE_PUGL
-nodist_libdggui_la_SOURCES += \
- nativewindow_pugl.cc \
- $(top_srcdir)/pugl/pugl/pugl_x11.c
-endif
-
#if ENABLE_COCOA
#nodist_libdggui_la_SOURCES += \
# nativewindow_cocoa.m \
# nativewindow_cocoa.cc
#endif
+if ENABLE_PUGL_X11
+nodist_libdggui_la_SOURCES += \
+ nativewindow_pugl.cc \
+ $(top_srcdir)/pugl/pugl/pugl_x11.c
+
+libdggui_la_CPPFLAGS += \
+ -I$(top_srcdir)/pugl
+
+libdggui_la_CFLAGS += \
+ -std=c99
+endif
+
+if ENABLE_PUGL_WIN32
+nodist_libdggui_la_SOURCES += \
+ nativewindow_pugl.cc \
+ $(top_srcdir)/pugl/pugl/pugl_win.cpp
+
+libdggui_la_CPPFLAGS += \
+ -I$(top_srcdir)/pugl
+endif
+
+if ENABLE_PUGL_COCOA
+nodist_libdggui_la_SOURCES += \
+ nativewindow_pugl.cc \
+ $(top_srcdir)/pugl/pugl/pugl_osx.m
+
+libdggui_la_CPPFLAGS += \
+ -I$(top_srcdir)/pugl
+endif
+
plugingui_LDADD = libdggui.la $(top_srcdir)/src/libdg.la
plugingui_CXXFLAGS = $(SNDFILE_CXXFLAGS) $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) \
diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h
index 6dcb308..3995d43 100644
--- a/plugingui/nativewindow.h
+++ b/plugingui/nativewindow.h
@@ -52,7 +52,7 @@ public:
virtual void resize(std::size_t width, std::size_t height) = 0;
//! Query size of the native window.
- virtual std::pair<std::size_t, std::size_t> getSize() = 0;
+ virtual std::pair<std::size_t, std::size_t> getSize() const = 0;
//! Move the window to a new position.
//! Note: negative value are allowed.
@@ -60,7 +60,7 @@ public:
//! Query the screen position of the native window.
//! Note: returned values can be negative.
- virtual std::pair<int, int> getPosition() = 0;
+ virtual std::pair<int, int> getPosition() const = 0;
//! Show the window if it is hidden.
virtual void show() = 0;
diff --git a/plugingui/nativewindow_pugl.cc b/plugingui/nativewindow_pugl.cc
index d7cca54..59f03b1 100644
--- a/plugingui/nativewindow_pugl.cc
+++ b/plugingui/nativewindow_pugl.cc
@@ -42,46 +42,284 @@
#include <hugin.hpp>
-namespace GUI {
+namespace GUI
+{
+
+NativeWindowPugl::NativeWindowPugl(void* native_window, Window& window)
+ : window(window)
+{
+ INFO(nativewindow, "Running with PuGL native window\n");
+ view = puglInit(nullptr, nullptr);
+ puglInitContextType(view, PUGL_GL);
+ if(native_window)
+ {
+ puglInitWindowParent(view, (PuglNativeWindow)native_window);
+ }
+ puglInitWindowClass(view, "DrumgGizmo");
+ puglInitWindowSize(view, 750, 466);
+ puglInitResizable(view, true);
+ puglCreateWindow(view, "DrumGizmo");
+
+ puglSetHandle(view, (PuglHandle)this);
+ puglSetEventFunc(view, onEvent);
+}
+
+NativeWindowPugl::~NativeWindowPugl()
+{
+ puglDestroy(view);
+}
+
+void NativeWindowPugl::setFixedSize(std::size_t width, std::size_t height)
+{
+// redraw();
+}
+
+void NativeWindowPugl::resize(std::size_t width, std::size_t height)
+{
+// DEBUG(nativewindow_pugl, "Resizing to %dx%d\n", width, height);
+// init();
+// redraw();
+}
+
+std::pair<std::size_t, std::size_t> NativeWindowPugl::getSize() const
+{
+ int width, height;
+ puglGetSize(view, &width, &height);
+ return {width, height};
+}
+
+void NativeWindowPugl::move(int x, int y)
+{
+// redraw();
+}
+
+void NativeWindowPugl::show()
+{
+ puglShowWindow(view);
+}
+
+void NativeWindowPugl::hide()
+{
+ puglHideWindow(view);
+}
+
+bool NativeWindowPugl::visible() const
+{
+ return puglGetVisible(view);
+}
+
+void NativeWindowPugl::redraw(const Rect& dirty_rect)
+{
+ //puglPostRedisplay(view);// handleBuffer();
+ onDisplay(view);
+}
+
+void NativeWindowPugl::setCaption(const std::string &caption)
+{
+// redraw();
+}
+
+void NativeWindowPugl::grabMouse(bool grab)
+{
+ puglGrabFocus(view);
+}
+
+EventQueue NativeWindowPugl::getEvents()
+{
+ puglProcessEvents(view);
+ EventQueue events;
+ std::swap(events, event_queue);
+ return events;
+}
+
+void* NativeWindowPugl::getNativeWindowHandle() const
+{
+ return (void*)puglGetNativeWindow(view);
+}
+
+void NativeWindowPugl::onEvent(PuglView* view, const PuglEvent* event)
+{
+ NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view);
+
+ switch(event->type)
+ {
+ case PUGL_NOTHING:
+ break;
+ case PUGL_CONFIGURE:
+ onReshape(view, event->configure.width, event->configure.height);
+ {
+ auto resize_event = std::make_shared<ResizeEvent>();
+ resize_event->width = event->configure.width;
+ resize_event->height = event->configure.height;
+ native->event_queue.push_back(resize_event);
+ }
+ break;
+ case PUGL_EXPOSE:
+ onDisplay(view);
+ break;
+ case PUGL_CLOSE:
+ //quit = 1;
+ break;
+ case PUGL_KEY_PRESS:
+ fprintf(stderr, "Key %u (char %u) press (%s)%s\n",
+ event->key.keycode, event->key.character, event->key.utf8,
+ event->key.filter ? " (filtered)" : "");
+ if (event->key.character == 'q' ||
+ event->key.character == 'Q' ||
+ event->key.character == PUGL_CHAR_ESCAPE) {
+ //quit = 1;
+ }
+ break;
+ case PUGL_KEY_RELEASE:
+ fprintf(stderr, "Key %u (char %u) release (%s)%s\n",
+ event->key.keycode, event->key.character, event->key.utf8,
+ event->key.filter ? " (filtered)" : "");
+ break;
+ case PUGL_MOTION_NOTIFY:
+ {
+ auto mouseMoveEvent = std::make_shared<MouseMoveEvent>();
+ mouseMoveEvent->x = event->motion.x;
+ mouseMoveEvent->y = event->motion.y;
+ native->event_queue.push_back(mouseMoveEvent);
+ }
+ break;
+ case PUGL_BUTTON_PRESS:
+ case PUGL_BUTTON_RELEASE:
+ {
+ auto buttonEvent = std::make_shared<ButtonEvent>();
+ buttonEvent->x = event->button.x;
+ buttonEvent->y = event->button.y;
+ switch(event->button.button) {
+ case 1:
+ buttonEvent->button = MouseButton::left;
+ break;
+ case 2:
+ buttonEvent->button = MouseButton::middle;
+ break;
+ case 3:
+ buttonEvent->button = MouseButton::right;
+ break;
+ default:
+ WARN(X11, "Unknown button %d, setting to MouseButton::left\n",
+ event->button.button);
+ buttonEvent->button = MouseButton::left;
+ break;
+ }
+
+ buttonEvent->direction =
+ (event->type == PUGL_BUTTON_PRESS) ?
+ Direction::down : Direction::up;
+
+ buttonEvent->doubleClick =
+ (event->type == PUGL_BUTTON_PRESS) &&
+ ((event->button.time - native->last_click) < 200);
+
+ if(event->type == PUGL_BUTTON_PRESS)
+ {
+ native->last_click = event->button.time;
+ }
+ native->event_queue.push_back(buttonEvent);
+ }
+ fprintf(stderr, "Mouse %d %s at %f,%f ",
+ event->button.button,
+ (event->type == PUGL_BUTTON_PRESS) ? "down" : "up",
+ event->button.x,
+ event->button.y);
+ ///printModifiers(view, event->scroll.state);
+ break;
+ case PUGL_SCROLL:
+ {
+ auto scrollEvent = std::make_shared<ScrollEvent>();
+ scrollEvent->x = event->scroll.x;
+ scrollEvent->y = event->scroll.y;
+ scrollEvent->delta = event->scroll.dy * -1;//scroll * ((xevent.xbutton.button == 4) ? -1 : 1);
+ native->event_queue.push_back(scrollEvent);
+ }
+ fprintf(stderr, "Scroll %f %f %f %f ",
+ event->scroll.x, event->scroll.y, event->scroll.dx, event->scroll.dy);
+ //printModifiers(view, event->scroll.state);
+ //dist += event->scroll.dy;
+ //if (dist < 10.0f) {
+ // dist = 10.0f;
+ //}
+ puglPostRedisplay(view);
+ break;
+ case PUGL_ENTER_NOTIFY:
+ fprintf(stderr, "Entered\n");
+ break;
+ case PUGL_LEAVE_NOTIFY:
+ fprintf(stderr, "Exited\n");
+ break;
+ case PUGL_FOCUS_IN:
+ fprintf(stderr, "Focus in\n");
+ break;
+ case PUGL_FOCUS_OUT:
+ fprintf(stderr, "Focus out\n");
+ break;
+ }
+}
+
+void NativeWindowPugl::onReshape(PuglView* view, int width, int height)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glViewport(0, 0, width, height);
+}
void NativeWindowPugl::onDisplay(PuglView* view)
{
NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view);
Window& window = native->window;
+ //window.redraw();
+
+ printf("!!! %p %d %d\n", native, (int)window.wpixbuf.width, (int)window.wpixbuf.height);
+ if((window.wpixbuf.width < 16) || (window.wpixbuf.height < 16))
+ {
+ return;
+ }
+
+ puglEnterContext(view);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0f, 0.0f, 0.0f);
+
GLuint image;
glGenTextures(1, &image);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_NEAREST = no smoothing
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window.wpixbuf.width,
- window.wpixbuf.height, 0, GL_RGB, GL_UNSIGNED_BYTE,
+ glTexImage2D(GL_TEXTURE_2D,
+ 0, GL_RGBA,
+ window.wpixbuf.width,
+ window.wpixbuf.height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE,
window.wpixbuf.buf);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
- glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0);
- glTexCoord2d(0.0, 1.0); glVertex2f(0.0, window.wpixbuf.height);
- glTexCoord2d(1.0, 1.0); glVertex2f(window.wpixbuf.width, window.wpixbuf.height);
- glTexCoord2d(1.0, 0.0); glVertex2f(window.wpixbuf.width, 0.0);
+ glTexCoord2d(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+ glTexCoord2d(0.0f, -1.0f); glVertex2f(-1.0f, 1.0f);
+ glTexCoord2d(1.0f, -1.0f); glVertex2f( 1.0f, 1.0f);
+ glTexCoord2d(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glEnd();
glDeleteTextures(1, &image);
glDisable(GL_TEXTURE_2D);
glFlush();
- puglPostRedisplay(view);
+ puglLeaveContext(view, true);
}
void NativeWindowPugl::onMouse(PuglView* view, int button, bool press, int x, int y)
@@ -145,114 +383,4 @@ void NativeWindowPugl::onKeyboard(PuglView* view, bool press, uint32_t key)
native->eventq.push_back(e);
}
-NativeWindowPugl::NativeWindowPugl(void* native_window, Window& window)
- : window(window)
- , native_window(native_window)
-{
- INFO(nativewindow, "Running with PuGL native window\n");
- init();
-}
-
-NativeWindowPugl::~NativeWindowPugl()
-{
- puglDestroy(view);
-}
-
-void NativeWindowPugl::init()
-{
- PuglView* oldView = view;
- if(view)
- {
- oldView = view;
- }
-
-// view = puglCreate(0, "DrumgGizmo", window.x(), window.y(), false, true);
- view = puglCreate((PuglNativeWindow)native_window, "DrumgGizmo", 370, 330, false, true);
- puglSetHandle(view, (PuglHandle)this);
- puglSetDisplayFunc(view, onDisplay);
- puglSetMouseFunc(view, onMouse);
- puglSetKeyboardFunc(view, onKeyboard);
-
- if(oldView)
- {
- free(oldView);
- }
-}
-
-void NativeWindowPugl::setFixedSize(int width, int height)
-{
-// redraw();
-}
-
-void NativeWindowPugl::resize(int width, int height)
-{
-// DEBUG(nativewindow_pugl, "Resizing to %dx%d\n", width, height);
-// init();
-// redraw();
-}
-
-void NativeWindowPugl::move(int x, int y)
-{
-// redraw();
-}
-
-void NativeWindowPugl::show()
-{
-// redraw();
-}
-
-void NativeWindowPugl::hide()
-{
-// redraw();
-}
-
-void NativeWindowPugl::handleBuffer()
-{
- onDisplay(view);
-}
-
-void NativeWindowPugl::redraw()
-{
-// handleBuffer();
-}
-
-void NativeWindowPugl::setCaption(const std::string &caption)
-{
-// redraw();
-}
-
-void NativeWindowPugl::grabMouse(bool grab)
-{
-// redraw();
-}
-
-bool NativeWindowPugl::hasEvent()
-{
- // dirty hack - assume that this function is called enough times to get fluent gui
- // ^^ Bad assumption
- puglProcessEvents(view);
- return !eventq.empty();
-}
-
-Event *NativeWindowPugl::getNextEvent()
-{
- Event *event = nullptr;
-
- if(!eventq.empty()) {
- event = eventq.front();
- eventq.pop_front();
- }
- return event;
-}
-
-Event *NativeWindowPugl::peekNextEvent()
-{
- Event *event = nullptr;
-
- if(!eventq.empty()) {
- event = eventq.front();
- }
- return event;
-}
-
} // GUI::
diff --git a/plugingui/nativewindow_pugl.h b/plugingui/nativewindow_pugl.h
index 000a48b..6a667f4 100644
--- a/plugingui/nativewindow_pugl.h
+++ b/plugingui/nativewindow_pugl.h
@@ -27,11 +27,15 @@
#pragma once
#include "nativewindow.h"
-#include "pugl.h"
+extern "C"
+{
+#include <pugl/pugl.h>
+}
#include <list>
-namespace GUI {
+namespace GUI
+{
class Event;
class Window;
@@ -41,32 +45,39 @@ public:
NativeWindowPugl(void* native_window, Window& window);
~NativeWindowPugl();
- void init();
- void setFixedSize(int width, int height);
- void resize(int width, int height);
- void move(int x, int y);
- void show();
- void setCaption(const std::string &caption);
- void hide();
- void handleBuffer();
- void redraw();
- void grabMouse(bool grab);
-
- bool hasEvent();
- Event *getNextEvent();
- Event *peekNextEvent();
+ void setFixedSize(std::size_t width, std::size_t height) override;
+ void resize(std::size_t width, std::size_t height) override;
+ std::pair<std::size_t, std::size_t> getSize() const override;
+
+ void move(int x, int y) override;
+ std::pair<int, int> getPosition() const override{ return {}; }
+
+ void show() override;
+ void setCaption(const std::string &caption) override;
+ void hide() override;
+ bool visible() const override;
+ void redraw(const Rect& dirty_rect) override;
+ void grabMouse(bool grab) override;
+
+ EventQueue getEvents() override;
+
+ void* getNativeWindowHandle() const override;
private:
Window& window;
- void* native_window{nullptr};
PuglView* view{nullptr};
std::list<Event*> eventq;
// Internal pugl c-callbacks
+ static void onEvent(PuglView* view, const PuglEvent* event);
+ static void onReshape(PuglView* view, int width, int height);
static void onDisplay(PuglView* view);
static void onMouse(PuglView* view, int button, bool press, int x, int y);
static void onKeyboard(PuglView* view, bool press, uint32_t key);
+
+ EventQueue event_queue;
+ std::uint32_t last_click{0};
};
} // GUI::
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index 1de78fb..5cfb179 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -432,7 +432,7 @@ void NativeWindowWin32::resize(std::size_t width, std::size_t height)
SetWindowPos(hwnd, nullptr, -1, -1, width + w, height + h, SWP_NOMOVE);
}
-std::pair<std::size_t, std::size_t> NativeWindowWin32::getSize()
+std::pair<std::size_t, std::size_t> NativeWindowWin32::getSize() const
{
RECT rect;
GetClientRect(m_hwnd, &rect);
@@ -444,7 +444,7 @@ void NativeWindowWin32::move(int x, int y)
SetWindowPos(m_hwnd, nullptr, (int)x, (int)y, -1, -1, SWP_NOSIZE);
}
-std::pair<int, int> NativeWindowWin32::getPosition()
+std::pair<int, int> NativeWindowWin32::getPosition() const
{
RECT rect;
GetClientRect(m_hwnd, &rect);
diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h
index bb407d8..2945be6 100644
--- a/plugingui/nativewindow_win32.h
+++ b/plugingui/nativewindow_win32.h
@@ -46,9 +46,9 @@ public:
void setFixedSize(std::size_t width, std::size_t height) override;
void resize(std::size_t width, std::size_t height) override;
- std::pair<std::size_t, std::size_t> getSize() override;
+ std::pair<std::size_t, std::size_t> getSize() const override;
void move(int x, int y) override;
- std::pair<int, int> getPosition() override;
+ std::pair<int, int> getPosition() const override;
void show() override;
bool visible() const override;
void hide() override;
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index 5faecc1..056c69f 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -130,25 +130,14 @@ void NativeWindowX11::setFixedSize(std::size_t width, std::size_t height)
resize(width, height);
- XSizeHints* size_hints;
- size_hints = XAllocSizeHints();
+ XSizeHints size_hints;
+ memset(&size_hints, 0, sizeof(size_hints));
- if(size_hints == nullptr)
- {
- ERR(X11,"XMallocSizeHints() failed");
- return;
- }
-
- size_hints->flags = USPosition | PMinSize | PMaxSize;
- size_hints->min_width = size_hints->max_width = width;
- size_hints->min_height = size_hints->max_height = height;
-
- //size_hints->min_aspect.x = (float)window.width()/(float)window.height();
- //size_hints->max_aspect.x = (float)window.width()/(float)window.height();
- //size_hints->min_aspect.y = (float)window.width()/(float)window.height();
- //size_hints->max_aspect.y = size_hints->min_aspect.y;
+ size_hints.flags = PMinSize|PMaxSize;
+ size_hints.min_width = size_hints.max_width = (int)width;
+ size_hints.min_height = size_hints.max_height = (int)height;
- XSetWMNormalHints(display, xwindow, size_hints);
+ XSetNormalHints(display, xwindow, &size_hints);
}
void NativeWindowX11::resize(std::size_t width, std::size_t height)
@@ -161,7 +150,7 @@ void NativeWindowX11::resize(std::size_t width, std::size_t height)
XResizeWindow(display, xwindow, width, height);
}
-std::pair<std::size_t, std::size_t> NativeWindowX11::getSize()
+std::pair<std::size_t, std::size_t> NativeWindowX11::getSize() const
{
// XWindowAttributes attributes;
// XGetWindowAttributes(display, xwindow, &attributes);
@@ -175,7 +164,7 @@ std::pair<std::size_t, std::size_t> NativeWindowX11::getSize()
&x, &y,
&width, &height, &border, &depth);
- return std::make_pair(width, height);
+ return {width, height};
}
void NativeWindowX11::move(int x, int y)
@@ -188,7 +177,7 @@ void NativeWindowX11::move(int x, int y)
XMoveWindow(display, xwindow, x, y);
}
-std::pair<int, int> NativeWindowX11::getPosition()
+std::pair<int, int> NativeWindowX11::getPosition() const
{
::Window root_window;
::Window child_window;
diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h
index c6c038e..eb88b6c 100644
--- a/plugingui/nativewindow_x11.h
+++ b/plugingui/nativewindow_x11.h
@@ -48,9 +48,9 @@ public:
// From NativeWindow:
void setFixedSize(std::size_t width, std::size_t height) override;
void resize(std::size_t width, std::size_t height) override;
- std::pair<std::size_t, std::size_t> getSize() override;
+ std::pair<std::size_t, std::size_t> getSize() const override;
void move(int x, int y) override;
- std::pair<int, int> getPosition() override;
+ std::pair<int, int> getPosition() const override;
void show() override;
void hide() override;
bool visible() const override;