]> git.saurik.com Git - wxWidgets.git/blob - src/univ/topluniv.cpp
New positioning code, eliminating a lot of extra, unnecessary methods
[wxWidgets.git] / src / univ / topluniv.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: topluniv.cpp
3 // Author: Vaclav Slavik
4 // Id: $Id$
5 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // ============================================================================
10 // declarations
11 // ============================================================================
12
13 // ----------------------------------------------------------------------------
14 // headers
15 // ----------------------------------------------------------------------------
16
17 #ifdef __GNUG__
18 #pragma implementation "univtoplevel.h"
19 #endif
20
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #include "wx/defs.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/dcclient.h"
32 #include "wx/settings.h"
33 #endif
34
35 #include "wx/toplevel.h"
36 #include "wx/univ/renderer.h"
37 #include "wx/bitmap.h"
38 #include "wx/image.h"
39 #include "wx/cshelp.h"
40 #include "wx/evtloop.h"
41
42
43 // ----------------------------------------------------------------------------
44 // event tables
45 // ----------------------------------------------------------------------------
46
47 BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative)
48 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow)
49 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint)
50 END_EVENT_TABLE()
51
52 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow)
53
54 // ============================================================================
55 // implementation
56 // ============================================================================
57
58 int wxTopLevelWindow::ms_drawDecorations = -1;
59 int wxTopLevelWindow::ms_canIconize = -1;
60
61 void wxTopLevelWindow::Init()
62 {
63 m_isActive = FALSE;
64 m_windowStyle = 0;
65 m_pressedButton = 0;
66 }
67
68 bool wxTopLevelWindow::Create(wxWindow *parent,
69 wxWindowID id,
70 const wxString& title,
71 const wxPoint& pos,
72 const wxSize& size,
73 long style,
74 const wxString &name)
75 {
76 // init them to avoid compiler warnings
77 long styleOrig = 0,
78 exstyleOrig = 0;
79
80 if ( ms_drawDecorations == -1 )
81 {
82 ms_drawDecorations =
83 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS)
84 || wxGetEnv(wxT("WXDECOR"), NULL);
85 // FIXME -- wxUniv should provide a way to force non-native decorations!
86 // $WXDECOR is just a hack in absence of better wxUniv solution
87 }
88
89 if ( ms_canIconize == -1 )
90 {
91 ms_canIconize = wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME);
92 }
93
94 if ( ms_drawDecorations )
95 {
96 CreateInputHandler(wxINP_HANDLER_TOPLEVEL);
97
98 styleOrig = style;
99 exstyleOrig = GetExtraStyle();
100 style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
101 wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW |
102 wxTHICK_FRAME);
103 style = wxSIMPLE_BORDER;
104 SetExtraStyle(exstyleOrig &
105 ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP));
106 }
107
108 if ( !wxTopLevelWindowNative::Create(parent, id, title, pos,
109 size, style, name) )
110 return FALSE;
111
112 if ( ms_drawDecorations )
113 {
114 m_windowStyle = styleOrig;
115 m_exStyle = exstyleOrig;
116 }
117
118 return TRUE;
119 }
120
121 bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
122 {
123 if ( show == IsFullScreen() ) return FALSE;
124
125 if ( ms_drawDecorations )
126 {
127 if ( show )
128 {
129 m_fsSavedStyle = m_windowStyle;
130 if ( style & wxFULLSCREEN_NOBORDER )
131 m_windowStyle |= wxSIMPLE_BORDER;
132 if ( style & wxFULLSCREEN_NOCAPTION )
133 m_windowStyle &= ~wxCAPTION;
134 }
135 else
136 {
137 m_windowStyle = m_fsSavedStyle;
138 }
139 }
140
141 return wxTopLevelWindowNative::ShowFullScreen(show, style);
142 }
143
144 long wxTopLevelWindow::GetDecorationsStyle() const
145 {
146 long style = 0;
147
148 if ( m_windowStyle & wxCAPTION )
149 {
150 style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_BUTTON_CLOSE;
151 if ( (m_windowStyle & wxMINIMIZE_BOX) && ms_canIconize )
152 style |= wxTOPLEVEL_BUTTON_ICONIZE;
153 if ( m_windowStyle & wxMAXIMIZE_BOX )
154 {
155 if ( IsMaximized() )
156 style |= wxTOPLEVEL_BUTTON_RESTORE;
157 else
158 style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
159 }
160 #if wxUSE_HELP
161 if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
162 style |= wxTOPLEVEL_BUTTON_HELP;
163 #endif
164 }
165 if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 )
166 style |= wxTOPLEVEL_BORDER;
167 if ( m_windowStyle & (wxRESIZE_BORDER | wxTHICK_FRAME) )
168 style |= wxTOPLEVEL_RESIZEABLE;
169
170 if ( IsMaximized() )
171 style |= wxTOPLEVEL_MAXIMIZED;
172 if ( GetIcon().Ok() )
173 style |= wxTOPLEVEL_ICON;
174 if ( m_isActive )
175 style |= wxTOPLEVEL_ACTIVE;
176
177 return style;
178 }
179
180 void wxTopLevelWindow::RefreshTitleBar()
181 {
182 wxNcPaintEvent event(GetId());
183 event.SetEventObject(this);
184 GetEventHandler()->ProcessEvent(event);
185 }
186
187 // ----------------------------------------------------------------------------
188 // client area handling
189 // ----------------------------------------------------------------------------
190
191 wxPoint wxTopLevelWindow::GetClientAreaOrigin() const
192 {
193 if ( ms_drawDecorations )
194 {
195 int w, h;
196 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
197 wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
198 wxSize(w, h));
199 rect = m_renderer->GetFrameClientArea(rect,
200 GetDecorationsStyle());
201 return rect.GetPosition();
202 }
203 else
204 {
205 return wxTopLevelWindowNative::GetClientAreaOrigin();
206 }
207 }
208
209 void wxTopLevelWindow::DoGetClientSize(int *width, int *height) const
210 {
211 if ( ms_drawDecorations )
212 {
213 int w, h;
214 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
215 wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
216 wxSize(w, h));
217 rect = m_renderer->GetFrameClientArea(rect,
218 GetDecorationsStyle());
219 if ( width )
220 *width = rect.width;
221 if ( height )
222 *height = rect.height;
223 }
224 else
225 wxTopLevelWindowNative::DoGetClientSize(width, height);
226 }
227
228 void wxTopLevelWindow::DoSetClientSize(int width, int height)
229 {
230 if ( ms_drawDecorations )
231 {
232 wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height),
233 GetDecorationsStyle());
234 wxTopLevelWindowNative::DoSetClientSize(size.x, size.y);
235 }
236 else
237 wxTopLevelWindowNative::DoSetClientSize(width, height);
238 }
239
240 void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
241 {
242 if ( !ms_drawDecorations || !m_renderer )
243 event.Skip();
244 else
245 {
246 // get the window rect
247 wxRect rect;
248 wxSize size = GetSize();
249 rect.x =
250 rect.y = 0;
251 rect.width = size.x;
252 rect.height = size.y;
253
254 wxWindowDC dc(this);
255 m_renderer->DrawFrameTitleBar(dc, rect,
256 GetTitle(), m_titlebarIcon,
257 GetDecorationsStyle(),
258 m_pressedButton,
259 wxCONTROL_PRESSED);
260 }
261 }
262
263 long wxTopLevelWindow::HitTest(const wxPoint& pt) const
264 {
265 int w, h;
266 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
267 wxRect rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w, h));
268
269 return m_renderer->HitTestFrame(rect, pt+GetClientAreaOrigin(), GetDecorationsStyle());
270 }
271
272 // ----------------------------------------------------------------------------
273 // icons
274 // ----------------------------------------------------------------------------
275
276 void wxTopLevelWindow::SetIcon(const wxIcon& icon)
277 {
278 wxTopLevelWindowNative::SetIcon(icon);
279
280 if ( ms_drawDecorations && m_renderer )
281 {
282 wxSize size = m_renderer->GetFrameIconSize();
283
284 if ( !icon.Ok() || size.x == -1 )
285 m_titlebarIcon = icon;
286 else
287 {
288 wxBitmap bmp1;
289 bmp1.CopyFromIcon(icon);
290 if ( !bmp1.Ok() )
291 m_titlebarIcon = wxNullIcon;
292 else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
293 m_titlebarIcon = icon;
294 else
295 {
296 wxImage img = bmp1.ConvertToImage();
297 img.Rescale(size.x, size.y);
298 m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
299 }
300 }
301 }
302 }
303
304 // ----------------------------------------------------------------------------
305 // interactive manipulation
306 // ----------------------------------------------------------------------------
307
308 #define wxINTERACTIVE_RESIZE_DIR \
309 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
310 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
311
312 struct wxInteractiveMoveData
313 {
314 wxTopLevelWindowBase *m_window;
315 wxEventLoop *m_evtLoop;
316 int m_flags;
317 wxRect m_rect;
318 wxRect m_rectOrig;
319 wxPoint m_pos;
320 wxSize m_minSize, m_maxSize;
321 };
322
323 class wxInteractiveMoveHandler : public wxEvtHandler
324 {
325 public:
326 wxInteractiveMoveHandler(wxInteractiveMoveData& data) : m_data(data) {}
327
328 private:
329 DECLARE_EVENT_TABLE()
330 void OnMouseMove(wxMouseEvent& event);
331 void OnMouseDown(wxMouseEvent& event);
332 void OnMouseUp(wxMouseEvent& event);
333 void OnKeyDown(wxKeyEvent& event);
334
335 wxInteractiveMoveData& m_data;
336 };
337
338 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler, wxEvtHandler)
339 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove)
340 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown)
341 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp)
342 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown)
343 END_EVENT_TABLE()
344
345
346 static inline LINKAGEMODE
347 void wxApplyResize(wxInteractiveMoveData& data, const wxPoint& diff)
348 {
349 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
350 {
351 data.m_rect.x += diff.x;
352 data.m_rect.width -= diff.x;
353 }
354 else if ( data.m_flags & wxINTERACTIVE_RESIZE_E )
355 {
356 data.m_rect.width += diff.x;
357 }
358 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
359 {
360 data.m_rect.y += diff.y;
361 data.m_rect.height -= diff.y;
362 }
363 else if ( data.m_flags & wxINTERACTIVE_RESIZE_S )
364 {
365 data.m_rect.height += diff.y;
366 }
367
368 if ( data.m_minSize.x != -1 && data.m_rect.width < data.m_minSize.x )
369 {
370 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
371 data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
372 data.m_rect.width = data.m_minSize.x;
373 }
374 if ( data.m_maxSize.x != -1 && data.m_rect.width > data.m_maxSize.x )
375 {
376 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
377 data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
378 data.m_rect.width = data.m_maxSize.x;
379 }
380 if ( data.m_minSize.y != -1 && data.m_rect.height < data.m_minSize.y )
381 {
382 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
383 data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
384 data.m_rect.height = data.m_minSize.y;
385 }
386 if ( data.m_maxSize.y != -1 && data.m_rect.height > data.m_maxSize.y )
387 {
388 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
389 data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
390 data.m_rect.height = data.m_maxSize.y;
391 }
392 }
393
394 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent& event)
395 {
396 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
397 event.Skip();
398
399 else if ( m_data.m_flags & wxINTERACTIVE_MOVE )
400 {
401 wxPoint diff = wxGetMousePosition() - m_data.m_pos;
402 m_data.m_rect = m_data.m_rectOrig;
403 m_data.m_rect.Offset(diff);
404 m_data.m_window->Move(m_data.m_rect.GetPosition());
405 }
406
407 else if ( m_data.m_flags & wxINTERACTIVE_RESIZE )
408 {
409 wxPoint diff = wxGetMousePosition() - m_data.m_pos;
410 m_data.m_rect = m_data.m_rectOrig;
411 wxApplyResize(m_data, diff);
412 m_data.m_window->SetSize(m_data.m_rect);
413 }
414 }
415
416 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent& event)
417 {
418 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
419 {
420 m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
421 m_data.m_pos = wxGetMousePosition();
422 }
423 }
424
425 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent& event)
426 {
427 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
428 {
429 m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
430 m_data.m_pos = wxGetMousePosition();
431 }
432
433 wxPoint diff(-1,-1);
434
435 switch ( event.GetKeyCode() )
436 {
437 case WXK_UP: diff = wxPoint(0, -16); break;
438 case WXK_DOWN: diff = wxPoint(0, 16); break;
439 case WXK_LEFT: diff = wxPoint(-16, 0); break;
440 case WXK_RIGHT: diff = wxPoint(16, 0); break;
441 case WXK_ESCAPE:
442 m_data.m_window->SetSize(m_data.m_rectOrig);
443 m_data.m_evtLoop->Exit();
444 return;
445 case WXK_RETURN:
446 m_data.m_evtLoop->Exit();
447 return;
448 }
449
450 if ( diff.x != -1 )
451 {
452 if ( m_data.m_flags & wxINTERACTIVE_MOVE )
453 {
454 m_data.m_rect.Offset(diff);
455 m_data.m_window->Move(m_data.m_rect.GetPosition());
456 }
457 else /* wxINTERACTIVE_RESIZE */
458 {
459 if ( !(m_data.m_flags & wxINTERACTIVE_RESIZE_DIR) )
460 {
461 if ( diff.y < 0 )
462 m_data.m_flags |= wxINTERACTIVE_RESIZE_N;
463 else if ( diff.y > 0 )
464 m_data.m_flags |= wxINTERACTIVE_RESIZE_S;
465 if ( diff.x < 0 )
466 m_data.m_flags |= wxINTERACTIVE_RESIZE_W;
467 else if ( diff.x > 0 )
468 m_data.m_flags |= wxINTERACTIVE_RESIZE_E;
469 }
470
471 wxApplyResize(m_data, diff);
472 m_data.m_window->SetSize(m_data.m_rect);
473 }
474 }
475 }
476
477 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent& event)
478 {
479 m_data.m_evtLoop->Exit();
480 }
481
482
483 void wxTopLevelWindow::InteractiveMove(int flags)
484 {
485 wxASSERT_MSG( !((flags & wxINTERACTIVE_MOVE) && (flags & wxINTERACTIVE_RESIZE)),
486 wxT("can't move and resize window at the same time") );
487
488 wxASSERT_MSG( !(flags & wxINTERACTIVE_RESIZE) ||
489 (flags & wxINTERACTIVE_WAIT_FOR_INPUT) ||
490 (flags & wxINTERACTIVE_RESIZE_DIR),
491 wxT("direction of resizing not specified") );
492
493 wxInteractiveMoveData data;
494 wxEventLoop loop;
495 wxWindow *focus = FindFocus();
496
497 // FIXME - display resize cursor if waiting for initial input
498
499 data.m_window = this;
500 data.m_evtLoop = &loop;
501 data.m_flags = flags;
502 data.m_rect = data.m_rectOrig = GetRect();
503 data.m_pos = wxGetMousePosition();
504 data.m_minSize = wxSize(GetMinWidth(), GetMinHeight());
505 data.m_maxSize = wxSize(GetMaxWidth(), GetMaxHeight());
506
507 this->PushEventHandler(new wxInteractiveMoveHandler(data));
508 if ( focus )
509 focus->PushEventHandler(new wxInteractiveMoveHandler(data));
510
511 CaptureMouse();
512 loop.Run();
513 ReleaseMouse();
514
515 this->PopEventHandler(TRUE/*delete*/);
516 if ( focus )
517 focus->PopEventHandler(TRUE/*delete*/);
518 }
519
520 // ----------------------------------------------------------------------------
521 // actions
522 // ----------------------------------------------------------------------------
523
524 void wxTopLevelWindow::ClickTitleBarButton(long button)
525 {
526 switch ( button )
527 {
528 case wxTOPLEVEL_BUTTON_CLOSE:
529 Close();
530 break;
531
532 case wxTOPLEVEL_BUTTON_ICONIZE:
533 Iconize();
534 break;
535
536 case wxTOPLEVEL_BUTTON_MAXIMIZE:
537 Maximize();
538 break;
539
540 case wxTOPLEVEL_BUTTON_RESTORE:
541 Restore();
542 break;
543
544 case wxTOPLEVEL_BUTTON_HELP:
545 #if wxUSE_HELP
546 {
547 wxContextHelp contextHelp(this);
548 }
549 #endif
550 break;
551
552 default:
553 wxFAIL_MSG(wxT("incorrect button specification"));
554 }
555 }
556
557 bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
558 long numArg,
559 const wxString& strArg)
560 {
561 bool isActive = numArg != 0;
562
563 if ( action == wxACTION_TOPLEVEL_ACTIVATE )
564 {
565 if ( m_isActive != isActive )
566 {
567 m_isActive = isActive;
568 RefreshTitleBar();
569 }
570 return TRUE;
571 }
572
573 else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS )
574 {
575 m_pressedButton = numArg;
576 RefreshTitleBar();
577 return TRUE;
578 }
579
580 else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE )
581 {
582 m_pressedButton = 0;
583 RefreshTitleBar();
584 return TRUE;
585 }
586
587 else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK )
588 {
589 m_pressedButton = 0;
590 RefreshTitleBar();
591 ClickTitleBarButton(numArg);
592 return TRUE;
593 }
594
595 else if ( action == wxACTION_TOPLEVEL_MOVE )
596 {
597 InteractiveMove(wxINTERACTIVE_MOVE);
598 return TRUE;
599 }
600
601 else if ( action == wxACTION_TOPLEVEL_RESIZE )
602 {
603 int flags = wxINTERACTIVE_RESIZE;
604 if ( numArg & wxHT_TOPLEVEL_BORDER_N )
605 flags |= wxINTERACTIVE_RESIZE_N;
606 if ( numArg & wxHT_TOPLEVEL_BORDER_S )
607 flags |= wxINTERACTIVE_RESIZE_S;
608 if ( numArg & wxHT_TOPLEVEL_BORDER_W )
609 flags |= wxINTERACTIVE_RESIZE_W;
610 if ( numArg & wxHT_TOPLEVEL_BORDER_E )
611 flags |= wxINTERACTIVE_RESIZE_E;
612 InteractiveMove(flags);
613 return TRUE;
614 }
615
616 else
617 return FALSE;
618 }
619
620
621 // ============================================================================
622 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
623 // ============================================================================
624
625 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand)
626 : wxStdInputHandler(inphand)
627 {
628 m_winCapture = NULL;
629 m_winHitTest = 0;
630 m_winPressed = 0;
631 m_borderCursorOn = FALSE;
632 }
633
634 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
635 const wxMouseEvent& event)
636 {
637 // the button has 2 states: pressed and normal with the following
638 // transitions between them:
639 //
640 // normal -> left down -> capture mouse and go to pressed state
641 // pressed -> left up inside -> generate click -> go to normal
642 // outside ------------------>
643 //
644 // the other mouse buttons are ignored
645 if ( event.Button(1) )
646 {
647 if ( event.ButtonDown(1) )
648 {
649 wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
650 long hit = w->HitTest(event.GetPosition());
651
652 if ( hit & wxHT_TOPLEVEL_ANY_BUTTON )
653 {
654 m_winCapture = w;
655 m_winCapture->CaptureMouse();
656 m_winHitTest = hit;
657 m_winPressed = hit;
658 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
659 return TRUE;
660 }
661 else if ( hit & wxHT_TOPLEVEL_TITLEBAR )
662 {
663 consumer->PerformAction(wxACTION_TOPLEVEL_MOVE);
664 return TRUE;
665 }
666 else if ( (consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER)
667 && (hit & wxHT_TOPLEVEL_ANY_BORDER) )
668 {
669 consumer->PerformAction(wxACTION_TOPLEVEL_RESIZE, hit);
670 return TRUE;
671 }
672 }
673
674 else // up
675 {
676 if ( m_winCapture )
677 {
678 m_winCapture->ReleaseMouse();
679 m_winCapture = NULL;
680
681 if ( m_winHitTest == m_winPressed )
682 {
683 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed);
684 return TRUE;
685 }
686 }
687 //else: the mouse was released outside the window, this doesn't
688 // count as a click
689 }
690 }
691
692 return wxStdInputHandler::HandleMouse(consumer, event);
693 }
694
695 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer,
696 const wxMouseEvent& event)
697 {
698 if ( event.GetEventObject() == m_winCapture )
699 {
700 long hit = m_winCapture->HitTest(event.GetPosition());
701
702 if ( hit != m_winHitTest )
703 {
704 if ( hit != m_winPressed )
705 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed);
706 else
707 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
708
709 m_winHitTest = hit;
710 return TRUE;
711 }
712 }
713 else if ( consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER )
714 {
715 wxTopLevelWindow *win = wxStaticCast(consumer->GetInputWindow(),
716 wxTopLevelWindow);
717 long hit = win->HitTest(event.GetPosition());
718
719 if ( hit != m_winHitTest )
720 {
721 m_winHitTest = hit;
722
723 if ( m_borderCursorOn )
724 {
725 m_borderCursorOn = FALSE;
726 win->SetCursor(m_origCursor);
727 }
728
729 if ( hit & wxHT_TOPLEVEL_ANY_BORDER )
730 {
731 m_borderCursorOn = TRUE;
732 wxCursor cur;
733
734 switch (hit)
735 {
736 case wxHT_TOPLEVEL_BORDER_N:
737 case wxHT_TOPLEVEL_BORDER_S:
738 cur = wxCursor(wxCURSOR_SIZENS);
739 break;
740 case wxHT_TOPLEVEL_BORDER_W:
741 case wxHT_TOPLEVEL_BORDER_E:
742 cur = wxCursor(wxCURSOR_SIZEWE);
743 break;
744 case wxHT_TOPLEVEL_BORDER_NE:
745 case wxHT_TOPLEVEL_BORDER_SW:
746 cur = wxCursor(wxCURSOR_SIZENESW);
747 break;
748 case wxHT_TOPLEVEL_BORDER_NW:
749 case wxHT_TOPLEVEL_BORDER_SE:
750 cur = wxCursor(wxCURSOR_SIZENWSE);
751 break;
752 default:
753 m_borderCursorOn = FALSE;
754 break;
755 }
756 if ( m_borderCursorOn )
757 {
758 m_origCursor = win->GetCursor();
759 win->SetCursor(cur);
760 }
761 }
762 }
763 }
764
765 return wxStdInputHandler::HandleMouseMove(consumer, event);
766 }
767
768 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer,
769 bool activated)
770 {
771 if ( m_borderCursorOn )
772 {
773 consumer->GetInputWindow()->SetCursor(m_origCursor);
774 m_borderCursorOn = FALSE;
775 }
776 consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
777 return FALSE;
778 }