dlangui/src/dlangui/platforms/dsfml/dsfmlapp.d

439 lines
15 KiB
D

module dlangui.platforms.dsfml.dsfmlapp;
public import dlangui.core.config;
static if (BACKEND_DSFML):
import dlangui.platforms.common.platform;
import dsfml.graphics;
import std.array;
import dlangui.core.collections;
import dlangui.core.logger;
import dlangui.widgets.widget;
import dlangui.widgets.popup;
import dlangui.graphics.drawbuf;
import dlangui.core.stdaction;
import dlangui.dialogs.msgbox;
private import dlangui.graphics.gldrawbuf;
/**
* Window abstraction layer. Widgets can be shown only inside window.
*
*/
class DSFMLWindow : dlangui.platforms.common.platform.Window {
private RenderWindow _wnd;
private bool _ownRenderWindow;
static private bool _gl3Reloaded = false;
@property RenderWindow wnd() { return _wnd; }
this(RenderWindow wnd, bool own) {
_wnd = wnd;
_ownRenderWindow = own;
super();
auto sz = wnd.size;
onResize(sz.x, sz.y);
}
~this() {
if (_ownRenderWindow) {
destroy(_wnd);
}
_wnd = null;
}
override void show() {
}
/// returns window caption
override @property dstring windowCaption() {
// TODO
return ""d;
}
/// sets window caption
override @property void windowCaption(dstring caption) {
// TODO
}
/// sets window icon
override @property void windowIcon(DrawBufRef icon) {
// TODO
}
/// request window redraw
override void invalidate() {
// TODO
}
/// close window
override void close() {
// TODO
}
void draw() {
paintUsingOpenGL();
}
private void paintUsingOpenGL() {
import derelict.opengl3.gl3;
import dlangui.graphics.gldrawbuf;
import dlangui.graphics.glsupport;
if (!_gl3Reloaded) {
DerelictGL3.reload();
_gl3Reloaded = true;
if (!glSupport.valid && !glSupport.initShaders()) {
Log.d("Cannot init opengl");
assert(0);
}
}
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, _dx, _dy);
float a = 1.0f;
float r = ((_backgroundColor >> 16) & 255) / 255.0f;
float g = ((_backgroundColor >> 8) & 255) / 255.0f;
float b = ((_backgroundColor >> 0) & 255) / 255.0f;
//glClearColor(r, g, b, a);
//glClear(GL_COLOR_BUFFER_BIT);
GLDrawBuf buf = new GLDrawBuf(_dx, _dy, false);
buf.beforeDrawing();
onDraw(buf);
buf.afterDrawing();
}
private MouseButton translateButton(uint btn) {
switch(btn) {
default:
case Mouse.Button.Left:
return MouseButton.Left;
case Mouse.Button.Right:
return MouseButton.Right;
case Mouse.Button.Middle:
return MouseButton.Middle;
case Mouse.Button.XButton1:
return MouseButton.XButton1;
case Mouse.Button.XButton2:
return MouseButton.XButton2;
}
}
private uint translateKey(uint key) {
switch(key) {
case Keyboard.Key.A: return KeyCode.KEY_A;
case Keyboard.Key.B: return KeyCode.KEY_B;
case Keyboard.Key.C: return KeyCode.KEY_C;
case Keyboard.Key.D: return KeyCode.KEY_D;
case Keyboard.Key.E: return KeyCode.KEY_E;
case Keyboard.Key.F: return KeyCode.KEY_F;
case Keyboard.Key.G: return KeyCode.KEY_G;
case Keyboard.Key.H: return KeyCode.KEY_H;
case Keyboard.Key.I: return KeyCode.KEY_I;
case Keyboard.Key.J: return KeyCode.KEY_J;
case Keyboard.Key.K: return KeyCode.KEY_K;
case Keyboard.Key.L: return KeyCode.KEY_L;
case Keyboard.Key.M: return KeyCode.KEY_M;
case Keyboard.Key.N: return KeyCode.KEY_N;
case Keyboard.Key.O: return KeyCode.KEY_O;
case Keyboard.Key.P: return KeyCode.KEY_P;
case Keyboard.Key.Q: return KeyCode.KEY_Q;
case Keyboard.Key.R: return KeyCode.KEY_R;
case Keyboard.Key.S: return KeyCode.KEY_S;
case Keyboard.Key.T: return KeyCode.KEY_T;
case Keyboard.Key.U: return KeyCode.KEY_U;
case Keyboard.Key.V: return KeyCode.KEY_V;
case Keyboard.Key.W: return KeyCode.KEY_W;
case Keyboard.Key.X: return KeyCode.KEY_X;
case Keyboard.Key.Y: return KeyCode.KEY_Y;
case Keyboard.Key.Z: return KeyCode.KEY_Z;
case Keyboard.Key.Num0: return KeyCode.KEY_0;
case Keyboard.Key.Num1: return KeyCode.KEY_1;
case Keyboard.Key.Num2: return KeyCode.KEY_2;
case Keyboard.Key.Num3: return KeyCode.KEY_3;
case Keyboard.Key.Num4: return KeyCode.KEY_4;
case Keyboard.Key.Num5: return KeyCode.KEY_5;
case Keyboard.Key.Num6: return KeyCode.KEY_6;
case Keyboard.Key.Num7: return KeyCode.KEY_7;
case Keyboard.Key.Num8: return KeyCode.KEY_8;
case Keyboard.Key.Num9: return KeyCode.KEY_9;
case Keyboard.Key.Escape: return KeyCode.ESCAPE;
case Keyboard.Key.LControl: return KeyCode.LCONTROL;
case Keyboard.Key.LShift: return KeyCode.LSHIFT;
case Keyboard.Key.LAlt: return KeyCode.LALT;
case Keyboard.Key.RControl: return KeyCode.RCONTROL;
case Keyboard.Key.RShift: return KeyCode.RSHIFT;
case Keyboard.Key.RAlt: return KeyCode.RALT;
///The [ key
case Keyboard.Key.LBracket: return KeyCode.KEY_BRACKETOPEN;
///The ] key
case Keyboard.Key.RBracket: return KeyCode.KEY_BRACKETCLOSE;
///The ; key
case Keyboard.Key.SemiColon: return KeyCode.KEY_BRACKETOPEN;
///The , key
case Keyboard.Key.Comma: return KeyCode.KEY_COMMA;
///The . key
case Keyboard.Key.Period: return KeyCode.KEY_PERIOD;
///The ' key
case Keyboard.Key.Quote: return KeyCode.QUOTE;
///The / key
case Keyboard.Key.Slash: return KeyCode.KEY_DIVIDE;
///The \ key
case Keyboard.Key.BackSlash: return KeyCode.BACKSLASH;
///The ~ key
case Keyboard.Key.Tilde: return KeyCode.TILDE;
///The = key
case Keyboard.Key.Equal: return KeyCode.EQUAL;
///The - key
case Keyboard.Key.Dash: return KeyCode.SUB;
///The Space key
case Keyboard.Key.Space: return KeyCode.SPACE;
case Keyboard.Key.Numpad0: return KeyCode.NUM_0;
case Keyboard.Key.Numpad1: return KeyCode.NUM_1;
case Keyboard.Key.Numpad2: return KeyCode.NUM_2;
case Keyboard.Key.Numpad3: return KeyCode.NUM_3;
case Keyboard.Key.Numpad4: return KeyCode.NUM_4;
case Keyboard.Key.Numpad5: return KeyCode.NUM_5;
case Keyboard.Key.Numpad6: return KeyCode.NUM_6;
case Keyboard.Key.Numpad7: return KeyCode.NUM_7;
case Keyboard.Key.Numpad8: return KeyCode.NUM_8;
case Keyboard.Key.Numpad9: return KeyCode.NUM_9;
case Keyboard.Key.F1: return KeyCode.F1;
case Keyboard.Key.F2: return KeyCode.F2;
case Keyboard.Key.F3: return KeyCode.F3;
case Keyboard.Key.F4: return KeyCode.F4;
case Keyboard.Key.F5: return KeyCode.F5;
case Keyboard.Key.F6: return KeyCode.F6;
case Keyboard.Key.F7: return KeyCode.F7;
case Keyboard.Key.F8: return KeyCode.F8;
case Keyboard.Key.F9: return KeyCode.F9;
case Keyboard.Key.F10: return KeyCode.F10;
case Keyboard.Key.F11: return KeyCode.F11;
case Keyboard.Key.F12: return KeyCode.F12;
case Keyboard.Key.F13: return KeyCode.F13;
case Keyboard.Key.F14: return KeyCode.F14;
case Keyboard.Key.F15: return KeyCode.F15;
case Keyboard.Key.Return: return KeyCode.RETURN;
case Keyboard.Key.BackSpace: return KeyCode.BACK;
case Keyboard.Key.Tab: return KeyCode.TAB;
case Keyboard.Key.PageUp: return KeyCode.PAGEUP;
case Keyboard.Key.PageDown: return KeyCode.PAGEDOWN;
case Keyboard.Key.End: return KeyCode.END;
case Keyboard.Key.Home: return KeyCode.HOME;
case Keyboard.Key.Insert: return KeyCode.INS;
case Keyboard.Key.Delete: return KeyCode.DEL;
case Keyboard.Key.Add: return KeyCode.ADD;
case Keyboard.Key.Subtract: return KeyCode.SUB;
case Keyboard.Key.Multiply: return KeyCode.MUL;
case Keyboard.Key.Divide: return KeyCode.DIV;
case Keyboard.Key.Left: return KeyCode.LEFT;
case Keyboard.Key.Right: return KeyCode.RIGHT;
case Keyboard.Key.Up: return KeyCode.UP;
case Keyboard.Key.Down: return KeyCode.DOWN;
default: return 0x8000_0000 | key;
}
}
private ushort mouseFlags;
private ushort keyFlags;
bool handleEvent(ref Event event) {
switch (event.type) {
case(event.EventType.Closed): {
break;
}
case(event.EventType.Resized): {
onResize(event.size.width, event.size.height);
break;
}
case(event.EventType.MouseButtonPressed): {
auto btn = translateButton(event.mouseButton.button);
mouseFlags |= mouseButtonToFlag(btn);
MouseEvent ev = new MouseEvent(MouseAction.ButtonDown, btn, mouseFlags, cast(short)event.mouseButton.x, cast(short)event.mouseButton.y);
return dispatchMouseEvent(ev);
}
case(event.EventType.MouseButtonReleased): {
auto btn = translateButton(event.mouseButton.button);
mouseFlags &= ~mouseButtonToFlag(btn);
MouseEvent ev = new MouseEvent(MouseAction.ButtonUp, btn, mouseFlags, cast(short)event.mouseButton.x, cast(short)event.mouseButton.y);
return dispatchMouseEvent(ev);
}
case(event.EventType.MouseMoved): {
MouseEvent ev = new MouseEvent(MouseAction.Move, MouseButton.None, mouseFlags, cast(short)event.mouseMove.x, cast(short)event.mouseMove.y);
return dispatchMouseEvent(ev);
}
case(event.EventType.MouseEntered): {
break;
}
case(event.EventType.MouseLeft): {
mouseFlags = 0;
break;
}
case(event.EventType.MouseWheelMoved): {
break;
}
case(event.EventType.TextEntered): {
KeyEvent ev = new KeyEvent(KeyAction.Text, 0, 0, [event.text.unicode]);
return dispatchKeyEvent(ev);
}
case(event.EventType.KeyReleased):
case(event.EventType.KeyPressed): {
keyFlags = 0;
if (event.key.alt)
keyFlags |= KeyFlag.Alt;
if (event.key.control)
keyFlags |= KeyFlag.Control;
if (event.key.shift)
keyFlags |= KeyFlag.Shift;
KeyEvent ev = new KeyEvent(event.type == event.EventType.KeyPressed ? KeyAction.KeyDown : KeyAction.KeyUp, translateKey(event.key.code), keyFlags, [event.text.unicode]);
return dispatchKeyEvent(ev);
}
default:
break;
}
return true;
}
}
/**
* Platform abstraction layer.
*
* Represents application.
*
*/
class DSFMLPlatform : Platform {
private DSFMLWindow[] _activeWindows;
/// register DSFML window created outside dlangui
DSFMLWindow registerWindow(RenderWindow window) {
DSFMLWindow w = new DSFMLWindow(window, false);
_activeWindows ~= w;
return w;
}
/**
* create window
* Args:
* windowCaption = window caption text
* parent = parent Window, or null if no parent
* flags = WindowFlag bit set, combination of Resizable, Modal, Fullscreen
*
* Window w/o Resizable nor Fullscreen will be created with size based on measurement of its content widget
*/
override dlangui.platforms.common.platform.Window createWindow(dstring windowCaption,
dlangui.platforms.common.platform.Window parent,
uint flags = WindowFlag.Resizable, uint width = 0, uint height = 0) {
auto window = new RenderWindow(VideoMode(800, 600, 32), "Hello DSFML!", dsfml.window.window.Window.Style.Titlebar | dsfml.window.window.Window.Style.Close | dsfml.window.window.Window.Style.Resize);
window.setFramerateLimit(60);
DSFMLWindow w = new DSFMLWindow(window, true);
_activeWindows ~= w;
return w;
}
/**
* close window
*
* Closes window earlier created with createWindow()
*/
override void closeWindow(dlangui.platforms.common.platform.Window w) {
DSFMLWindow win = cast(DSFMLWindow)w;
// TODO: support more than one window
_activeWindows[0] = null;
_activeWindows.length = 0;// = _activeWindows.remove(win);
win.wnd.close();
}
/**
* Starts application message loop.
*
* When returned from this method, application is shutting down.
*/
override int enterMessageLoop() {
// TODO: support more than one window
if (_activeWindows.length < 1)
return 1;
DSFMLWindow w = _activeWindows[0];
RenderWindow window = w.wnd;
while (window.isOpen())
{
Event event;
while(window.pollEvent(event))
{
if(event.type == event.EventType.Closed)
{
closeWindow(w);
//window.close();
}
}
window.clear();
//window.draw(head);
//window.draw(leftEye);
//window.draw(rightEye);
//window.draw(smile);
//window.draw(smileCover);
window.display();
}
return 0;
}
/// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override dstring getClipboardText(bool mouseBuffer = false) {
// TODO:
return ""d;
}
/// sets text to clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
override void setClipboardText(dstring text, bool mouseBuffer = false) {
// TODO:
}
/// calls request layout for all windows
override void requestLayout() {
// TODO:
}
}
/// shortcut to current DSFMLPlatform instance
@property DSFMLPlatform dsfmlPlatform() {
return cast(DSFMLPlatform)Platform.instance;
}
// entry point
extern(C) int UIAppMain(string[] args);
void initDSFMLApp() {
initLogs();
Log.d("Initializing DSFML platform");
DSFMLPlatform p = new DSFMLPlatform();
Platform.setInstance(p);
initFontManager();
currentTheme = createDefaultTheme();
import derelict.opengl3.gl3;
import dlangui.graphics.glsupport;
DerelictGL3.load();
if (!_glSupport)
_glSupport = new GLSupport();
Platform.instance.uiTheme = "theme_dark";
}
void uninitDSFMLApp() {
Log.d("Destroying DSFML platform");
Platform.setInstance(null);
releaseResourcesOnAppExit();
}