1 module des.gui.sdlgl.window; 2 3 import des.gui.sdlgl.base; 4 5 import des.gui.event; 6 import des.gui.sdlgl.context; 7 import des.gui.sdlgl.canvas; 8 9 import std.conv; 10 11 class NotInputEventException : Exception 12 { this() @safe pure nothrow { super( "service exception" ); } } 13 14 /// SDL window with open gl 15 class DiSDLGLWindow : DesObject 16 { 17 mixin DES; 18 19 package: 20 21 SDL_Window* win = null; 22 23 void prepare() 24 { 25 _canvas.prepare(); 26 } 27 28 protected: 29 30 ivec2 _size; 31 32 DiSDLGLContext ctx; 33 34 DiWidget _widget; 35 DiGLCanvas _canvas; 36 37 public: 38 39 enum Flag : uint 40 { 41 FULLSCREEN = SDL_WINDOW_FULLSCREEN, /// `SDL_WINDOW_FULLSCREEN` 42 FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN_DESKTOP, /// `SDL_WINDOW_FULLSCREEN_DESKTOP` 43 OPENGL = SDL_WINDOW_OPENGL, /// `SDL_WINDOW_OPENGL` 44 SHOWN = SDL_WINDOW_SHOWN, /// `SDL_WINDOW_SHOWN` 45 HIDDEN = SDL_WINDOW_HIDDEN, /// `SDL_WINDOW_HIDDEN` 46 BORDERLESS = SDL_WINDOW_BORDERLESS, /// `SDL_WINDOW_BORDERLESS` 47 RESIZABLE = SDL_WINDOW_RESIZABLE, /// `SDL_WINDOW_RESIZABLE` 48 MINIMIZED = SDL_WINDOW_MINIMIZED, /// `SDL_WINDOW_MINIMIZED` 49 MAXIMIZED = SDL_WINDOW_MAXIMIZED, /// `SDL_WINDOW_MAXIMIZED` 50 INPUT_GRABBED = SDL_WINDOW_INPUT_GRABBED, /// `SDL_WINDOW_INPUT_GRABBED` 51 INPUT_FOCUS = SDL_WINDOW_INPUT_FOCUS, /// `SDL_WINDOW_INPUT_FOCUS` 52 MOUSE_FOCUS = SDL_WINDOW_MOUSE_FOCUS, /// `SDL_WINDOW_MOUSE_FOCUS` 53 FOREIGN = SDL_WINDOW_FOREIGN, /// `SDL_WINDOW_FOREIGN` 54 ALLOW_HIGHDPI = SDL_WINDOW_ALLOW_HIGHDPI, /// `SDL_WINDOW_ALLOW_HIGHDPI` 55 } 56 57 this( DiSDLGLContext ctx, DiWidget w ) 58 { 59 bool fullscreen = false; 60 int display = 0; 61 62 _widget = w; 63 this.ctx = ctx; 64 65 createWindow( to!string(w.name), w.size, fullscreen, display ); 66 67 _canvas = newEMM!DiGLCanvas; 68 69 logger.Debug( "pass" ); 70 } 71 72 /// 73 DiWidget widget() @property { return _widget; } 74 75 /// 76 DiCanvas canvas() @property { return _canvas; } 77 78 /// 79 //Предполагается, что входящее событие предназначено именно этому окну 80 void procEvent( in SDL_Event ev ) 81 { 82 try widget.processInput( convToInputEvent(ev) ); 83 catch( NotInputEventException ) 84 { 85 /+ TODO: process window, user, quit etc +/ 86 } 87 88 if( ev.type == SDL_WINDOWEVENT && 89 ev.window.event == SDL_WINDOWEVENT_RESIZED ) 90 { 91 _size = ivec2( ev.window.data1, ev.window.data2 ); 92 _canvas.resize( _size ); 93 widget.shape.rect = DiRect( 0, 0, _size ); 94 } 95 } 96 97 void step() 98 { 99 makeCurrent(); 100 widget.update(); 101 102 preDraw(); 103 widget.render(); 104 postDraw(); 105 } 106 107 @property 108 { 109 /// 110 uint id() { return SDL_GetWindowID( win ); } 111 112 /// 113 ivec2 size() const { return _size; } 114 115 /// 116 float brightness() const 117 { return SDL_GetWindowBrightness( cast(SDL_Window*)win ); } 118 119 /// 120 float brightness( float v ) 121 { 122 SDL_SetWindowBrightness( win, v ); 123 return v; 124 } 125 126 /// 127 int displayIndex() const 128 { return SDL_GetWindowDisplayIndex( cast(SDL_Window*)win ); } 129 } 130 131 /// 132 void show() { SDL_ShowWindow( win ); } 133 /// 134 void hide() { SDL_HideWindow( win ); } 135 136 /// 137 bool checkFlag( Flag flag ) const { return cast(bool)( SDLFlags & flag ); } 138 139 const @property 140 { 141 /// 142 bool isFullscreen() { return checkFlag( Flag.FULLSCREEN ); } 143 /// 144 bool isFullscreenDesktop() { return checkFlag( Flag.FULLSCREEN_DESKTOP ); } 145 /// 146 bool isOpenGL() { return checkFlag( Flag.OPENGL ); } 147 /// 148 bool isShown() { return checkFlag( Flag.SHOWN ); } 149 /// 150 bool isHidden() { return checkFlag( Flag.HIDDEN ); } 151 /// 152 bool isBorderless() { return checkFlag( Flag.BORDERLESS ); } 153 /// 154 bool isResizable() { return checkFlag( Flag.RESIZABLE ); } 155 /// 156 bool isMinimized() { return checkFlag( Flag.MINIMIZED ); } 157 /// 158 bool isMaximized() { return checkFlag( Flag.MAXIMIZED ); } 159 /// 160 bool isInputGrabbed() { return checkFlag( Flag.INPUT_GRABBED ); } 161 /// 162 bool isInputFocus() { return checkFlag( Flag.INPUT_FOCUS ); } 163 /// 164 bool isMouseFocus() { return checkFlag( Flag.MOUSE_FOCUS ); } 165 /// 166 bool isForeign() { return checkFlag( Flag.FOREIGN ); } 167 /// 168 bool isAllowHighdpi() { return checkFlag( Flag.ALLOW_HIGHDPI ); } 169 } 170 171 void startTextInput() { ctx.startTextInput(); } 172 void stopTextInput() { ctx.stopTextInput(); } 173 174 protected: 175 176 DiInputEvent convToInputEvent( in SDL_Event ev ) const 177 { 178 switch( ev.type ) 179 { 180 case SDL_KEYDOWN: 181 case SDL_KEYUP: 182 case SDL_MOUSEMOTION: 183 case SDL_MOUSEBUTTONDOWN: 184 case SDL_MOUSEBUTTONUP: 185 case SDL_MOUSEWHEEL: 186 case SDL_TEXTINPUT: 187 case SDL_TEXTEDITING: 188 case SDL_JOYAXISMOTION: 189 case SDL_JOYBALLMOTION: 190 case SDL_JOYHATMOTION: 191 case SDL_JOYBUTTONUP: 192 case SDL_JOYBUTTONDOWN: 193 case SDL_JOYDEVICEADDED: 194 case SDL_JOYDEVICEREMOVED: 195 case SDL_FINGERDOWN: 196 case SDL_FINGERUP: 197 case SDL_FINGERMOTION: 198 case SDL_DROPFILE: 199 return cast(DiInputEvent)ev; 200 default: 201 throw new NotInputEventException; 202 } 203 } 204 205 void preDraw() { canvas.preDraw(); } 206 void postDraw() 207 { 208 canvas.postDraw(); 209 SDL_GL_SwapWindow( win ); 210 } 211 void makeCurrent() { SDL_GL_MakeCurrent( win, ctx.context ); } 212 213 /// 214 uint SDLFlags() const @property 215 { return SDL_GetWindowFlags( cast(SDL_Window*)win ); } 216 217 void createWindow( string title, ivec2 sz, bool fullscreen, int display ) 218 { 219 _size = sz; 220 if( display != -1 && display > SDL_GetNumVideoDisplays() - 1 ) 221 throw new DiException( format( "No such display: display%d", display ) ); 222 223 auto flags = Flag.OPENGL | Flag.SHOWN | ( fullscreen ? Flag.FULLSCREEN : Flag.RESIZABLE ); 224 225 auto pos = ivec2( SDL_WINDOWPOS_CENTERED ); 226 227 if( display != -1 ) 228 pos = ivec2( SDL_WINDOWPOS_CENTERED_DISPLAY( display ) ); 229 230 win = SDL_CreateWindow( title.toStringz, pos.x, pos.y, _size.x, _size.y, flags ); 231 if( win is null ) 232 throw new DiException( "Couldn't create SDL widnow: " ~ toDString( SDL_GetError() ) ); 233 } 234 235 override void selfDestroy() 236 { 237 if( win !is null ) 238 SDL_DestroyWindow( win ); 239 win = null; 240 debug logger.Debug("pass"); 241 } 242 }