Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1452 | chris | 1 | #region License |
| 2 | // |
||
| 3 | // The Open Toolkit Library License |
||
| 4 | // |
||
| 5 | // Copyright (c) 2006 - 2009 the Open Toolkit library. |
||
| 6 | // |
||
| 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
||
| 8 | // of this software and associated documentation files (the "Software"), to deal |
||
| 9 | // in the Software without restriction, including without limitation the rights to |
||
| 10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||
| 11 | // the Software, and to permit persons to whom the Software is furnished to do |
||
| 12 | // so, subject to the following conditions: |
||
| 13 | // |
||
| 14 | // The above copyright notice and this permission notice shall be included in all |
||
| 15 | // copies or substantial portions of the Software. |
||
| 16 | // |
||
| 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||
| 18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||
| 19 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||
| 20 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||
| 21 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||
| 22 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
| 23 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
| 24 | // OTHER DEALINGS IN THE SOFTWARE. |
||
| 25 | // |
||
| 26 | #endregion |
||
| 27 | |||
| 28 | using System; |
||
| 29 | using System.Collections.Generic; |
||
| 30 | using System.ComponentModel; |
||
| 31 | using System.Diagnostics; |
||
| 32 | using System.Drawing; |
||
| 33 | using System.Text; |
||
| 34 | |||
| 35 | namespace OpenTK.Platform.MacOS |
||
| 36 | { |
||
| 37 | using Carbon; |
||
| 38 | using Graphics; |
||
| 39 | |||
| 40 | class CarbonGLNative : INativeWindow |
||
| 41 | { |
||
| 42 | #region Fields |
||
| 43 | |||
| 44 | CarbonWindowInfo window; |
||
| 45 | CarbonInput mInputDriver; |
||
| 46 | |||
| 47 | static MacOSKeyMap Keymap = new MacOSKeyMap(); |
||
| 48 | |||
| 49 | IntPtr uppHandler; |
||
| 50 | |||
| 51 | string title = "OpenTK Window"; |
||
| 52 | Rectangle bounds, clientRectangle; |
||
| 53 | Rectangle windowedBounds; |
||
| 54 | bool mIsDisposed = false; |
||
| 55 | bool mExists = true; |
||
| 56 | DisplayDevice mDisplayDevice; |
||
| 57 | |||
| 58 | WindowAttributes mWindowAttrib; |
||
| 59 | WindowClass mWindowClass; |
||
| 60 | WindowPositionMethod mPositionMethod = WindowPositionMethod.CenterOnMainScreen; |
||
| 61 | int mTitlebarHeight; |
||
| 62 | private WindowBorder windowBorder = WindowBorder.Resizable; |
||
| 63 | private WindowState windowState = WindowState.Normal; |
||
| 64 | |||
| 65 | static Dictionary<IntPtr, WeakReference> mWindows = new Dictionary<IntPtr, WeakReference>(); |
||
| 66 | |||
| 67 | KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0); |
||
| 68 | |||
| 69 | bool mMouseIn = false; |
||
| 70 | bool mIsActive = false; |
||
| 71 | |||
| 72 | Icon mIcon; |
||
| 73 | |||
| 74 | #endregion |
||
| 75 | |||
| 76 | #region AGL Device Hack |
||
| 77 | |||
| 78 | static internal Dictionary<IntPtr, WeakReference> WindowRefMap { get { return mWindows; } } |
||
| 79 | internal DisplayDevice TargetDisplayDevice { get { return mDisplayDevice; } } |
||
| 80 | |||
| 81 | #endregion |
||
| 82 | |||
| 83 | #region Constructors |
||
| 84 | |||
| 85 | static CarbonGLNative() |
||
| 86 | { |
||
| 87 | Application.Initialize(); |
||
| 88 | } |
||
| 89 | |||
| 90 | CarbonGLNative() |
||
| 91 | : this(WindowClass.Document, |
||
| 92 | WindowAttributes.StandardDocument | |
||
| 93 | WindowAttributes.StandardHandler | |
||
| 94 | WindowAttributes.InWindowMenu | |
||
| 95 | WindowAttributes.LiveResize) |
||
| 96 | { } |
||
| 97 | |||
| 98 | |||
| 99 | CarbonGLNative(WindowClass @class, WindowAttributes attrib) |
||
| 100 | { |
||
| 101 | mWindowClass = @class; |
||
| 102 | mWindowAttrib = attrib; |
||
| 103 | } |
||
| 104 | |||
| 105 | public CarbonGLNative(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device) |
||
| 106 | { |
||
| 107 | CreateNativeWindow(WindowClass.Document, |
||
| 108 | WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | |
||
| 109 | WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, |
||
| 110 | new Rect((short)x, (short)y, (short)width, (short)height)); |
||
| 111 | |||
| 112 | mDisplayDevice = device; |
||
| 113 | } |
||
| 114 | |||
| 115 | #endregion |
||
| 116 | |||
| 117 | #region IDisposable |
||
| 118 | |||
| 119 | public void Dispose() |
||
| 120 | { |
||
| 121 | Dispose(true); |
||
| 122 | GC.SuppressFinalize(this); |
||
| 123 | } |
||
| 124 | |||
| 125 | protected virtual void Dispose(bool disposing) |
||
| 126 | { |
||
| 127 | if (mIsDisposed) |
||
| 128 | return; |
||
| 129 | |||
| 130 | Debug.Print("Disposing of CarbonGLNative window."); |
||
| 131 | |||
| 132 | API.DisposeWindow(window.WindowRef); |
||
| 133 | |||
| 134 | mIsDisposed = true; |
||
| 135 | mExists = false; |
||
| 136 | |||
| 137 | if (disposing) |
||
| 138 | { |
||
| 139 | mWindows.Remove(window.WindowRef); |
||
| 140 | |||
| 141 | window.Dispose(); |
||
| 142 | window = null; |
||
| 143 | } |
||
| 144 | |||
| 145 | DisposeUPP(); |
||
| 146 | |||
| 147 | } |
||
| 148 | |||
| 149 | ~CarbonGLNative() |
||
| 150 | { |
||
| 151 | Dispose(false); |
||
| 152 | } |
||
| 153 | |||
| 154 | #endregion |
||
| 155 | |||
| 156 | #region Private Members |
||
| 157 | |||
| 158 | void DisposeUPP() |
||
| 159 | { |
||
| 160 | if (uppHandler != IntPtr.Zero) |
||
| 161 | { |
||
| 162 | //API.RemoveEventHandler(uppHandler); |
||
| 163 | //API.DisposeEventHandlerUPP(uppHandler); |
||
| 164 | } |
||
| 165 | |||
| 166 | uppHandler = IntPtr.Zero; |
||
| 167 | } |
||
| 168 | |||
| 169 | void CreateNativeWindow(WindowClass @class, WindowAttributes attrib, Rect r) |
||
| 170 | { |
||
| 171 | Debug.Print("Creating window..."); |
||
| 172 | Debug.Indent(); |
||
| 173 | |||
| 174 | IntPtr windowRef = API.CreateNewWindow(@class, attrib, r); |
||
| 175 | API.SetWindowTitle(windowRef, title); |
||
| 176 | |||
| 177 | window = new CarbonWindowInfo(windowRef, true, false); |
||
| 178 | |||
| 179 | SetLocation(r.X, r.Y); |
||
| 180 | SetSize(r.Width, r.Height); |
||
| 181 | |||
| 182 | Debug.Unindent(); |
||
| 183 | Debug.Print("Created window."); |
||
| 184 | |||
| 185 | mWindows.Add(windowRef, new WeakReference(this)); |
||
| 186 | |||
| 187 | LoadSize(); |
||
| 188 | |||
| 189 | Rect titleSize = API.GetWindowBounds(window.WindowRef, WindowRegionCode.TitleBarRegion); |
||
| 190 | mTitlebarHeight = titleSize.Height; |
||
| 191 | |||
| 192 | Debug.Print("Titlebar size: {0}", titleSize); |
||
| 193 | |||
| 194 | ConnectEvents(); |
||
| 195 | |||
| 196 | System.Diagnostics.Debug.Print("Attached window events."); |
||
| 197 | } |
||
| 198 | |||
| 199 | void ConnectEvents() |
||
| 200 | { |
||
| 201 | mInputDriver = new CarbonInput(); |
||
| 202 | |||
| 203 | EventTypeSpec[] eventTypes = new EventTypeSpec[] |
||
| 204 | { |
||
| 205 | new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose), |
||
| 206 | new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed), |
||
| 207 | new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged), |
||
| 208 | new EventTypeSpec(EventClass.Window, WindowEventKind.WindowActivate), |
||
| 209 | new EventTypeSpec(EventClass.Window, WindowEventKind.WindowDeactivate), |
||
| 210 | |||
| 211 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown), |
||
| 212 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp), |
||
| 213 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved), |
||
| 214 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged), |
||
| 215 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered), |
||
| 216 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited), |
||
| 217 | //new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved), |
||
| 218 | |||
| 219 | //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown), |
||
| 220 | //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat), |
||
| 221 | //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp), |
||
| 222 | //new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged), |
||
| 223 | }; |
||
| 224 | |||
| 225 | MacOSEventHandler handler = EventHandler; |
||
| 226 | uppHandler = API.NewEventHandlerUPP(handler); |
||
| 227 | |||
| 228 | API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero); |
||
| 229 | |||
| 230 | Application.WindowEventHandler = this; |
||
| 231 | } |
||
| 232 | |||
| 233 | void Activate() |
||
| 234 | { |
||
| 235 | API.SelectWindow(window.WindowRef); |
||
| 236 | } |
||
| 237 | |||
| 238 | void Show() |
||
| 239 | { |
||
| 240 | IntPtr parent = IntPtr.Zero; |
||
| 241 | |||
| 242 | API.ShowWindow(window.WindowRef); |
||
| 243 | API.RepositionWindow(window.WindowRef, parent, WindowPositionMethod); |
||
| 244 | API.SelectWindow(window.WindowRef); |
||
| 245 | } |
||
| 246 | |||
| 247 | void Hide() |
||
| 248 | { |
||
| 249 | API.HideWindow(window.WindowRef); |
||
| 250 | } |
||
| 251 | |||
| 252 | internal void SetFullscreen(AglContext context) |
||
| 253 | { |
||
| 254 | windowedBounds = bounds; |
||
| 255 | |||
| 256 | int width, height; |
||
| 257 | |||
| 258 | context.SetFullScreen(window, out width, out height); |
||
| 259 | |||
| 260 | Debug.Print("Prev Size: {0}, {1}", Width, Height); |
||
| 261 | clientRectangle.Size = new Size(width, height); |
||
| 262 | Debug.Print("New Size: {0}, {1}", Width, Height); |
||
| 263 | |||
| 264 | // TODO: if we go full screen we need to make this use the device specified. |
||
| 265 | bounds = mDisplayDevice.Bounds; |
||
| 266 | |||
| 267 | |||
| 268 | windowState = WindowState.Fullscreen; |
||
| 269 | } |
||
| 270 | |||
| 271 | internal void UnsetFullscreen(AglContext context) |
||
| 272 | { |
||
| 273 | context.UnsetFullScreen(window); |
||
| 274 | |||
| 275 | Debug.Print("Telling Carbon to reset window state to " + windowState.ToString()); |
||
| 276 | SetCarbonWindowState(); |
||
| 277 | |||
| 278 | SetSize((short)windowedBounds.Width, (short)windowedBounds.Height); |
||
| 279 | } |
||
| 280 | |||
| 281 | bool IsDisposed |
||
| 282 | { |
||
| 283 | get { return mIsDisposed; } |
||
| 284 | } |
||
| 285 | |||
| 286 | WindowPositionMethod WindowPositionMethod |
||
| 287 | { |
||
| 288 | get { return mPositionMethod; } |
||
| 289 | set { mPositionMethod = value; } |
||
| 290 | } |
||
| 291 | |||
| 292 | internal OSStatus DispatchEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) |
||
| 293 | { |
||
| 294 | switch (evt.EventClass) |
||
| 295 | { |
||
| 296 | case EventClass.Window: |
||
| 297 | return ProcessWindowEvent(inCaller, inEvent, evt, userData); |
||
| 298 | |||
| 299 | case EventClass.Mouse: |
||
| 300 | return ProcessMouseEvent(inCaller, inEvent, evt, userData); |
||
| 301 | |||
| 302 | case EventClass.Keyboard: |
||
| 303 | return ProcessKeyboardEvent(inCaller, inEvent, evt, userData); |
||
| 304 | |||
| 305 | default: |
||
| 306 | return OSStatus.EventNotHandled; |
||
| 307 | } |
||
| 308 | } |
||
| 309 | |||
| 310 | protected static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData) |
||
| 311 | { |
||
| 312 | // bail out if the window passed in is not actually our window. |
||
| 313 | // I think this happens if using winforms with a GameWindow sometimes. |
||
| 314 | if (mWindows.ContainsKey(userData) == false) |
||
| 315 | return OSStatus.EventNotHandled; |
||
| 316 | |||
| 317 | WeakReference reference = mWindows[userData]; |
||
| 318 | |||
| 319 | // bail out if the CarbonGLNative window has been garbage collected. |
||
| 320 | if (reference.IsAlive == false) |
||
| 321 | { |
||
| 322 | mWindows.Remove(userData); |
||
| 323 | return OSStatus.EventNotHandled; |
||
| 324 | } |
||
| 325 | |||
| 326 | CarbonGLNative window = (CarbonGLNative)reference.Target; |
||
| 327 | EventInfo evt = new EventInfo(inEvent); |
||
| 328 | |||
| 329 | //Debug.Print("Processing {0} event for {1}.", evt, window.window); |
||
| 330 | |||
| 331 | if (window == null) |
||
| 332 | { |
||
| 333 | Debug.WriteLine("Window for event not found."); |
||
| 334 | return OSStatus.EventNotHandled; |
||
| 335 | } |
||
| 336 | |||
| 337 | switch (evt.EventClass) |
||
| 338 | { |
||
| 339 | case EventClass.Window: |
||
| 340 | return window.ProcessWindowEvent(inCaller, inEvent, evt, userData); |
||
| 341 | |||
| 342 | case EventClass.Mouse: |
||
| 343 | return window.ProcessMouseEvent(inCaller, inEvent, evt, userData); |
||
| 344 | |||
| 345 | case EventClass.Keyboard: |
||
| 346 | return window.ProcessKeyboardEvent(inCaller, inEvent, evt, userData); |
||
| 347 | |||
| 348 | default: |
||
| 349 | return OSStatus.EventNotHandled; |
||
| 350 | } |
||
| 351 | } |
||
| 352 | |||
| 353 | private OSStatus ProcessKeyboardEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) |
||
| 354 | { |
||
| 355 | System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Keyboard); |
||
| 356 | MacOSKeyCode code = (MacOSKeyCode)0; |
||
| 357 | char charCode = '\0'; |
||
| 358 | |||
| 359 | //Debug.Print("Processing keyboard event {0}", evt.KeyboardEventKind); |
||
| 360 | |||
| 361 | switch (evt.KeyboardEventKind) |
||
| 362 | { |
||
| 363 | case KeyboardEventKind.RawKeyDown: |
||
| 364 | case KeyboardEventKind.RawKeyRepeat: |
||
| 365 | case KeyboardEventKind.RawKeyUp: |
||
| 366 | GetCharCodes(inEvent, out code, out charCode); |
||
| 367 | mKeyPressArgs.KeyChar = charCode; |
||
| 368 | break; |
||
| 369 | } |
||
| 370 | |||
| 371 | switch (evt.KeyboardEventKind) |
||
| 372 | { |
||
| 373 | case KeyboardEventKind.RawKeyRepeat: |
||
| 374 | InputDriver.Keyboard[0].KeyRepeat = true; |
||
| 375 | goto case KeyboardEventKind.RawKeyDown; |
||
| 376 | |||
| 377 | case KeyboardEventKind.RawKeyDown: |
||
| 378 | OnKeyPress(mKeyPressArgs); |
||
| 379 | InputDriver.Keyboard[0][Keymap[code]] = true; |
||
| 380 | return OSStatus.NoError; |
||
| 381 | |||
| 382 | case KeyboardEventKind.RawKeyUp: |
||
| 383 | InputDriver.Keyboard[0][Keymap[code]] = false; |
||
| 384 | |||
| 385 | return OSStatus.NoError; |
||
| 386 | |||
| 387 | case KeyboardEventKind.RawKeyModifiersChanged: |
||
| 388 | ProcessModifierKey(inEvent); |
||
| 389 | return OSStatus.NoError; |
||
| 390 | |||
| 391 | default: |
||
| 392 | return OSStatus.EventNotHandled; |
||
| 393 | } |
||
| 394 | |||
| 395 | |||
| 396 | } |
||
| 397 | |||
| 398 | private OSStatus ProcessWindowEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) |
||
| 399 | { |
||
| 400 | System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Window); |
||
| 401 | |||
| 402 | switch (evt.WindowEventKind) |
||
| 403 | { |
||
| 404 | case WindowEventKind.WindowClose: |
||
| 405 | CancelEventArgs cancel = new CancelEventArgs(); |
||
| 406 | OnClosing(cancel); |
||
| 407 | |||
| 408 | if (cancel.Cancel) |
||
| 409 | return OSStatus.NoError; |
||
| 410 | else |
||
| 411 | return OSStatus.EventNotHandled; |
||
| 412 | |||
| 413 | case WindowEventKind.WindowClosed: |
||
| 414 | mExists = false; |
||
| 415 | OnClosed(); |
||
| 416 | |||
| 417 | return OSStatus.NoError; |
||
| 418 | |||
| 419 | case WindowEventKind.WindowBoundsChanged: |
||
| 420 | int thisWidth = Width; |
||
| 421 | int thisHeight = Height; |
||
| 422 | |||
| 423 | LoadSize(); |
||
| 424 | |||
| 425 | if (thisWidth != Width || thisHeight != Height) |
||
| 426 | OnResize(); |
||
| 427 | |||
| 428 | return OSStatus.EventNotHandled; |
||
| 429 | |||
| 430 | case WindowEventKind.WindowActivate: |
||
| 431 | OnActivate(); |
||
| 432 | return OSStatus.EventNotHandled; |
||
| 433 | |||
| 434 | case WindowEventKind.WindowDeactivate: |
||
| 435 | OnDeactivate(); |
||
| 436 | return OSStatus.EventNotHandled; |
||
| 437 | |||
| 438 | default: |
||
| 439 | Debug.Print("{0}", evt); |
||
| 440 | |||
| 441 | return OSStatus.EventNotHandled; |
||
| 442 | } |
||
| 443 | } |
||
| 444 | protected OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) |
||
| 445 | { |
||
| 446 | System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse); |
||
| 447 | MouseButton button = MouseButton.Primary; |
||
| 448 | HIPoint pt = new HIPoint(); |
||
| 449 | HIPoint screenLoc = new HIPoint(); |
||
| 450 | |||
| 451 | OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc); |
||
| 452 | |||
| 453 | if (this.windowState == WindowState.Fullscreen) |
||
| 454 | { |
||
| 455 | pt = screenLoc; |
||
| 456 | } |
||
| 457 | else |
||
| 458 | { |
||
| 459 | err = API.GetEventWindowMouseLocation(inEvent, out pt); |
||
| 460 | } |
||
| 461 | |||
| 462 | if (err != OSStatus.NoError) |
||
| 463 | { |
||
| 464 | // this error comes up from the application event handler. |
||
| 465 | if (err != OSStatus.EventParameterNotFound) |
||
| 466 | { |
||
| 467 | throw new MacOSException(err); |
||
| 468 | } |
||
| 469 | } |
||
| 470 | |||
| 471 | Point mousePosInClient = new Point((int)pt.X, (int)pt.Y); |
||
| 472 | if (this.windowState != WindowState.Fullscreen) |
||
| 473 | { |
||
| 474 | mousePosInClient.Y -= mTitlebarHeight; |
||
| 475 | } |
||
| 476 | |||
| 477 | // check for enter/leave events |
||
| 478 | IntPtr thisEventWindow; |
||
| 479 | API.GetEventWindowRef(inEvent, out thisEventWindow); |
||
| 480 | CheckEnterLeaveEvents(thisEventWindow, mousePosInClient); |
||
| 481 | |||
| 482 | switch (evt.MouseEventKind) |
||
| 483 | { |
||
| 484 | case MouseEventKind.MouseDown: |
||
| 485 | button = API.GetEventMouseButton(inEvent); |
||
| 486 | |||
| 487 | switch (button) |
||
| 488 | { |
||
| 489 | case MouseButton.Primary: |
||
| 490 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = true; |
||
| 491 | break; |
||
| 492 | |||
| 493 | case MouseButton.Secondary: |
||
| 494 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = true; |
||
| 495 | break; |
||
| 496 | |||
| 497 | case MouseButton.Tertiary: |
||
| 498 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = true; |
||
| 499 | break; |
||
| 500 | } |
||
| 501 | |||
| 502 | |||
| 503 | return OSStatus.NoError; |
||
| 504 | |||
| 505 | case MouseEventKind.MouseUp: |
||
| 506 | button = API.GetEventMouseButton(inEvent); |
||
| 507 | |||
| 508 | switch (button) |
||
| 509 | { |
||
| 510 | case MouseButton.Primary: |
||
| 511 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = false; |
||
| 512 | break; |
||
| 513 | |||
| 514 | case MouseButton.Secondary: |
||
| 515 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = false; |
||
| 516 | break; |
||
| 517 | |||
| 518 | case MouseButton.Tertiary: |
||
| 519 | InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = false; |
||
| 520 | break; |
||
| 521 | } |
||
| 522 | |||
| 523 | button = API.GetEventMouseButton(inEvent); |
||
| 524 | |||
| 525 | return OSStatus.NoError; |
||
| 526 | |||
| 527 | case MouseEventKind.WheelMoved: |
||
| 528 | |||
| 529 | int delta = API.GetEventMouseWheelDelta(inEvent) / 3; |
||
| 530 | |||
| 531 | InputDriver.Mouse[0].Wheel += delta; |
||
| 532 | |||
| 533 | return OSStatus.NoError; |
||
| 534 | |||
| 535 | case MouseEventKind.MouseMoved: |
||
| 536 | case MouseEventKind.MouseDragged: |
||
| 537 | |||
| 538 | //Debug.Print("Mouse Location: {0}, {1}", pt.X, pt.Y); |
||
| 539 | |||
| 540 | if (this.windowState == WindowState.Fullscreen) |
||
| 541 | { |
||
| 542 | if (mousePosInClient.X != InputDriver.Mouse[0].X || |
||
| 543 | mousePosInClient.Y != InputDriver.Mouse[0].Y) |
||
| 544 | { |
||
| 545 | InputDriver.Mouse[0].Position = mousePosInClient; |
||
| 546 | } |
||
| 547 | } |
||
| 548 | else |
||
| 549 | { |
||
| 550 | // ignore clicks in the title bar |
||
| 551 | if (pt.Y < 0) |
||
| 552 | return OSStatus.EventNotHandled; |
||
| 553 | |||
| 554 | if (mousePosInClient.X != InputDriver.Mouse[0].X || |
||
| 555 | mousePosInClient.Y != InputDriver.Mouse[0].Y) |
||
| 556 | { |
||
| 557 | InputDriver.Mouse[0].Position = mousePosInClient; |
||
| 558 | } |
||
| 559 | } |
||
| 560 | |||
| 561 | return OSStatus.EventNotHandled; |
||
| 562 | |||
| 563 | default: |
||
| 564 | Debug.Print("{0}", evt); |
||
| 565 | |||
| 566 | return OSStatus.EventNotHandled; |
||
| 567 | } |
||
| 568 | } |
||
| 569 | |||
| 570 | private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt) |
||
| 571 | { |
||
| 572 | if (window == null) |
||
| 573 | return; |
||
| 574 | |||
| 575 | bool thisIn = eventWindowRef == window.WindowRef; |
||
| 576 | |||
| 577 | if (pt.Y < 0) |
||
| 578 | thisIn = false; |
||
| 579 | |||
| 580 | if (thisIn != mMouseIn) |
||
| 581 | { |
||
| 582 | mMouseIn = thisIn; |
||
| 583 | |||
| 584 | if (mMouseIn) |
||
| 585 | OnMouseEnter(); |
||
| 586 | else |
||
| 587 | OnMouseLeave(); |
||
| 588 | } |
||
| 589 | } |
||
| 590 | |||
| 591 | private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) |
||
| 592 | { |
||
| 593 | code = API.GetEventKeyboardKeyCode(inEvent); |
||
| 594 | charCode = API.GetEventKeyboardChar(inEvent); |
||
| 595 | } |
||
| 596 | private void ProcessModifierKey(IntPtr inEvent) |
||
| 597 | { |
||
| 598 | MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent); |
||
| 599 | |||
| 600 | bool caps = (modifiers & MacOSKeyModifiers.CapsLock) != 0 ? true : false; |
||
| 601 | bool control = (modifiers & MacOSKeyModifiers.Control) != 0 ? true : false; |
||
| 602 | bool command = (modifiers & MacOSKeyModifiers.Command) != 0 ? true : false; |
||
| 603 | bool option = (modifiers & MacOSKeyModifiers.Option) != 0 ? true : false; |
||
| 604 | bool shift = (modifiers & MacOSKeyModifiers.Shift) != 0 ? true : false; |
||
| 605 | |||
| 606 | Debug.Print("Modifiers Changed: {0}", modifiers); |
||
| 607 | |||
| 608 | Input.KeyboardDevice keyboard = InputDriver.Keyboard[0]; |
||
| 609 | |||
| 610 | if (keyboard[OpenTK.Input.Key.AltLeft] ^ option) |
||
| 611 | keyboard[OpenTK.Input.Key.AltLeft] = option; |
||
| 612 | |||
| 613 | if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift) |
||
| 614 | keyboard[OpenTK.Input.Key.ShiftLeft] = shift; |
||
| 615 | |||
| 616 | if (keyboard[OpenTK.Input.Key.WinLeft] ^ command) |
||
| 617 | keyboard[OpenTK.Input.Key.WinLeft] = command; |
||
| 618 | |||
| 619 | if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control) |
||
| 620 | keyboard[OpenTK.Input.Key.ControlLeft] = control; |
||
| 621 | |||
| 622 | if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps) |
||
| 623 | keyboard[OpenTK.Input.Key.CapsLock] = caps; |
||
| 624 | |||
| 625 | } |
||
| 626 | |||
| 627 | Rect GetRegion() |
||
| 628 | { |
||
| 629 | Rect retval = API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); |
||
| 630 | |||
| 631 | return retval; |
||
| 632 | } |
||
| 633 | |||
| 634 | void SetLocation(short x, short y) |
||
| 635 | { |
||
| 636 | if (windowState == WindowState.Fullscreen) |
||
| 637 | return; |
||
| 638 | |||
| 639 | API.MoveWindow(window.WindowRef, x, y, false); |
||
| 640 | } |
||
| 641 | |||
| 642 | void SetSize(short width, short height) |
||
| 643 | { |
||
| 644 | if (WindowState == WindowState.Fullscreen) |
||
| 645 | return; |
||
| 646 | |||
| 647 | // The bounds of the window should be the size specified, but |
||
| 648 | // API.SizeWindow sets the content region size. So |
||
| 649 | // we reduce the size to get the correct bounds. |
||
| 650 | width -= (short)(bounds.Width - clientRectangle.Width); |
||
| 651 | height -= (short)(bounds.Height - clientRectangle.Height); |
||
| 652 | |||
| 653 | API.SizeWindow(window.WindowRef, width, height, true); |
||
| 654 | } |
||
| 655 | |||
| 656 | void SetClientSize(short width, short height) |
||
| 657 | { |
||
| 658 | if (WindowState == WindowState.Fullscreen) |
||
| 659 | return; |
||
| 660 | |||
| 661 | API.SizeWindow(window.WindowRef, width, height, true); |
||
| 662 | } |
||
| 663 | |||
| 664 | protected void OnResize() |
||
| 665 | { |
||
| 666 | LoadSize(); |
||
| 667 | |||
| 668 | if (Resize != null) |
||
| 669 | { |
||
| 670 | Resize(this, EventArgs.Empty); |
||
| 671 | } |
||
| 672 | } |
||
| 673 | |||
| 674 | private void LoadSize() |
||
| 675 | { |
||
| 676 | if (WindowState == WindowState.Fullscreen) |
||
| 677 | return; |
||
| 678 | |||
| 679 | Rect r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.StructureRegion); |
||
| 680 | bounds = new Rectangle(r.X, r.Y, r.Width, r.Height); |
||
| 681 | |||
| 682 | r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.GlobalPortRegion); |
||
| 683 | clientRectangle = new Rectangle(0, 0, r.Width, r.Height); |
||
| 684 | } |
||
| 685 | |||
| 686 | #endregion |
||
| 687 | |||
| 688 | #region INativeWindow Members |
||
| 689 | |||
| 690 | public void ProcessEvents() |
||
| 691 | { |
||
| 692 | Application.ProcessEvents(); |
||
| 693 | } |
||
| 694 | |||
| 695 | public Point PointToClient(Point point) |
||
| 696 | { |
||
| 697 | IntPtr handle = window.WindowRef; |
||
| 698 | |||
| 699 | Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); |
||
| 700 | Debug.Print("Rect: {0}", r); |
||
| 701 | |||
| 702 | return new Point(point.X - r.X, point.Y - r.Y); |
||
| 703 | } |
||
| 704 | public Point PointToScreen(Point point) |
||
| 705 | { |
||
| 706 | IntPtr handle = window.WindowRef; |
||
| 707 | |||
| 708 | Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); |
||
| 709 | Debug.Print("Rect: {0}", r); |
||
| 710 | |||
| 711 | return new Point(point.X + r.X, point.Y + r.Y); |
||
| 712 | } |
||
| 713 | |||
| 714 | public bool Exists |
||
| 715 | { |
||
| 716 | get { return mExists; } |
||
| 717 | } |
||
| 718 | |||
| 719 | public IWindowInfo WindowInfo |
||
| 720 | { |
||
| 721 | get { return window; } |
||
| 722 | } |
||
| 723 | |||
| 724 | public bool IsIdle |
||
| 725 | { |
||
| 726 | get { return true; } |
||
| 727 | } |
||
| 728 | |||
| 729 | public OpenTK.Input.IInputDriver InputDriver |
||
| 730 | { |
||
| 731 | get |
||
| 732 | { |
||
| 733 | return mInputDriver; |
||
| 734 | } |
||
| 735 | } |
||
| 736 | |||
| 737 | |||
| 738 | public Icon Icon |
||
| 739 | { |
||
| 740 | get { return mIcon; } |
||
| 741 | set { |
||
| 742 | SetIcon(value); |
||
| 743 | } |
||
| 744 | } |
||
| 745 | |||
| 746 | private void SetIcon(Icon icon) |
||
| 747 | { |
||
| 748 | // The code for this function was adapted from Mono's |
||
| 749 | // XplatUICarbon implementation, written by Geoff Norton |
||
| 750 | // http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs?view=markup&pathrev=136932 |
||
| 751 | if (icon == null) |
||
| 752 | { |
||
| 753 | API.RestoreApplicationDockTileImage(); |
||
| 754 | } |
||
| 755 | else |
||
| 756 | { |
||
| 757 | Bitmap bitmap; |
||
| 758 | int size; |
||
| 759 | IntPtr[] data; |
||
| 760 | int index; |
||
| 761 | |||
| 762 | bitmap = new Bitmap(128, 128); |
||
| 763 | using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap)) |
||
| 764 | { |
||
| 765 | g.DrawImage(icon.ToBitmap(), 0, 0, 128, 128); |
||
| 766 | } |
||
| 767 | index = 0; |
||
| 768 | size = bitmap.Width * bitmap.Height; |
||
| 769 | data = new IntPtr[size]; |
||
| 770 | |||
| 771 | for (int y = 0; y < bitmap.Height; y++) |
||
| 772 | { |
||
| 773 | for (int x = 0; x < bitmap.Width; x++) |
||
| 774 | { |
||
| 775 | int pixel = bitmap.GetPixel(x, y).ToArgb(); |
||
| 776 | if (BitConverter.IsLittleEndian) |
||
| 777 | { |
||
| 778 | byte a = (byte)((pixel >> 24) & 0xFF); |
||
| 779 | byte r = (byte)((pixel >> 16) & 0xFF); |
||
| 780 | byte g = (byte)((pixel >> 8) & 0xFF); |
||
| 781 | byte b = (byte)(pixel & 0xFF); |
||
| 782 | data[index++] = (IntPtr)(a + (r << 8) + (g << 16) + (b << 24)); |
||
| 783 | } |
||
| 784 | else |
||
| 785 | { |
||
| 786 | data[index++] = (IntPtr)pixel; |
||
| 787 | } |
||
| 788 | } |
||
| 789 | } |
||
| 790 | |||
| 791 | IntPtr provider = API.CGDataProviderCreateWithData(IntPtr.Zero, data, size * 4, IntPtr.Zero); |
||
| 792 | IntPtr image = API.CGImageCreate(128, 128, 8, 32, 4 * 128, API.CGColorSpaceCreateDeviceRGB(), 4, provider, IntPtr.Zero, 0, 0); |
||
| 793 | API.SetApplicationDockTileImage(image); |
||
| 794 | } |
||
| 795 | } |
||
| 796 | |||
| 797 | public string Title |
||
| 798 | { |
||
| 799 | get |
||
| 800 | { |
||
| 801 | return title; |
||
| 802 | } |
||
| 803 | set |
||
| 804 | { |
||
| 805 | API.SetWindowTitle(window.WindowRef, value); |
||
| 806 | title = value; |
||
| 807 | } |
||
| 808 | } |
||
| 809 | |||
| 810 | public bool Visible |
||
| 811 | { |
||
| 812 | get { return API.IsWindowVisible(window.WindowRef); } |
||
| 813 | set |
||
| 814 | { |
||
| 815 | if (value && Visible == false) |
||
| 816 | Show(); |
||
| 817 | else |
||
| 818 | Hide(); |
||
| 819 | } |
||
| 820 | } |
||
| 821 | |||
| 822 | public bool Focused |
||
| 823 | { |
||
| 824 | get { return this.mIsActive; } |
||
| 825 | } |
||
| 826 | |||
| 827 | public Rectangle Bounds |
||
| 828 | { |
||
| 829 | get |
||
| 830 | { |
||
| 831 | |||
| 832 | return bounds; |
||
| 833 | } |
||
| 834 | set |
||
| 835 | { |
||
| 836 | Location = value.Location; |
||
| 837 | Size = value.Size; |
||
| 838 | } |
||
| 839 | } |
||
| 840 | |||
| 841 | public Point Location |
||
| 842 | { |
||
| 843 | get |
||
| 844 | { |
||
| 845 | return Bounds.Location; |
||
| 846 | } |
||
| 847 | set |
||
| 848 | { |
||
| 849 | SetLocation((short)value.X, (short)value.Y); |
||
| 850 | } |
||
| 851 | } |
||
| 852 | |||
| 853 | public Size Size |
||
| 854 | { |
||
| 855 | get |
||
| 856 | { |
||
| 857 | return bounds.Size; |
||
| 858 | } |
||
| 859 | set |
||
| 860 | { |
||
| 861 | SetSize((short)value.Width, (short)value.Height); |
||
| 862 | } |
||
| 863 | } |
||
| 864 | |||
| 865 | public int Width |
||
| 866 | { |
||
| 867 | get { return ClientRectangle.Width; } |
||
| 868 | set { SetClientSize((short)value, (short)Height); } |
||
| 869 | } |
||
| 870 | |||
| 871 | public int Height |
||
| 872 | { |
||
| 873 | get { return ClientRectangle.Height; } |
||
| 874 | set { SetClientSize((short)Width, (short)value); } |
||
| 875 | } |
||
| 876 | |||
| 877 | public int X |
||
| 878 | { |
||
| 879 | get |
||
| 880 | { |
||
| 881 | return ClientRectangle.X; |
||
| 882 | } |
||
| 883 | set |
||
| 884 | { |
||
| 885 | Location = new Point(value, Y); |
||
| 886 | } |
||
| 887 | } |
||
| 888 | |||
| 889 | public int Y |
||
| 890 | { |
||
| 891 | get |
||
| 892 | { |
||
| 893 | return ClientRectangle.Y; |
||
| 894 | } |
||
| 895 | set |
||
| 896 | { |
||
| 897 | Location = new Point(X, value); |
||
| 898 | } |
||
| 899 | } |
||
| 900 | |||
| 901 | public Rectangle ClientRectangle |
||
| 902 | { |
||
| 903 | get |
||
| 904 | { |
||
| 905 | return clientRectangle; |
||
| 906 | } |
||
| 907 | set |
||
| 908 | { |
||
| 909 | // just set the size, and ignore the location value. |
||
| 910 | // this is the behavior of the Windows WinGLNative. |
||
| 911 | ClientSize = value.Size; |
||
| 912 | } |
||
| 913 | } |
||
| 914 | |||
| 915 | public Size ClientSize |
||
| 916 | { |
||
| 917 | get |
||
| 918 | { |
||
| 919 | return clientRectangle.Size; |
||
| 920 | } |
||
| 921 | set |
||
| 922 | { |
||
| 923 | API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true); |
||
| 924 | OnResize(); |
||
| 925 | } |
||
| 926 | } |
||
| 927 | |||
| 928 | public void Close() |
||
| 929 | { |
||
| 930 | CancelEventArgs e = new CancelEventArgs(); |
||
| 931 | OnClosing(e); |
||
| 932 | |||
| 933 | if (e.Cancel) |
||
| 934 | return; |
||
| 935 | |||
| 936 | OnClosed(); |
||
| 937 | |||
| 938 | Dispose(); |
||
| 939 | } |
||
| 940 | |||
| 941 | public WindowState WindowState |
||
| 942 | { |
||
| 943 | get |
||
| 944 | { |
||
| 945 | if (windowState == WindowState.Fullscreen) |
||
| 946 | return WindowState.Fullscreen; |
||
| 947 | |||
| 948 | if (Carbon.API.IsWindowCollapsed(window.WindowRef)) |
||
| 949 | return WindowState.Minimized; |
||
| 950 | |||
| 951 | if (Carbon.API.IsWindowInStandardState(window.WindowRef)) |
||
| 952 | { |
||
| 953 | return WindowState.Maximized; |
||
| 954 | } |
||
| 955 | |||
| 956 | return WindowState.Normal; |
||
| 957 | } |
||
| 958 | set |
||
| 959 | { |
||
| 960 | if (value == WindowState) |
||
| 961 | return; |
||
| 962 | |||
| 963 | Debug.Print("Switching window state from {0} to {1}", WindowState, value); |
||
| 964 | WindowState oldState = WindowState; |
||
| 965 | |||
| 966 | windowState = value; |
||
| 967 | |||
| 968 | if (oldState == WindowState.Fullscreen) |
||
| 969 | { |
||
| 970 | window.GoWindowedHack = true; |
||
| 971 | |||
| 972 | // when returning from full screen, wait until the context is updated |
||
| 973 | // to actually do the work. |
||
| 974 | return; |
||
| 975 | } |
||
| 976 | |||
| 977 | if (oldState == WindowState.Minimized) |
||
| 978 | { |
||
| 979 | API.CollapseWindow(window.WindowRef, false); |
||
| 980 | } |
||
| 981 | |||
| 982 | SetCarbonWindowState(); |
||
| 983 | } |
||
| 984 | } |
||
| 985 | |||
| 986 | private void SetCarbonWindowState() |
||
| 987 | { |
||
| 988 | CarbonPoint idealSize; |
||
| 989 | |||
| 990 | switch (windowState) |
||
| 991 | { |
||
| 992 | case WindowState.Fullscreen: |
||
| 993 | window.GoFullScreenHack = true; |
||
| 994 | |||
| 995 | break; |
||
| 996 | |||
| 997 | case WindowState.Maximized: |
||
| 998 | // hack because mac os has no concept of maximized. Instead windows are "zoomed" |
||
| 999 | // meaning they are maximized up to their reported ideal size. So we report a |
||
| 1000 | // large ideal size. |
||
| 1001 | idealSize = new CarbonPoint(9000, 9000); |
||
| 1002 | API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomOut, ref idealSize); |
||
| 1003 | break; |
||
| 1004 | |||
| 1005 | case WindowState.Normal: |
||
| 1006 | if (WindowState == WindowState.Maximized) |
||
| 1007 | { |
||
| 1008 | idealSize = new CarbonPoint(); |
||
| 1009 | API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize); |
||
| 1010 | } |
||
| 1011 | break; |
||
| 1012 | |||
| 1013 | case WindowState.Minimized: |
||
| 1014 | API.CollapseWindow(window.WindowRef, true); |
||
| 1015 | |||
| 1016 | break; |
||
| 1017 | } |
||
| 1018 | |||
| 1019 | |||
| 1020 | OnWindowStateChanged(); |
||
| 1021 | |||
| 1022 | OnResize(); |
||
| 1023 | } |
||
| 1024 | |||
| 1025 | public WindowBorder WindowBorder |
||
| 1026 | { |
||
| 1027 | get |
||
| 1028 | { |
||
| 1029 | return windowBorder; |
||
| 1030 | } |
||
| 1031 | set |
||
| 1032 | { |
||
| 1033 | if (windowBorder == value) |
||
| 1034 | return; |
||
| 1035 | |||
| 1036 | windowBorder = value; |
||
| 1037 | |||
| 1038 | if (windowBorder == WindowBorder.Resizable) |
||
| 1039 | { |
||
| 1040 | API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom, |
||
| 1041 | WindowAttributes.NoAttributes); |
||
| 1042 | } |
||
| 1043 | else if (windowBorder == WindowBorder.Fixed) |
||
| 1044 | { |
||
| 1045 | API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes, |
||
| 1046 | WindowAttributes.Resizable | WindowAttributes.FullZoom); |
||
| 1047 | } |
||
| 1048 | |||
| 1049 | if (WindowBorderChanged != null) |
||
| 1050 | WindowBorderChanged(this, EventArgs.Empty); |
||
| 1051 | } |
||
| 1052 | } |
||
| 1053 | |||
| 1054 | #region --- Event wrappers --- |
||
| 1055 | |||
| 1056 | private void OnKeyPress(KeyPressEventArgs keyPressArgs) |
||
| 1057 | { |
||
| 1058 | if (KeyPress != null) |
||
| 1059 | KeyPress(this, keyPressArgs); |
||
| 1060 | } |
||
| 1061 | |||
| 1062 | |||
| 1063 | private void OnWindowStateChanged() |
||
| 1064 | { |
||
| 1065 | if (WindowStateChanged != null) |
||
| 1066 | WindowStateChanged(this, EventArgs.Empty); |
||
| 1067 | } |
||
| 1068 | |||
| 1069 | protected virtual void OnClosing(CancelEventArgs e) |
||
| 1070 | { |
||
| 1071 | if (Closing != null) |
||
| 1072 | Closing(this, e); |
||
| 1073 | } |
||
| 1074 | |||
| 1075 | protected virtual void OnClosed() |
||
| 1076 | { |
||
| 1077 | if (Closed != null) |
||
| 1078 | Closed(this, EventArgs.Empty); |
||
| 1079 | } |
||
| 1080 | |||
| 1081 | |||
| 1082 | private void OnMouseLeave() |
||
| 1083 | { |
||
| 1084 | if (MouseLeave != null) |
||
| 1085 | MouseLeave(this, EventArgs.Empty); |
||
| 1086 | } |
||
| 1087 | |||
| 1088 | private void OnMouseEnter() |
||
| 1089 | { |
||
| 1090 | if (MouseEnter != null) |
||
| 1091 | MouseEnter(this, EventArgs.Empty); |
||
| 1092 | } |
||
| 1093 | |||
| 1094 | private void OnActivate() |
||
| 1095 | { |
||
| 1096 | mIsActive = true; |
||
| 1097 | if (FocusedChanged != null) |
||
| 1098 | FocusedChanged(this, EventArgs.Empty); |
||
| 1099 | } |
||
| 1100 | private void OnDeactivate() |
||
| 1101 | { |
||
| 1102 | mIsActive = false; |
||
| 1103 | if (FocusedChanged != null) |
||
| 1104 | FocusedChanged(this, EventArgs.Empty); |
||
| 1105 | } |
||
| 1106 | |||
| 1107 | #endregion |
||
| 1108 | |||
| 1109 | public event EventHandler<EventArgs> Idle; |
||
| 1110 | public event EventHandler<EventArgs> Load; |
||
| 1111 | public event EventHandler<EventArgs> Unload; |
||
| 1112 | public event EventHandler<EventArgs> Move; |
||
| 1113 | public event EventHandler<EventArgs> Resize; |
||
| 1114 | public event EventHandler<CancelEventArgs> Closing; |
||
| 1115 | public event EventHandler<EventArgs> Closed; |
||
| 1116 | public event EventHandler<EventArgs> Disposed; |
||
| 1117 | public event EventHandler<EventArgs> IconChanged; |
||
| 1118 | public event EventHandler<EventArgs> TitleChanged; |
||
| 1119 | public event EventHandler<EventArgs> ClientSizeChanged; |
||
| 1120 | public event EventHandler<EventArgs> VisibleChanged; |
||
| 1121 | public event EventHandler<EventArgs> WindowInfoChanged; |
||
| 1122 | public event EventHandler<EventArgs> FocusedChanged; |
||
| 1123 | public event EventHandler<EventArgs> WindowBorderChanged; |
||
| 1124 | public event EventHandler<EventArgs> WindowStateChanged; |
||
| 1125 | public event EventHandler<KeyPressEventArgs> KeyPress; |
||
| 1126 | public event EventHandler<EventArgs> MouseEnter; |
||
| 1127 | public event EventHandler<EventArgs> MouseLeave; |
||
| 1128 | |||
| 1129 | #endregion |
||
| 1130 | } |
||
| 1131 | } |