Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -265,7 +265,7 @@ endif | |||
ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) | |||
ifeq ($(HAVE_X11),true) | |||
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags x11) | |||
DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags x11) -DHAVE_X11 | |||
DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs x11) | |||
ifeq ($(HAVE_XCURSOR),true) | |||
# TODO -DHAVE_XCURSOR | |||
@@ -50,6 +50,60 @@ class TopLevelWidget; | |||
class Window | |||
{ | |||
public: | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
File browser options. | |||
@see Window::openFileBrowser | |||
*/ | |||
struct FileBrowserOptions { | |||
/** | |||
File browser button state. | |||
This allows to customize the behaviour of the file browse dialog buttons. | |||
*/ | |||
enum ButtonState { | |||
kButtonInvisible, | |||
kButtonVisibleUnchecked, | |||
kButtonVisibleChecked, | |||
}; | |||
/** Start directory, uses current working directory if null */ | |||
const char* startDir; | |||
/** File browser dialog window title, uses "FileBrowser" if null */ | |||
const char* title; | |||
/** File browser dialog window width */ | |||
uint width; | |||
/** File browser dialog window height */ | |||
uint height; | |||
// TODO file filter | |||
/** | |||
File browser buttons. | |||
*/ | |||
struct Buttons { | |||
/** Whether to list all files vs only those with matching file extension */ | |||
ButtonState listAllFiles; | |||
/** Whether to show hidden files */ | |||
ButtonState showHidden; | |||
/** Whether to show list of places (bookmarks) */ | |||
ButtonState showPlaces; | |||
/** Constuctor for default values */ | |||
Buttons() | |||
: listAllFiles(kButtonVisibleChecked), | |||
showHidden(kButtonVisibleUnchecked), | |||
showPlaces(kButtonVisibleUnchecked) {} | |||
} buttons; | |||
/** Constuctor for default values */ | |||
FileBrowserOptions() | |||
: startDir(nullptr), | |||
title(nullptr), | |||
width(0), | |||
height(0), | |||
buttons() {} | |||
}; | |||
#endif // DGL_FILE_BROWSER_DISABLED | |||
/** | |||
Constructor for a regular, standalone window. | |||
*/ | |||
@@ -130,7 +184,18 @@ public: | |||
*/ | |||
void close(); | |||
/** | |||
Check if this window is resizable. | |||
@see setResizable | |||
*/ | |||
bool isResizable() const noexcept; | |||
/** | |||
Set window as resizable (by the user or window manager). | |||
It is always possible to resize a window programmatically, which is not the same as the user being allowed to it. | |||
@note This function does nothing for plugins, where the resizable state is set via macro. | |||
@see DISTRHO_UI_USER_RESIZABLE | |||
*/ | |||
void setResizable(bool resizable); | |||
/** | |||
@@ -247,6 +312,17 @@ public: | |||
*/ | |||
void focus(); | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
Open a file browser dialog with this window as parent. | |||
A few options can be specified to setup the dialog. | |||
This function does not block. | |||
If a path is selected, onFileSelected() will be called with the user chosen path. | |||
*/ | |||
bool openFileBrowser(const FileBrowserOptions& options); | |||
#endif | |||
/** | |||
Request repaint of this window, for the entire area. | |||
*/ | |||
@@ -272,16 +348,15 @@ public: | |||
bool keepAspectRatio = false, | |||
bool automaticallyScale = false); | |||
/* | |||
void setTransientWinId(uintptr_t winId); | |||
*/ | |||
/** DEPRECATED Use isIgnoringKeyRepeat(). */ | |||
DISTRHO_DEPRECATED_BY("isIgnoringKeyRepeat()") | |||
inline bool getIgnoringKeyRepeat() const noexcept { return isIgnoringKeyRepeat(); } | |||
/** DEPRECATED Use getScaleFactor(). */ | |||
DISTRHO_DEPRECATED_BY("getScaleFactor()") | |||
inline double getScaling() const noexcept { return getScaleFactor(); } | |||
/** DEPRECATED Use runAsModal(bool). */ | |||
DISTRHO_DEPRECATED_BY("runAsModal(bool)") | |||
inline void exec(bool blockWait = false) { runAsModal(blockWait); } | |||
@@ -302,9 +377,23 @@ protected: | |||
/** | |||
A function called when the window is resized. | |||
If there is a top-level widget associated with this window, its size will be set right after this function. | |||
The default implementation sets up drawing context where necessary. | |||
*/ | |||
virtual void onReshape(uint width, uint height); | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
A function called when a path is selected by the user, as triggered by openFileBrowser(). | |||
This action happens after the user confirms the action, so the file browser dialog will be closed at this point. | |||
The default implementation does nothing. | |||
*/ | |||
virtual void onFileSelected(const char* filename); | |||
/** DEPRECATED Use onFileSelected(). */ | |||
DISTRHO_DEPRECATED_BY("onFileSelected(const char*)") | |||
inline virtual void fileBrowserSelected(const char* filename) { return onFileSelected(filename); } | |||
#endif | |||
private: | |||
struct PrivateData; | |||
PrivateData* const pData; | |||
@@ -319,62 +408,10 @@ private: | |||
END_NAMESPACE_DGL | |||
/* TODO | |||
* add focusEvent with CrossingMode arg | |||
* add eventcrossing/enter-leave event | |||
*/ | |||
#if 0 | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
File browser options. | |||
*/ | |||
struct FileBrowserOptions { | |||
const char* startDir; | |||
const char* title; | |||
uint width; | |||
uint height; | |||
/** | |||
File browser buttons. | |||
0 means hidden. | |||
1 means visible and unchecked. | |||
2 means visible and checked. | |||
*/ | |||
struct Buttons { | |||
uint listAllFiles; | |||
uint showHidden; | |||
uint showPlaces; | |||
/** Constuctor for default values */ | |||
Buttons() | |||
: listAllFiles(2), | |||
showHidden(1), | |||
showPlaces(1) {} | |||
} buttons; | |||
/** Constuctor for default values */ | |||
FileBrowserOptions() | |||
: startDir(nullptr), | |||
title(nullptr), | |||
width(0), | |||
height(0), | |||
buttons() {} | |||
}; | |||
#endif // DGL_FILE_BROWSER_DISABLED | |||
void addIdleCallback(IdleCallback* const callback); | |||
void removeIdleCallback(IdleCallback* const callback); | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
bool openFileBrowser(const FileBrowserOptions& options); | |||
#endif | |||
protected: | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
virtual void fileBrowserSelected(const char* filename); | |||
#endif | |||
bool handlePluginKeyboard(const bool press, const uint key); | |||
bool handlePluginSpecial(const bool press, const Key key); | |||
#endif | |||
@@ -201,6 +201,13 @@ void Window::focus() | |||
pData->focus(); | |||
} | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
bool Window::openFileBrowser(const FileBrowserOptions& options) | |||
{ | |||
return pData->openFileBrowser(options); | |||
} | |||
#endif | |||
void Window::repaint() noexcept | |||
{ | |||
puglPostRedisplay(pData->view); | |||
@@ -271,51 +278,20 @@ void Window::onReshape(uint, uint) | |||
puglFallbackOnResize(pData->view); | |||
} | |||
#if 0 | |||
void Window::setTransientWinId(const uintptr_t winId) | |||
{ | |||
puglSetTransientFor(pData->fView, winId); | |||
} | |||
void Window::_addWidget(Widget* const widget) | |||
{ | |||
pData->addWidget(widget); | |||
} | |||
void Window::_removeWidget(Widget* const widget) | |||
{ | |||
pData->removeWidget(widget); | |||
} | |||
void Window::_idle() | |||
{ | |||
pData->windowSpecificIdle(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
void Window::addIdleCallback(IdleCallback* const callback) | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
void Window::onFileSelected(const char*) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | |||
pData->fAppData->idleCallbacks.push_back(callback); | |||
} | |||
#endif | |||
void Window::removeIdleCallback(IdleCallback* const callback) | |||
#if 0 | |||
void Window::setTransientWinId(const uintptr_t winId) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | |||
pData->fAppData->idleCallbacks.remove(callback); | |||
puglSetTransientFor(pData->view, winId); | |||
} | |||
// ----------------------------------------------------------------------- | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
void Window::fileBrowserSelected(const char*) | |||
{ | |||
} | |||
#endif | |||
bool Window::handlePluginKeyboard(const bool press, const uint key) | |||
{ | |||
// TODO | |||
@@ -19,6 +19,14 @@ | |||
#include "pugl.hpp" | |||
#include "../../distrho/extra/String.hpp" | |||
#ifdef DISTRHO_OS_WINDOWS | |||
# include <direct.h> | |||
#else | |||
# include <unistd.h> | |||
#endif | |||
#define DGL_DEBUG_EVENTS | |||
#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS) | |||
@@ -66,6 +74,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
minHeight(0), | |||
#ifdef DISTRHO_OS_WINDOWS | |||
win32SelectedFile(nullptr), | |||
#endif | |||
modal() | |||
{ | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
@@ -85,6 +96,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
minHeight(0), | |||
#ifdef DISTRHO_OS_WINDOWS | |||
win32SelectedFile(nullptr), | |||
#endif | |||
modal(ppData) | |||
{ | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
@@ -108,6 +122,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
minHeight(0), | |||
#ifdef DISTRHO_OS_WINDOWS | |||
win32SelectedFile(nullptr), | |||
#endif | |||
modal() | |||
{ | |||
if (isEmbed) | |||
@@ -142,6 +159,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
autoScaleFactor(1.0), | |||
minWidth(0), | |||
minHeight(0), | |||
#ifdef DISTRHO_OS_WINDOWS | |||
win32SelectedFile(nullptr), | |||
#endif | |||
modal() | |||
{ | |||
if (isEmbed) | |||
@@ -163,6 +183,9 @@ Window::PrivateData::~PrivateData() | |||
{ | |||
if (isEmbed) | |||
{ | |||
#ifdef HAVE_X11 | |||
sofdFileDialogClose(view); | |||
#endif | |||
puglHide(view); | |||
appData->oneWindowClosed(); | |||
isClosed = true; | |||
@@ -199,9 +222,6 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r | |||
puglSetViewHint(view, PUGL_STENCIL_BITS, 8); | |||
// PUGL_SAMPLES ?? | |||
puglSetEventFunc(view, puglEventCallback); | |||
// #ifndef DGL_FILE_BROWSER_DISABLED | |||
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | |||
// #endif | |||
PuglRect rect = puglGetFrame(view); | |||
rect.width = width; | |||
@@ -215,6 +235,21 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r | |||
// ----------------------------------------------------------------------- | |||
void Window::PrivateData::close() | |||
{ | |||
DGL_DBG("Window close\n"); | |||
// DGL_DBGp("Window close DBG %i %i %p\n", isEmbed, isClosed, appData); | |||
if (isEmbed || isClosed) | |||
return; | |||
isClosed = true; | |||
hide(); | |||
appData->oneWindowClosed(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
void Window::PrivateData::show() | |||
{ | |||
if (isVisible) | |||
@@ -293,6 +328,9 @@ void Window::PrivateData::hide() | |||
if (modal.enabled) | |||
stopModal(); | |||
#ifdef HAVE_X11 | |||
sofdFileDialogClose(view); | |||
#endif | |||
puglHide(view); | |||
isVisible = false; | |||
@@ -300,21 +338,6 @@ void Window::PrivateData::hide() | |||
// ----------------------------------------------------------------------- | |||
void Window::PrivateData::close() | |||
{ | |||
DGL_DBG("Window close\n"); | |||
// DGL_DBGp("Window close DBG %i %i %p\n", isEmbed, isClosed, appData); | |||
if (isEmbed || isClosed) | |||
return; | |||
isClosed = true; | |||
hide(); | |||
appData->oneWindowClosed(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
void Window::PrivateData::focus() | |||
{ | |||
if (! isEmbed) | |||
@@ -341,20 +364,29 @@ void Window::PrivateData::setResizable(const bool resizable) | |||
void Window::PrivateData::idleCallback() | |||
{ | |||
// #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) | |||
// if (fSelectedFile.isNotEmpty()) | |||
// { | |||
// char* const buffer = fSelectedFile.getAndReleaseBuffer(); | |||
// fView->fileSelectedFunc(fView, buffer); | |||
// std::free(buffer); | |||
// } | |||
// #endif | |||
// if (modal.enabled && modal.parent != nullptr) | |||
// modal.parent->idleCallback(); | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
# ifdef DISTRHO_OS_WINDOWS | |||
if (char* const path = win32SelectedFile) | |||
{ | |||
win32SelectedFile = nullptr; | |||
self->onFileSelected(path); | |||
std::free(path); | |||
} | |||
# endif | |||
# ifdef HAVE_X11 | |||
char* path; | |||
if (sofdFileDialogGetPath(&path)) | |||
{ | |||
// TODO ignore null path?? | |||
self->onFileSelected(path); | |||
sofdFileDialogFree(path); | |||
} | |||
# endif | |||
#endif | |||
} | |||
// ----------------------------------------------------------------------- | |||
// idle callback stuff | |||
bool Window::PrivateData::addIdleCallback(IdleCallback* const callback, const uint timerFrequencyInMs) | |||
{ | |||
@@ -379,6 +411,69 @@ bool Window::PrivateData::removeIdleCallback(IdleCallback* const callback) | |||
return puglStopTimer(view, (uintptr_t)callback) == PUGL_SUCCESS; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// file handling | |||
bool Window::PrivateData::openFileBrowser(const Window::FileBrowserOptions& options) | |||
{ | |||
using DISTRHO_NAMESPACE::String; | |||
// -------------------------------------------------------------------------- | |||
// configure start dir | |||
// TODO: get abspath if needed | |||
// TODO: cross-platform | |||
String startDir(options.startDir); | |||
if (startDir.isEmpty()) | |||
{ | |||
// TESTING verify this whole thing... | |||
#ifdef DISTRHO_OS_WINDOWS | |||
if (char* const cwd = _getcwd(nullptr, 0)) | |||
{ | |||
startDir = cwd; | |||
std::free(cwd); | |||
} | |||
#else | |||
if (char* const cwd = getcwd(nullptr, 0)) | |||
{ | |||
startDir = cwd; | |||
std::free(cwd); | |||
} | |||
#endif | |||
} | |||
DISTRHO_SAFE_ASSERT_RETURN(startDir.isNotEmpty(), false); | |||
if (! startDir.endsWith(DISTRHO_OS_SEP)) | |||
startDir += DISTRHO_OS_SEP_STR; | |||
// -------------------------------------------------------------------------- | |||
// configure title | |||
String title(options.title); | |||
if (title.isEmpty()) | |||
{ | |||
title = puglGetWindowTitle(view); | |||
if (title.isEmpty()) | |||
title = "FileBrowser"; | |||
} | |||
// -------------------------------------------------------------------------- | |||
// show | |||
#ifdef HAVE_X11 | |||
uint flags = 0x0; | |||
// TODO flags | |||
return sofdFileDialogShow(view, startDir, title, flags, options.width, options.height); | |||
#endif | |||
return false; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// modal handling | |||
@@ -30,7 +30,7 @@ class TopLevelWidget; | |||
// ----------------------------------------------------------------------- | |||
struct Window::PrivateData : IdleCallback { | |||
/* Reference to the DGL Application class this (private data) window associates with. */ | |||
/** Reference to the DGL Application class this (private data) window associates with. */ | |||
Application& app; | |||
/** Direct access to the DGL Application private data where we registers ourselves in. */ | |||
@@ -68,6 +68,11 @@ struct Window::PrivateData : IdleCallback { | |||
/** Pugl minWidth, minHeight access. */ | |||
uint minWidth, minHeight; | |||
#ifdef DISTRHO_OS_WINDOWS | |||
/** Selected file for openFileBrowser on windows, stored for fake async operation. */ | |||
const char* win32SelectedFile; | |||
#endif | |||
/** Modal window setup. */ | |||
struct Modal { | |||
PrivateData* parent; // parent of this window (so we can become modal) | |||
@@ -102,9 +107,6 @@ struct Window::PrivateData : IdleCallback { | |||
/** Constructor for a modal window. */ | |||
explicit PrivateData(Application& app, Window* self, PrivateData* ppData); | |||
/** Constructor for a regular, standalone window with a transient parent. */ | |||
// explicit PrivateData(Application& app, Window* self, Window& transientWindow); | |||
/** Constructor for an embed Window, with a few extra hints from the host side. */ | |||
explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable); | |||
@@ -118,9 +120,6 @@ struct Window::PrivateData : IdleCallback { | |||
/** Helper initialization function called at the end of all this class constructors. */ | |||
void init(uint width, uint height, bool resizable); | |||
void show(); | |||
void hide(); | |||
/** Hide window and notify application of a window close event. | |||
* Does nothing if window is embed (that is, not standalone). | |||
* The application event-loop will stop when all windows have been closed. | |||
@@ -130,17 +129,23 @@ struct Window::PrivateData : IdleCallback { | |||
*/ | |||
void close(); | |||
void show(); | |||
void hide(); | |||
void focus(); | |||
void setResizable(bool resizable); | |||
const GraphicsContext& getGraphicsContext() const noexcept; | |||
// idle callback stuff | |||
void idleCallback() override; | |||
bool addIdleCallback(IdleCallback* callback, uint timerFrequencyInMs); | |||
bool removeIdleCallback(IdleCallback* callback); | |||
// file handling | |||
bool openFileBrowser(const Window::FileBrowserOptions& options); | |||
// modal handling | |||
void startModal(); | |||
void stopModal(); | |||
@@ -1 +1 @@ | |||
Subproject commit ecfa817136831ca2fe38561a68344f9e9076d3e7 | |||
Subproject commit 83ccad73546576a5b439c0fe2415e16509f8f28a |
@@ -89,6 +89,12 @@ | |||
# endif | |||
#endif | |||
#ifdef HAVE_X11 | |||
# define 400 | |||
# include "sofd/libsofd.h" | |||
# include "sofd/libsofd.c" | |||
#endif | |||
#ifndef DISTRHO_OS_MAC | |||
START_NAMESPACE_DGL | |||
#endif | |||
@@ -355,6 +361,94 @@ void puglWin32SetWindowResizable(PuglView* const view, const bool resizable) | |||
: GetWindowLong(impl->hwnd, GWL_STYLE) & ~WS_SIZEBOX; | |||
SetWindowLong(impl->hwnd, GWL_STYLE, winFlags); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
#endif | |||
#ifdef HAVE_X11 | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// X11 specific, setup event loop filter for sofd file dialog | |||
static bool sofd_has_action; | |||
static char* sofd_filename; | |||
static bool sofd_event_filter(Display* const display, XEvent* const xevent) | |||
{ | |||
if (x_fib_handle_events(display, xevent) == 0) | |||
return false; | |||
if (sofd_filename != nullptr) | |||
std::free(sofd_filename); | |||
if (x_fib_status() > 0) | |||
sofd_filename = x_fib_filename(); | |||
else | |||
sofd_filename = nullptr; | |||
x_fib_close(display); | |||
sofd_has_action = true; | |||
return true; | |||
} | |||
void sofdFileDialogSetup(PuglWorld* const world) | |||
{ | |||
puglX11SetEventFilter(world, sofd_event_filter); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// X11 specific, show file dialog via sofd | |||
bool sofdFileDialogShow(PuglView* const view, | |||
const char* const startDir, const char* const title, | |||
const uint flags, const uint width, const uint height) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(0, startDir) == 0, false); | |||
DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(1, title) == 0, false); | |||
/* | |||
x_fib_cfg_buttons(3, options.buttons.listAllFiles-1); | |||
x_fib_cfg_buttons(1, options.buttons.showHidden-1); | |||
x_fib_cfg_buttons(2, options.buttons.showPlaces-1); | |||
*/ | |||
PuglInternals* const impl = view->impl; | |||
return (x_fib_show(impl->display, impl->win, width, height) == 0); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// X11 specific, close sofd file dialog | |||
void sofdFileDialogClose(PuglView* const view) | |||
{ | |||
PuglInternals* const impl = view->impl; | |||
x_fib_close(impl->display); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// X11 specific, get path chosen via sofd file dialog | |||
bool sofdFileDialogGetPath(char** path) | |||
{ | |||
if (! sofd_has_action) | |||
return false; | |||
sofd_has_action = false; | |||
*path = sofd_filename; | |||
return true; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// X11 specific, free path of sofd file dialog, no longer needed | |||
void sofdFileDialogFree(char* const path) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(path == nullptr || path == sofd_filename,); | |||
std::free(sofd_filename); | |||
sofd_filename = nullptr; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
#endif | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -88,6 +88,28 @@ PUGL_API void | |||
puglWin32SetWindowResizable(PuglView* view, bool resizable); | |||
#endif | |||
#ifdef HAVE_X11 | |||
// X11 specific, setup event loop filter for sofd file dialog | |||
PUGL_API void | |||
sofdFileDialogSetup(PuglWorld* world); | |||
// X11 specific, show file dialog via sofd | |||
PUGL_API bool | |||
sofdFileDialogShow(PuglView* view, const char* startDir, const char* title, uint flags, uint width, uint height); | |||
// X11 specific, close sofd file dialog | |||
PUGL_API void | |||
sofdFileDialogClose(PuglView* view); | |||
// X11 specific, get path chosen via sofd file dialog | |||
PUGL_API bool | |||
sofdFileDialogGetPath(char** path); | |||
// X11 specific, free path of sofd file dialog, no longer needed | |||
PUGL_API void | |||
sofdFileDialogFree(char* path); | |||
#endif | |||
PUGL_END_DECLS | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -32,7 +32,7 @@ | |||
*/ | |||
#ifdef SOFD_TEST | |||
#define SOFD_HAVE_X11 | |||
#define HAVE_X11 | |||
#include "libsofd.h" | |||
#endif | |||
@@ -337,7 +337,7 @@ const char *x_fib_recent_file(const char *appname) { | |||
return NULL; | |||
} | |||
#ifdef SOFD_HAVE_X11 | |||
#ifdef HAVE_X11 | |||
#include <mntent.h> | |||
#include <dirent.h> | |||
@@ -475,7 +475,10 @@ static int (*_fib_filter_function)(const char *filename); | |||
#define FAREATEXTL (FAREAMRGL + TEXTSEP) //px; filename text-left FAREAMRGL + TEXTSEP | |||
#define SORTBTNOFF -10 //px; | |||
#define DBLCLKTME 400 //msec; double click time | |||
#ifndef DBLCLKTME | |||
#define DBLCLKTME 200 //msec; double click time | |||
#endif | |||
#define DRAW_OUTLINE | |||
#define DOUBLE_BUFFER | |||
@@ -1208,7 +1211,7 @@ static int fib_dirlistadd (Display *dpy, const int i, const char* path, const ch | |||
static int fib_openrecent (Display *dpy, const char *sel) { | |||
int i; | |||
unsigned int j; | |||
unsigned int j; | |||
assert (_recentcnt > 0); | |||
fib_pre_opendir (dpy); | |||
query_font_geometry (dpy, _fib_gc, "Last Used", &_fib_font_time_width, NULL, NULL, NULL); | |||
@@ -1332,8 +1335,8 @@ static int fib_open (Display *dpy, int item) { | |||
static void cb_cancel (Display *dpy) { | |||
_status = -1; | |||
// unused | |||
return; (void)dpy; | |||
// unused | |||
return; (void)dpy; | |||
} | |||
static void cb_open (Display *dpy) { | |||
@@ -1478,8 +1481,8 @@ static int fib_widget_at_pos (Display *dpy, int x, int y, int *it) { | |||
return 0; | |||
// unused | |||
(void)dpy; | |||
// unused | |||
(void)dpy; | |||
} | |||
static void fib_update_hover (Display *dpy, int need_expose, const int type, const int item) { | |||
@@ -1592,9 +1595,11 @@ static void fib_mousedown (Display *dpy, int x, int y, int btn, unsigned long ti | |||
fib_select (dpy, it); | |||
_dblclk = time; | |||
} | |||
/*if (_fsel >= 0) { | |||
/* | |||
if (_fsel >= 0) { | |||
if (!(_dirlist[_fsel].flags & 4)); | |||
}*/ | |||
} | |||
*/ | |||
} | |||
break; | |||
case 1: // paths | |||
@@ -1656,8 +1661,8 @@ static void fib_mousedown (Display *dpy, int x, int y, int btn, unsigned long ti | |||
static void fib_mouseup (Display *dpy, int x, int y, int btn, unsigned long time) { | |||
_scrl_my = -1; | |||
// unused | |||
return; (void)dpy; (void)x; (void)y; (void)btn; (void)time; | |||
// unused | |||
return; (void)dpy; (void)x; (void)y; (void)btn; (void)time; | |||
} | |||
static void add_place_raw (Display *dpy, const char *name, const char *path) { | |||
@@ -1885,8 +1890,8 @@ static int x_error_handler (Display *d, XErrorEvent *e) { | |||
font_err = 1; | |||
return 0; | |||
// unused | |||
(void)d; (void)e; | |||
// unused | |||
(void)d; (void)e; | |||
} | |||
int x_fib_show (Display *dpy, Window parent, int x, int y) { | |||
@@ -2340,7 +2345,7 @@ char *x_fib_filename () { | |||
else | |||
return NULL; | |||
} | |||
#endif // SOFD_HAVE_X11 | |||
#endif // HAVE_X11 | |||
#if defined(__clang__) | |||
# pragma clang diagnostic pop | |||
@@ -22,10 +22,15 @@ | |||
*/ | |||
#ifndef LIBSOFD_H | |||
#define LIBSOFD_H | |||
#define LIBSOFD_H 1 | |||
#ifdef HAVE_X11 | |||
#include <X11/Xlib.h> | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/////////////////////////////////////////////////////////////////////////////// | |||
/* public API */ | |||
@@ -110,6 +115,16 @@ int x_fib_cfg_buttons (int k, int v); | |||
*/ | |||
int x_fib_cfg_filter_callback (int (*cb)(const char*)); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* END X11 specific functions */ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* 'recently used' API. x-platform | |||
* NOTE: all functions use a static cache and are not reentrant. | |||
* It is expected that none of these functions are called in | |||
@@ -172,4 +187,8 @@ unsigned int x_fib_recent_count (); | |||
*/ | |||
const char *x_fib_recent_at (unsigned int i); | |||
#endif // LIBSOFD_H | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif // header guard |
@@ -246,7 +246,7 @@ protected: | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
File browser selected function. | |||
@see Window::fileBrowserSelected(const char*) | |||
@see Window::onFileSelected(const char*) | |||
*/ | |||
virtual void uiFileBrowserSelected(const char* filename); | |||
# endif | |||
@@ -185,6 +185,7 @@ void UI::uiFileBrowserSelected(const char*) | |||
void UI::uiReshape(uint, uint) | |||
{ | |||
// NOTE this must be the same as Window::onReshape | |||
pData->fallbackOnResize(); | |||
} | |||
@@ -201,7 +202,9 @@ void UI::onResize(const ResizeEvent& ev) | |||
const uint width = ev.size.getWidth(); | |||
const uint height = ev.size.getHeight(); | |||
/* | |||
pData->window.setSize(width, height); | |||
*/ | |||
uiData->setSizeCallback(width, height); | |||
} | |||
#endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
@@ -95,25 +95,25 @@ protected: | |||
UI::PrivateData* const uiData = fUI->uiData; | |||
DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,); | |||
/* | |||
uiData->resizeInProgress = true; | |||
fUI->setSize(width, height); | |||
uiData->resizeInProgress = false; | |||
*/ | |||
fUI->uiReshape(width, height); | |||
fIsReady = true; | |||
} | |||
#if 0 /* TODO */ | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
// custom file-browser selected | |||
void fileBrowserSelected(const char* filename) override | |||
void onFileSelected(const char* const filename) override | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||
fUI->uiFileBrowserSelected(filename); | |||
} | |||
# endif | |||
#endif | |||
private: | |||
UI* const fUI; | |||