]> git.saurik.com Git - wxWidgets.git/blob - src/univ/topluniv.cpp
wxRTTI for wxPopupWindow in wxMGL
[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 // VS: we can't use real client area size in 'rect', because
215 // wxTLWNative::DoGetClientSize calls GetClientAreaOrigin
216 // under wxMSW which in turn calls DoGetClientSize...
217 // inifinite recursion
218 #if 0
219 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
220 #else
221 w = h = 500;
222 #endif
223 wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
224 wxSize(w, h));
225 rect = m_renderer->GetFrameClientArea(rect,
226 GetDecorationsStyle());
227 if ( width )
228 *width = rect.width;
229 if ( height )
230 *height = rect.height;
231 }
232 else
233 wxTopLevelWindowNative::DoGetClientSize(width, height);
234 }
235
236 void wxTopLevelWindow::DoSetClientSize(int width, int height)
237 {
238 if ( ms_drawDecorations )
239 {
240 wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height),
241 GetDecorationsStyle());
242 wxTopLevelWindowNative::DoSetClientSize(size.x, size.y);
243 }
244 else
245 wxTopLevelWindowNative::DoSetClientSize(width, height);
246 }
247
248 void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
249 {
250 if ( !ms_drawDecorations || !m_renderer )
251 event.Skip();
252 else
253 {
254 // get the window rect
255 wxRect rect;
256 wxSize size = GetSize();
257 rect.x =
258 rect.y = 0;
259 rect.width = size.x;
260 rect.height = size.y;
261
262 wxWindowDC dc(this);
263 m_renderer->DrawFrameTitleBar(dc, rect,
264 GetTitle(), m_titlebarIcon,
265 GetDecorationsStyle(),
266 m_pressedButton,
267 wxCONTROL_PRESSED);
268 }
269 }
270
271 long wxTopLevelWindow::HitTest(const wxPoint& pt) const
272 {
273 int w, h;
274 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
275 wxRect rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w, h));
276
277 return m_renderer->HitTestFrame(rect, pt+GetClientAreaOrigin(), GetDecorationsStyle());
278 }
279
280 // ----------------------------------------------------------------------------
281 // icons
282 // ----------------------------------------------------------------------------
283
284 void wxTopLevelWindow::SetIcon(const wxIcon& icon)
285 {
286 wxTopLevelWindowNative::SetIcon(icon);
287
288 if ( ms_drawDecorations && m_renderer )
289 {
290 wxSize size = m_renderer->GetFrameIconSize();
291
292 if ( !icon.Ok() || size.x == -1 )
293 m_titlebarIcon = icon;
294 else
295 {
296 wxBitmap bmp1;
297 bmp1.CopyFromIcon(icon);
298 if ( !bmp1.Ok() )
299 m_titlebarIcon = wxNullIcon;
300 else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
301 m_titlebarIcon = icon;
302 else
303 {
304 wxImage img = bmp1.ConvertToImage();
305 img.Rescale(size.x, size.y);
306 m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
307 }
308 }
309 }
310 }
311
312 // ----------------------------------------------------------------------------
313 // interactive manipulation
314 // ----------------------------------------------------------------------------
315
316 #define wxINTERACTIVE_RESIZE_DIR \
317 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
318 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
319
320 struct wxInteractiveMoveData
321 {
322 wxTopLevelWindowBase *m_window;
323 wxEventLoop *m_evtLoop;
324 int m_flags;
325 wxRect m_rect;
326 wxRect m_rectOrig;
327 wxPoint m_pos;
328 wxSize m_minSize, m_maxSize;
329 };
330
331 class wxInteractiveMoveHandler : public wxEvtHandler
332 {
333 public:
334 wxInteractiveMoveHandler(wxInteractiveMoveData& data) : m_data(data) {}
335
336 private:
337 DECLARE_EVENT_TABLE()
338 void OnMouseMove(wxMouseEvent& event);
339 void OnMouseDown(wxMouseEvent& event);
340 void OnMouseUp(wxMouseEvent& event);
341 void OnKeyDown(wxKeyEvent& event);
342
343 wxInteractiveMoveData& m_data;
344 };
345
346 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler, wxEvtHandler)
347 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove)
348 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown)
349 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp)
350 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown)
351 END_EVENT_TABLE()
352
353
354 static inline LINKAGEMODE
355 void wxApplyResize(wxInteractiveMoveData& data, const wxPoint& diff)
356 {
357 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
358 {
359 data.m_rect.x += diff.x;
360 data.m_rect.width -= diff.x;
361 }
362 else if ( data.m_flags & wxINTERACTIVE_RESIZE_E )
363 {
364 data.m_rect.width += diff.x;
365 }
366 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
367 {
368 data.m_rect.y += diff.y;
369 data.m_rect.height -= diff.y;
370 }
371 else if ( data.m_flags & wxINTERACTIVE_RESIZE_S )
372 {
373 data.m_rect.height += diff.y;
374 }
375
376 if ( data.m_minSize.x != -1 && data.m_rect.width < data.m_minSize.x )
377 {
378 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
379 data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
380 data.m_rect.width = data.m_minSize.x;
381 }
382 if ( data.m_maxSize.x != -1 && data.m_rect.width > data.m_maxSize.x )
383 {
384 if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
385 data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
386 data.m_rect.width = data.m_maxSize.x;
387 }
388 if ( data.m_minSize.y != -1 && data.m_rect.height < data.m_minSize.y )
389 {
390 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
391 data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
392 data.m_rect.height = data.m_minSize.y;
393 }
394 if ( data.m_maxSize.y != -1 && data.m_rect.height > data.m_maxSize.y )
395 {
396 if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
397 data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
398 data.m_rect.height = data.m_maxSize.y;
399 }
400 }
401
402 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent& event)
403 {
404 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
405 event.Skip();
406
407 else if ( m_data.m_flags & wxINTERACTIVE_MOVE )
408 {
409 wxPoint diff = wxGetMousePosition() - m_data.m_pos;
410 m_data.m_rect = m_data.m_rectOrig;
411 m_data.m_rect.Offset(diff);
412 m_data.m_window->Move(m_data.m_rect.GetPosition());
413 }
414
415 else if ( m_data.m_flags & wxINTERACTIVE_RESIZE )
416 {
417 wxPoint diff = wxGetMousePosition() - m_data.m_pos;
418 m_data.m_rect = m_data.m_rectOrig;
419 wxApplyResize(m_data, diff);
420 m_data.m_window->SetSize(m_data.m_rect);
421 }
422 }
423
424 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent& event)
425 {
426 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
427 {
428 m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
429 m_data.m_pos = wxGetMousePosition();
430 }
431 }
432
433 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent& event)
434 {
435 if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
436 {
437 m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
438 m_data.m_pos = wxGetMousePosition();
439 }
440
441 wxPoint diff(-1,-1);
442
443 switch ( event.GetKeyCode() )
444 {
445 case WXK_UP: diff = wxPoint(0, -16); break;
446 case WXK_DOWN: diff = wxPoint(0, 16); break;
447 case WXK_LEFT: diff = wxPoint(-16, 0); break;
448 case WXK_RIGHT: diff = wxPoint(16, 0); break;
449 case WXK_ESCAPE:
450 m_data.m_window->SetSize(m_data.m_rectOrig);
451 m_data.m_evtLoop->Exit();
452 return;
453 case WXK_RETURN:
454 m_data.m_evtLoop->Exit();
455 return;
456 }
457
458 if ( diff.x != -1 )
459 {
460 if ( m_data.m_flags & wxINTERACTIVE_MOVE )
461 {
462 m_data.m_rect.Offset(diff);
463 m_data.m_window->Move(m_data.m_rect.GetPosition());
464 }
465 else /* wxINTERACTIVE_RESIZE */
466 {
467 if ( !(m_data.m_flags & wxINTERACTIVE_RESIZE_DIR) )
468 {
469 if ( diff.y < 0 )
470 m_data.m_flags |= wxINTERACTIVE_RESIZE_N;
471 else if ( diff.y > 0 )
472 m_data.m_flags |= wxINTERACTIVE_RESIZE_S;
473 if ( diff.x < 0 )
474 m_data.m_flags |= wxINTERACTIVE_RESIZE_W;
475 else if ( diff.x > 0 )
476 m_data.m_flags |= wxINTERACTIVE_RESIZE_E;
477 }
478
479 wxApplyResize(m_data, diff);
480 m_data.m_window->SetSize(m_data.m_rect);
481 }
482 }
483 }
484
485 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent& event)
486 {
487 m_data.m_evtLoop->Exit();
488 }
489
490
491 void wxTopLevelWindow::InteractiveMove(int flags)
492 {
493 wxASSERT_MSG( !((flags & wxINTERACTIVE_MOVE) && (flags & wxINTERACTIVE_RESIZE)),
494 wxT("can't move and resize window at the same time") );
495
496 wxASSERT_MSG( !(flags & wxINTERACTIVE_RESIZE) ||
497 (flags & wxINTERACTIVE_WAIT_FOR_INPUT) ||
498 (flags & wxINTERACTIVE_RESIZE_DIR),
499 wxT("direction of resizing not specified") );
500
501 wxInteractiveMoveData data;
502 wxEventLoop loop;
503 wxWindow *focus = FindFocus();
504
505 // FIXME - display resize cursor if waiting for initial input
506
507 data.m_window = this;
508 data.m_evtLoop = &loop;
509 data.m_flags = flags;
510 data.m_rect = data.m_rectOrig = GetRect();
511 data.m_pos = wxGetMousePosition();
512 data.m_minSize = wxSize(GetMinWidth(), GetMinHeight());
513 data.m_maxSize = wxSize(GetMaxWidth(), GetMaxHeight());
514
515 this->PushEventHandler(new wxInteractiveMoveHandler(data));
516 if ( focus )
517 focus->PushEventHandler(new wxInteractiveMoveHandler(data));
518
519 CaptureMouse();
520 loop.Run();
521 ReleaseMouse();
522
523 this->PopEventHandler(TRUE/*delete*/);
524 if ( focus )
525 focus->PopEventHandler(TRUE/*delete*/);
526 }
527
528 // ----------------------------------------------------------------------------
529 // actions
530 // ----------------------------------------------------------------------------
531
532 void wxTopLevelWindow::ClickTitleBarButton(long button)
533 {
534 switch ( button )
535 {
536 case wxTOPLEVEL_BUTTON_CLOSE:
537 Close();
538 break;
539
540 case wxTOPLEVEL_BUTTON_ICONIZE:
541 Iconize();
542 break;
543
544 case wxTOPLEVEL_BUTTON_MAXIMIZE:
545 Maximize();
546 break;
547
548 case wxTOPLEVEL_BUTTON_RESTORE:
549 Restore();
550 break;
551
552 case wxTOPLEVEL_BUTTON_HELP:
553 #if wxUSE_HELP
554 {
555 wxContextHelp contextHelp(this);
556 }
557 #endif
558 break;
559
560 default:
561 wxFAIL_MSG(wxT("incorrect button specification"));
562 }
563 }
564
565 bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
566 long numArg,
567 const wxString& strArg)
568 {
569 bool isActive = numArg != 0;
570
571 if ( action == wxACTION_TOPLEVEL_ACTIVATE )
572 {
573 if ( m_isActive != isActive )
574 {
575 m_isActive = isActive;
576 RefreshTitleBar();
577 }
578 return TRUE;
579 }
580
581 else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS )
582 {
583 m_pressedButton = numArg;
584 RefreshTitleBar();
585 return TRUE;
586 }
587
588 else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE )
589 {
590 m_pressedButton = 0;
591 RefreshTitleBar();
592 return TRUE;
593 }
594
595 else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK )
596 {
597 m_pressedButton = 0;
598 RefreshTitleBar();
599 ClickTitleBarButton(numArg);
600 return TRUE;
601 }
602
603 else if ( action == wxACTION_TOPLEVEL_MOVE )
604 {
605 InteractiveMove(wxINTERACTIVE_MOVE);
606 return TRUE;
607 }
608
609 else if ( action == wxACTION_TOPLEVEL_RESIZE )
610 {
611 int flags = wxINTERACTIVE_RESIZE;
612 if ( numArg & wxHT_TOPLEVEL_BORDER_N )
613 flags |= wxINTERACTIVE_RESIZE_N;
614 if ( numArg & wxHT_TOPLEVEL_BORDER_S )
615 flags |= wxINTERACTIVE_RESIZE_S;
616 if ( numArg & wxHT_TOPLEVEL_BORDER_W )
617 flags |= wxINTERACTIVE_RESIZE_W;
618 if ( numArg & wxHT_TOPLEVEL_BORDER_E )
619 flags |= wxINTERACTIVE_RESIZE_E;
620 InteractiveMove(flags);
621 return TRUE;
622 }
623
624 else
625 return FALSE;
626 }
627
628
629 // ============================================================================
630 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
631 // ============================================================================
632
633 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand)
634 : wxStdInputHandler(inphand)
635 {
636 m_winCapture = NULL;
637 m_winHitTest = 0;
638 m_winPressed = 0;
639 m_borderCursorOn = FALSE;
640 }
641
642 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
643 const wxMouseEvent& event)
644 {
645 // the button has 2 states: pressed and normal with the following
646 // transitions between them:
647 //
648 // normal -> left down -> capture mouse and go to pressed state
649 // pressed -> left up inside -> generate click -> go to normal
650 // outside ------------------>
651 //
652 // the other mouse buttons are ignored
653 if ( event.Button(1) )
654 {
655 if ( event.ButtonDown(1) )
656 {
657 wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
658 long hit = w->HitTest(event.GetPosition());
659
660 if ( hit & wxHT_TOPLEVEL_ANY_BUTTON )
661 {
662 m_winCapture = w;
663 m_winCapture->CaptureMouse();
664 m_winHitTest = hit;
665 m_winPressed = hit;
666 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
667 return TRUE;
668 }
669 else if ( hit & wxHT_TOPLEVEL_TITLEBAR )
670 {
671 consumer->PerformAction(wxACTION_TOPLEVEL_MOVE);
672 return TRUE;
673 }
674 else if ( (consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER)
675 && (hit & wxHT_TOPLEVEL_ANY_BORDER) )
676 {
677 consumer->PerformAction(wxACTION_TOPLEVEL_RESIZE, hit);
678 return TRUE;
679 }
680 }
681
682 else // up
683 {
684 if ( m_winCapture )
685 {
686 m_winCapture->ReleaseMouse();
687 m_winCapture = NULL;
688
689 if ( m_winHitTest == m_winPressed )
690 {
691 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed);
692 return TRUE;
693 }
694 }
695 //else: the mouse was released outside the window, this doesn't
696 // count as a click
697 }
698 }
699
700 return wxStdInputHandler::HandleMouse(consumer, event);
701 }
702
703 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer,
704 const wxMouseEvent& event)
705 {
706 if ( event.GetEventObject() == m_winCapture )
707 {
708 long hit = m_winCapture->HitTest(event.GetPosition());
709
710 if ( hit != m_winHitTest )
711 {
712 if ( hit != m_winPressed )
713 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed);
714 else
715 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
716
717 m_winHitTest = hit;
718 return TRUE;
719 }
720 }
721 else if ( consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER )
722 {
723 wxTopLevelWindow *win = wxStaticCast(consumer->GetInputWindow(),
724 wxTopLevelWindow);
725 long hit = win->HitTest(event.GetPosition());
726
727 if ( hit != m_winHitTest )
728 {
729 m_winHitTest = hit;
730
731 if ( m_borderCursorOn )
732 {
733 m_borderCursorOn = FALSE;
734 win->SetCursor(m_origCursor);
735 }
736
737 if ( hit & wxHT_TOPLEVEL_ANY_BORDER )
738 {
739 m_borderCursorOn = TRUE;
740 wxCursor cur;
741
742 switch (hit)
743 {
744 case wxHT_TOPLEVEL_BORDER_N:
745 case wxHT_TOPLEVEL_BORDER_S:
746 cur = wxCursor(wxCURSOR_SIZENS);
747 break;
748 case wxHT_TOPLEVEL_BORDER_W:
749 case wxHT_TOPLEVEL_BORDER_E:
750 cur = wxCursor(wxCURSOR_SIZEWE);
751 break;
752 case wxHT_TOPLEVEL_BORDER_NE:
753 case wxHT_TOPLEVEL_BORDER_SW:
754 cur = wxCursor(wxCURSOR_SIZENESW);
755 break;
756 case wxHT_TOPLEVEL_BORDER_NW:
757 case wxHT_TOPLEVEL_BORDER_SE:
758 cur = wxCursor(wxCURSOR_SIZENWSE);
759 break;
760 default:
761 m_borderCursorOn = FALSE;
762 break;
763 }
764 if ( m_borderCursorOn )
765 {
766 m_origCursor = win->GetCursor();
767 win->SetCursor(cur);
768 }
769 }
770 }
771 }
772
773 return wxStdInputHandler::HandleMouseMove(consumer, event);
774 }
775
776 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer,
777 bool activated)
778 {
779 if ( m_borderCursorOn )
780 {
781 consumer->GetInputWindow()->SetCursor(m_origCursor);
782 m_borderCursorOn = FALSE;
783 }
784 consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
785 return FALSE;
786 }