Signed-off-by: falkTX <falktx@falktx.com>pull/321/head
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -159,15 +159,15 @@ enum MouseButton { | |||
This is a portable subset of mouse cursors that exist on X11, MacOS, and Windows. | |||
*/ | |||
enum MouseCursor { | |||
kMouseCursorArrow, ///< Default pointing arrow | |||
kMouseCursorCaret, ///< Caret (I-Beam) for text entry | |||
kMouseCursorCrosshair, ///< Cross-hair | |||
kMouseCursorHand, ///< Hand with a pointing finger | |||
kMouseCursorNotAllowed, ///< Operation not allowed | |||
kMouseCursorLeftRight, ///< Left/right arrow for horizontal resize | |||
kMouseCursorUpDown, ///< Up/down arrow for vertical resize | |||
kMouseCursorDiagonal, ///< Top-left to bottom-right arrow for diagonal resize | |||
kMouseCursorAntiDiagonal ///< Bottom-left to top-right arrow for diagonal resize | |||
kMouseCursorArrow, ///< Default pointing arrow | |||
kMouseCursorCaret, ///< Caret (I-Beam) for text entry | |||
kMouseCursorCrosshair, ///< Cross-hair | |||
kMouseCursorHand, ///< Hand with a pointing finger | |||
kMouseCursorNotAllowed, ///< Operation not allowed | |||
kMouseCursorLeftRight, ///< Left/right arrow for horizontal resize | |||
kMouseCursorUpDown, ///< Up/down arrow for vertical resize | |||
kMouseCursorDiagonal, ///< Top-left to bottom-right arrow for diagonal resize | |||
kMouseCursorAntiDiagonal ///< Bottom-left to top-right arrow for diagonal resize | |||
}; | |||
/** | |||
@@ -178,11 +178,29 @@ enum MouseCursor { | |||
while a smooth scroll is for those with arbitrary scroll direction freedom, like some touchpads. | |||
*/ | |||
enum ScrollDirection { | |||
kScrollUp, ///< Scroll up | |||
kScrollDown, ///< Scroll down | |||
kScrollLeft, ///< Scroll left | |||
kScrollRight, ///< Scroll right | |||
kScrollSmooth ///< Smooth scroll in any direction | |||
kScrollUp, ///< Scroll up | |||
kScrollDown, ///< Scroll down | |||
kScrollLeft, ///< Scroll left | |||
kScrollRight, ///< Scroll right | |||
kScrollSmooth ///< Smooth scroll in any direction | |||
}; | |||
/** | |||
A clipboard data offer. | |||
@see Window::onClipboardDataOffer | |||
*/ | |||
struct ClipboardDataOffer { | |||
/** | |||
The id of this data offer. | |||
@note The value 0 is reserved for null/invalid. | |||
*/ | |||
uint32_t id; | |||
/** | |||
The type of this data offer. | |||
Usually a MIME type, but may also be another platform-specific type identifier. | |||
*/ | |||
const char* type; | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -101,8 +101,8 @@ public: | |||
void repaint(const Rectangle<uint>& rect) noexcept; | |||
// TODO group stuff after here, convenience functions present in Window class | |||
const void* getClipboard(size_t& dataSize); | |||
bool setClipboard(const char* mimeType, const void* data, size_t dataSize); | |||
const void* getClipboard(const char*& mimeType, size_t& dataSize); | |||
bool setCursor(MouseCursor cursor); | |||
bool addIdleCallback(IdleCallback* callback, uint timerFrequencyInMs = 0); | |||
bool removeIdleCallback(IdleCallback* callback); | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -23,6 +23,8 @@ | |||
# include "../distrho/extra/FileBrowserDialog.hpp" | |||
#endif | |||
#include <vector> | |||
START_NAMESPACE_DGL | |||
class Application; | |||
@@ -298,6 +300,16 @@ public: | |||
*/ | |||
void setIgnoringKeyRepeat(bool ignore) noexcept; | |||
/** | |||
Get the clipboard contents. | |||
This gets the system clipboard contents, | |||
which may have been set with setClipboard() or copied from another application. | |||
returns the clipboard contents, or null. | |||
*/ | |||
const void* getClipboard(size_t& dataSize); | |||
/** | |||
Set the clipboard contents. | |||
@@ -309,16 +321,6 @@ public: | |||
*/ | |||
bool setClipboard(const char* mimeType, const void* data, size_t dataSize); | |||
/** | |||
Get the clipboard contents. | |||
This gets the system clipboard contents, | |||
which may have been set with setClipboard() or copied from another application. | |||
returns the clipboard contents, or null. | |||
*/ | |||
const void* getClipboard(const char*& mimeType, size_t& dataSize); | |||
/** | |||
Set the mouse cursor. | |||
@@ -450,6 +452,23 @@ public: | |||
inline void exec(bool blockWait = false) { runAsModal(blockWait); } | |||
protected: | |||
/** | |||
Get the types available for the data in a clipboard. | |||
Must only be called within the context of onClipboardDataOffer. | |||
*/ | |||
std::vector<ClipboardDataOffer> getClipboardDataOfferTypes(); | |||
/** | |||
A function called when clipboard has data present, possibly with several datatypes. | |||
While handling this event, the data types can be investigated with getClipboardDataOfferTypes() to decide whether to accept the offer. | |||
Reimplement and return a non-zero id to accept the clipboard data offer for a particular type. | |||
Applications must ignore any type they do not recognize. | |||
The default implementation does nothing. | |||
*/ | |||
virtual uint32_t onClipboardDataOffer(); | |||
/** | |||
A function called when the window is attempted to be closed. | |||
Returning true closes the window, which is the default behaviour. | |||
@@ -60,14 +60,14 @@ void TopLevelWidget::setSize(const Size<uint>& size) | |||
pData->window.setSize(size); | |||
} | |||
bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize) | |||
const void* TopLevelWidget::getClipboard(size_t& dataSize) | |||
{ | |||
return pData->window.setClipboard(mimeType, data, dataSize); | |||
return pData->window.getClipboard(dataSize); | |||
} | |||
const void* TopLevelWidget::getClipboard(const char*& mimeType, size_t& dataSize) | |||
bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize) | |||
{ | |||
return pData->window.getClipboard(mimeType, dataSize); | |||
return pData->window.setClipboard(mimeType, data, dataSize); | |||
} | |||
bool TopLevelWidget::setCursor(const MouseCursor cursor) | |||
@@ -319,15 +319,20 @@ void Window::setIgnoringKeyRepeat(const bool ignore) noexcept | |||
puglSetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT, ignore); | |||
} | |||
bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize) | |||
const void* Window::getClipboard(size_t& dataSize) | |||
{ | |||
return puglSetClipboard(pData->view, mimeType, data, dataSize) == PUGL_SUCCESS; | |||
if (pData->clipboardTypeIndex == 0) | |||
{ | |||
dataSize = 0; | |||
return nullptr; | |||
} | |||
return puglGetClipboard(pData->view, pData->clipboardTypeIndex, &dataSize); | |||
} | |||
const void* Window::getClipboard(const char*& mimeType, size_t& dataSize) | |||
bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize) | |||
{ | |||
const void* const clipboard = nullptr; // puglGetClipboard(pData->view, &mimeType, &dataSize); | |||
return clipboard; | |||
return puglSetClipboard(pData->view, mimeType, data, dataSize) == PUGL_SUCCESS; | |||
} | |||
bool Window::setCursor(const MouseCursor cursor) | |||
@@ -466,6 +471,29 @@ void Window::setGeometryConstraints(uint minimumWidth, | |||
} | |||
} | |||
std::vector<ClipboardDataOffer> Window::getClipboardDataOfferTypes() | |||
{ | |||
std::vector<ClipboardDataOffer> offerTypes; | |||
if (const uint32_t numTypes = puglGetNumClipboardTypes(pData->view)) | |||
{ | |||
offerTypes.reserve(numTypes); | |||
for (uint32_t i=0; i<numTypes; ++i) | |||
{ | |||
const ClipboardDataOffer offer = { i + 1, puglGetClipboardType(pData->view, i) }; | |||
offerTypes.push_back(offer); | |||
} | |||
} | |||
return offerTypes; | |||
} | |||
uint32_t Window::onClipboardDataOffer() | |||
{ | |||
return 0; | |||
} | |||
bool Window::onClose() | |||
{ | |||
return true; | |||
@@ -109,6 +109,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||
minHeight(0), | |||
keepAspectRatio(false), | |||
ignoreIdleCallbacks(false), | |||
clipboardTypeIndex(0), | |||
filenameToRenderInto(nullptr), | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
fileBrowserHandle(nullptr), | |||
@@ -135,6 +136,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c | |||
minHeight(0), | |||
keepAspectRatio(false), | |||
ignoreIdleCallbacks(false), | |||
clipboardTypeIndex(0), | |||
filenameToRenderInto(nullptr), | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
fileBrowserHandle(nullptr), | |||
@@ -163,6 +165,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
minHeight(0), | |||
keepAspectRatio(false), | |||
ignoreIdleCallbacks(false), | |||
clipboardTypeIndex(0), | |||
filenameToRenderInto(nullptr), | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
fileBrowserHandle(nullptr), | |||
@@ -192,6 +195,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
minHeight(0), | |||
keepAspectRatio(false), | |||
ignoreIdleCallbacks(false), | |||
clipboardTypeIndex(0), | |||
filenameToRenderInto(nullptr), | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
fileBrowserHandle(nullptr), | |||
@@ -753,6 +757,13 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev) | |||
#endif | |||
} | |||
uint32_t Window::PrivateData::onClipboardDataOffer() | |||
{ | |||
DGL_DBG("onClipboardDataOffer\n"); | |||
return clipboardTypeIndex = self->onClipboardDataOffer(); | |||
} | |||
#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS) | |||
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | |||
#endif | |||
@@ -933,6 +944,8 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
///< Data offered from clipboard, a #PuglDataOfferEvent | |||
case PUGL_DATA_OFFER: | |||
if (const uint32_t offerId = pData->onClipboardDataOffer()) | |||
puglAcceptOffer(view, &event->offer, offerId - 1); | |||
break; | |||
///< Data available from clipboard, a #PuglDataEvent | |||
@@ -80,6 +80,9 @@ struct Window::PrivateData : IdleCallback { | |||
/** Whether to ignore idle callback requests, useful for temporary windows. */ | |||
bool ignoreIdleCallbacks; | |||
/** The type index returned by the last onClipboardDataOffer call. */ | |||
uint32_t clipboardTypeIndex; | |||
/** Render to a picture file when non-null, automatically free+unset after saving. */ | |||
char* filenameToRenderInto; | |||
@@ -182,6 +185,7 @@ struct Window::PrivateData : IdleCallback { | |||
void onPuglMouse(const Widget::MouseEvent& ev); | |||
void onPuglMotion(const Widget::MotionEvent& ev); | |||
void onPuglScroll(const Widget::ScrollEvent& ev); | |||
uint32_t onClipboardDataOffer(); | |||
// Pugl event handling entry point | |||
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | |||
@@ -476,8 +476,8 @@ void puglMacOSShowCentered(PuglView* const view) | |||
const NSRect ourFrame = [view->impl->window frame]; | |||
const NSRect transientFrame = [transientWindow frame]; | |||
const int x = transientFrame.origin.x + transientFrame.size.width / 2 - ourFrame.size.width / 2; | |||
const int y = transientFrame.origin.y + transientFrame.size.height / 2 + ourFrame.size.height / 2; | |||
const int x = transientFrame.origin.x + (transientFrame.size.width - ourFrame.size.width) / 2; | |||
const int y = transientFrame.origin.y + (transientFrame.size.height - ourFrame.size.height) / 2; | |||
[view->impl->window setFrameTopLeftPoint:NSMakePoint(x, y)]; | |||
} | |||
@@ -543,8 +543,8 @@ void puglWin32ShowCentered(PuglView* const view) | |||
if (GetMonitorInfo(MonitorFromWindow(impl->hwnd, MONITOR_DEFAULTTOPRIMARY), &mInfo)) | |||
SetWindowPos(impl->hwnd, | |||
HWND_TOP, | |||
mInfo.rcWork.left + (mInfo.rcWork.right - view->frame.width) / 2, | |||
mInfo.rcWork.top + (mInfo.rcWork.bottom - view->frame.height) / 2, | |||
mInfo.rcWork.left + (mInfo.rcWork.right - mInfo.rcWork.left - view->frame.width) / 2, | |||
mInfo.rcWork.top + (mInfo.rcWork.bottom - mInfo.rcWork.top - view->frame.height) / 2, | |||
0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); | |||
else | |||
ShowWindow(impl->hwnd, SW_NORMAL); | |||
@@ -35,20 +35,12 @@ | |||
#define PUGL_NO_INCLUDE_GL_H | |||
#define PUGL_NO_INCLUDE_GLU_H | |||
// do not set extern "C" | |||
// #define __cplusplus_backup __cplusplus | |||
// #undef __cplusplus | |||
// give warning if defined as something else | |||
// #define PUGL_BEGIN_DECLS | |||
// #define PUGL_END_DECLS | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
START_NAMESPACE_DGL | |||
#include "pugl-upstream/include/pugl/pugl.h" | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// DGL specific, expose backend enter | |||
bool puglBackendEnter(PuglView* view); | |||
@@ -85,30 +77,24 @@ void puglFallbackOnResize(PuglView* view); | |||
#if defined(DISTRHO_OS_MAC) | |||
// macOS specific, allow standalone window to gain focus | |||
PUGL_API void | |||
puglMacOSActivateApp(); | |||
void puglMacOSActivateApp(); | |||
// macOS specific, add another view's window as child | |||
PUGL_API PuglStatus | |||
puglMacOSAddChildWindow(PuglView* view, PuglView* child); | |||
PuglStatus puglMacOSAddChildWindow(PuglView* view, PuglView* child); | |||
// macOS specific, remove another view's window as child | |||
PUGL_API PuglStatus | |||
puglMacOSRemoveChildWindow(PuglView* view, PuglView* child); | |||
PuglStatus puglMacOSRemoveChildWindow(PuglView* view, PuglView* child); | |||
// macOS specific, center view based on parent coordinates (if there is one) | |||
PUGL_API void | |||
puglMacOSShowCentered(PuglView* view); | |||
void puglMacOSShowCentered(PuglView* view); | |||
#elif defined(DISTRHO_OS_WINDOWS) | |||
// win32 specific, call ShowWindow with SW_RESTORE | |||
PUGL_API void | |||
puglWin32RestoreWindow(PuglView* view); | |||
void puglWin32RestoreWindow(PuglView* view); | |||
// win32 specific, center view based on parent coordinates (if there is one) | |||
PUGL_API void | |||
puglWin32ShowCentered(PuglView* view); | |||
void puglWin32ShowCentered(PuglView* view); | |||
#elif defined(HAVE_X11) | |||
@@ -121,7 +107,4 @@ void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone); | |||
END_NAMESPACE_DGL | |||
// #define __cplusplus __cplusplus_backup | |||
// #undef __cplusplus_backup | |||
#endif // DGL_PUGL_HPP_INCLUDED |
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -296,6 +296,23 @@ protected: | |||
virtual void uiScaleFactorChanged(double scaleFactor); | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
/** | |||
Get the types available for the data in a clipboard. | |||
Must only be called within the context of uiClipboardDataOffer. | |||
*/ | |||
std::vector<DGL_NAMESPACE::ClipboardDataOffer> getClipboardDataOfferTypes(); | |||
/** | |||
Window clipboard data offer function, called when clipboard has data present, possibly with several datatypes. | |||
While handling this event, the data types can be investigated with getClipboardDataOfferTypes() to decide whether to accept the offer. | |||
Reimplement and return a non-zero id to accept the clipboard data offer for a particular type. | |||
UIs must ignore any type they do not recognize. | |||
The default implementation does nothing. | |||
*/ | |||
virtual uint32_t uiClipboardDataOffer(); | |||
/** | |||
Windows focus function, called when the window gains or loses the keyboard focus. | |||
This function is for plugin UIs to be able to override Window::onFocus(bool, CrossingMode). | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -338,6 +338,16 @@ void UI::uiScaleFactorChanged(double) | |||
} | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
std::vector<DGL_NAMESPACE::ClipboardDataOffer> UI::getClipboardDataOfferTypes() | |||
{ | |||
return uiData->window->getClipboardDataOfferTypes(); | |||
} | |||
uint32_t UI::uiClipboardDataOffer() | |||
{ | |||
return 0; | |||
} | |||
void UI::uiFocus(bool, DGL_NAMESPACE::CrossingMode) | |||
{ | |||
} | |||
@@ -238,7 +238,22 @@ public: | |||
} | |||
#endif | |||
std::vector<ClipboardDataOffer> getClipboardDataOfferTypes() | |||
{ | |||
return Window::getClipboardDataOfferTypes(); | |||
} | |||
protected: | |||
uint32_t onClipboardDataOffer() override | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, 0); | |||
if (initializing) | |||
return 0; | |||
return ui->uiClipboardDataOffer(); | |||
} | |||
void onFocus(const bool focus, const DGL_NAMESPACE::CrossingMode mode) override | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
@@ -1,9 +1,10 @@ | |||
puglClearMinSize needed? | |||
clipboard todo | |||
puglSetWindowSize was used on first show, still needed? | |||
transientParentView needed? remove from WindowPrivateData | |||
pugl namespace details finalized | |||
update distrhoui.cpp get scale factor to match new parent request setup and pugl | |||
window starts centered for screen or parent finalized | |||
clipboard todo | |||
pugl namespace details finalized |