#ifndef SOLVESPACE_GUI_H
#define SOLVESPACE_GUI_H
namespace SolveSpace {
class RgbaColor;
namespace Platform {
class MouseEvent {
public:
enum class Type {
MOTION,
PRESS,
DBL_PRESS,
RELEASE,
SCROLL_VERT,
LEAVE,
};
enum class Button {
NONE,
LEFT,
MIDDLE,
RIGHT,
};
Type type;
double x;
double y;
bool shiftDown;
bool controlDown;
union {
Button button; double scrollDelta; };
};
struct SixDofEvent {
enum class Type {
MOTION,
PRESS,
RELEASE,
};
enum class Button {
FIT,
};
Type type;
bool shiftDown;
bool controlDown;
double translationX, translationY, translationZ; double rotationX, rotationY, rotationZ; Button button; };
struct KeyboardEvent {
enum class Type {
PRESS,
RELEASE,
};
enum class Key {
CHARACTER,
FUNCTION,
};
Type type;
Key key;
union {
char32_t chr; int num; };
bool shiftDown;
bool controlDown;
bool Equals(const KeyboardEvent &other) {
return type == other.type && key == other.key &&
shiftDown == other.shiftDown && controlDown == other.controlDown &&
((key == Key::CHARACTER && chr == other.chr) ||
(key == Key::FUNCTION && num == other.num));
}
};
std::string AcceleratorDescription(const KeyboardEvent &accel);
[[noreturn]]
void FatalError(const std::string &message);
class Settings {
public:
virtual ~Settings() = default;
virtual void FreezeInt(const std::string &key, uint32_t value) = 0;
virtual uint32_t ThawInt(const std::string &key, uint32_t defaultValue = 0) = 0;
virtual void FreezeFloat(const std::string &key, double value) = 0;
virtual double ThawFloat(const std::string &key, double defaultValue = 0.0) = 0;
virtual void FreezeString(const std::string &key, const std::string &value) = 0;
virtual std::string ThawString(const std::string &key,
const std::string &defaultValue = "") = 0;
virtual void FreezeBool(const std::string &key, bool value);
virtual bool ThawBool(const std::string &key, bool defaultValue = false);
virtual void FreezeColor(const std::string &key, RgbaColor value);
virtual RgbaColor ThawColor(const std::string &key, RgbaColor defaultValue);
};
typedef std::shared_ptr<Settings> SettingsRef;
SettingsRef GetSettings();
class Timer {
public:
std::function<void()> onTimeout;
virtual ~Timer() = default;
virtual void RunAfter(unsigned milliseconds) = 0;
virtual void RunAfterNextFrame() { RunAfter(1); }
virtual void RunAfterProcessingEvents() { RunAfter(0); }
};
typedef std::shared_ptr<Timer> TimerRef;
TimerRef CreateTimer();
class MenuItem {
public:
enum class Indicator {
NONE,
CHECK_MARK,
RADIO_MARK,
};
std::function<void()> onTrigger;
virtual ~MenuItem() = default;
virtual void SetAccelerator(KeyboardEvent accel) = 0;
virtual void SetIndicator(Indicator type) = 0;
virtual void SetEnabled(bool enabled) = 0;
virtual void SetActive(bool active) = 0;
};
typedef std::shared_ptr<MenuItem> MenuItemRef;
class Menu {
public:
virtual ~Menu() = default;
virtual std::shared_ptr<MenuItem> AddItem(
const std::string &label, std::function<void()> onTrigger = std::function<void()>(),
bool mnemonics = true) = 0;
virtual std::shared_ptr<Menu> AddSubMenu(const std::string &label) = 0;
virtual void AddSeparator() = 0;
virtual void PopUp() = 0;
virtual void Clear() = 0;
};
typedef std::shared_ptr<Menu> MenuRef;
class MenuBar {
public:
virtual ~MenuBar() = default;
virtual std::shared_ptr<Menu> AddSubMenu(const std::string &label) = 0;
virtual void Clear() = 0;
};
typedef std::shared_ptr<MenuBar> MenuBarRef;
MenuRef CreateMenu();
MenuBarRef GetOrCreateMainMenu(bool *unique);
class Window {
public:
enum class Kind {
TOPLEVEL,
TOOL,
};
enum class Cursor {
POINTER,
HAND
};
std::function<void()> onClose;
std::function<void(bool)> onFullScreen;
std::function<bool(MouseEvent)> onMouseEvent;
std::function<void(SixDofEvent)> onSixDofEvent;
std::function<bool(KeyboardEvent)> onKeyboardEvent;
std::function<void(std::string)> onEditingDone;
std::function<void(double)> onScrollbarAdjusted;
std::function<void()> onContextLost;
std::function<void()> onRender;
virtual ~Window() = default;
virtual double GetPixelDensity() = 0;
virtual double GetDevicePixelRatio() = 0;
virtual double GetDeviceFontScale() {
return GetPixelDensity() / GetDevicePixelRatio() / 96.0;
}
virtual bool IsVisible() = 0;
virtual void SetVisible(bool visible) = 0;
virtual void Focus() = 0;
virtual bool IsFullScreen() = 0;
virtual void SetFullScreen(bool fullScreen) = 0;
virtual void SetTitle(const std::string &title) = 0;
virtual bool SetTitleForFilename(const Path &filename) { return false; }
virtual void SetMenuBar(MenuBarRef menuBar) = 0;
virtual void GetContentSize(double *width, double *height) = 0;
virtual void SetMinContentSize(double width, double height) = 0;
virtual void FreezePosition(SettingsRef settings, const std::string &key) = 0;
virtual void ThawPosition(SettingsRef settings, const std::string &key) = 0;
virtual void SetCursor(Cursor cursor) = 0;
virtual void SetTooltip(const std::string &text, double x, double y,
double width, double height) = 0;
virtual bool IsEditorVisible() = 0;
virtual void ShowEditor(double x, double y, double fontHeight, double minWidth,
bool isMonospace, const std::string &text) = 0;
virtual void HideEditor() = 0;
virtual void SetScrollbarVisible(bool visible) = 0;
virtual void ConfigureScrollbar(double min, double max, double pageSize) = 0;
virtual double GetScrollbarPosition() = 0;
virtual void SetScrollbarPosition(double pos) = 0;
virtual void Invalidate() = 0;
};
typedef std::shared_ptr<Window> WindowRef;
WindowRef CreateWindow(Window::Kind kind = Window::Kind::TOPLEVEL,
WindowRef parentWindow = NULL);
void Open3DConnexion();
void Close3DConnexion();
void Request3DConnexionEventsForWindow(WindowRef window);
class MessageDialog {
public:
enum class Type {
INFORMATION,
QUESTION,
WARNING,
ERROR
};
enum class Response {
NONE,
OK,
YES,
NO,
CANCEL
};
std::function<void(Response)> onResponse;
virtual ~MessageDialog() = default;
virtual void SetType(Type type) = 0;
virtual void SetTitle(std::string title) = 0;
virtual void SetMessage(std::string message) = 0;
virtual void SetDescription(std::string description) = 0;
virtual void AddButton(std::string label, Response response, bool isDefault = false) = 0;
virtual Response RunModal() = 0;
virtual void ShowModal() {
Response response = RunModal();
if(onResponse) {
onResponse(response);
}
}
};
typedef std::shared_ptr<MessageDialog> MessageDialogRef;
MessageDialogRef CreateMessageDialog(WindowRef parentWindow);
struct FileFilter {
std::string name;
std::vector<std::string> extensions;
};
extern std::vector<FileFilter> SolveSpaceModelFileFilters;
extern std::vector<FileFilter> SolveSpaceLinkFileFilters;
extern std::vector<FileFilter> RasterFileFilters;
extern std::vector<FileFilter> MeshFileFilters;
extern std::vector<FileFilter> SurfaceFileFilters;
extern std::vector<FileFilter> VectorFileFilters;
extern std::vector<FileFilter> Vector3dFileFilters;
extern std::vector<FileFilter> ImportFileFilters;
extern std::vector<FileFilter> CsvFileFilters;
class FileDialog {
public:
virtual ~FileDialog() = default;
virtual void SetTitle(std::string title) = 0;
virtual void SetCurrentName(std::string name) = 0;
virtual Platform::Path GetFilename() = 0;
virtual void SetFilename(Platform::Path path) = 0;
virtual void SuggestFilename(Platform::Path path) = 0;
virtual void AddFilter(std::string name, std::vector<std::string> extensions) = 0;
void AddFilter(const FileFilter &filter);
void AddFilters(const std::vector<FileFilter> &filters);
virtual void FreezeChoices(SettingsRef settings, const std::string &key) = 0;
virtual void ThawChoices(SettingsRef settings, const std::string &key) = 0;
virtual bool RunModal() = 0;
};
typedef std::shared_ptr<FileDialog> FileDialogRef;
FileDialogRef CreateOpenFileDialog(WindowRef parentWindow);
FileDialogRef CreateSaveFileDialog(WindowRef parentWindow);
std::vector<Platform::Path> GetFontFiles();
void OpenInBrowser(const std::string &url);
std::vector<std::string> InitGui(int argc, char **argv);
void RunGui();
void ExitGui();
void ClearGui();
}
}
#endif