1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mac/classic/window.cpp 3// Purpose: wxWindowMac 4// Author: Stefan Csomor 5// Modified by: 6// Created: 1998-01-01 7// RCS-ID: $Id: window.cpp 39787 2006-06-19 07:12:50Z ABX $ 8// Copyright: (c) Stefan Csomor 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12#include "wx/wxprec.h" 13 14#include "wx/window.h" 15 16#ifndef WX_PRECOMP 17 #include "wx/log.h" 18 #include "wx/app.h" 19 #include "wx/utils.h" 20 #include "wx/panel.h" 21 #include "wx/frame.h" 22 #include "wx/dc.h" 23 #include "wx/dcclient.h" 24 #include "wx/button.h" 25 #include "wx/menu.h" 26 #include "wx/dialog.h" 27 #include "wx/settings.h" 28 #include "wx/msgdlg.h" 29 #include "wx/scrolbar.h" 30 #include "wx/statbox.h" 31 #include "wx/listbox.h" 32 #include "wx/layout.h" 33 #include "wx/statusbr.h" 34 #include "wx/menuitem.h" 35#endif 36 37#include "wx/notebook.h" 38#include "wx/tabctrl.h" 39#include "wx/tooltip.h" 40#include "wx/spinctrl.h" 41#include "wx/geometry.h" 42 43#if wxUSE_CARET 44 #include "wx/caret.h" 45#endif // wxUSE_CARET 46 47#define wxWINDOW_HSCROLL 5998 48#define wxWINDOW_VSCROLL 5997 49#define MAC_SCROLLBAR_SIZE 16 50 51#include "wx/mac/uma.h" 52#ifndef __DARWIN__ 53#include <Windows.h> 54#include <ToolUtils.h> 55#endif 56 57#if wxUSE_DRAG_AND_DROP 58#include "wx/dnd.h" 59#endif 60 61#include <string.h> 62 63wxWindowMac* gFocusWindow = NULL ; 64 65#ifdef __WXUNIVERSAL__ 66 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) 67#else // __WXMAC__ 68 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) 69#endif // __WXUNIVERSAL__/__WXMAC__ 70 71BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) 72 EVT_NC_PAINT(wxWindowMac::OnNcPaint) 73 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground) 74 EVT_SET_FOCUS(wxWindowMac::OnSetFocus) 75 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) 76END_EVENT_TABLE() 77 78#define wxMAC_DEBUG_REDRAW 0 79#ifndef wxMAC_DEBUG_REDRAW 80#define wxMAC_DEBUG_REDRAW 0 81#endif 82 83#define wxMAC_USE_THEME_BORDER 0 84 85 86// =========================================================================== 87// implementation 88// =========================================================================== 89 90 91// ---------------------------------------------------------------------------- 92// constructors and such 93// ---------------------------------------------------------------------------- 94 95void wxWindowMac::Init() 96{ 97 m_backgroundTransparent = false; 98 99 // as all windows are created with WS_VISIBLE style... 100 m_isShown = true; 101 102 m_x = 0; 103 m_y = 0 ; 104 m_width = 0 ; 105 m_height = 0 ; 106 107 m_hScrollBar = NULL ; 108 m_vScrollBar = NULL ; 109} 110 111// Destructor 112wxWindowMac::~wxWindowMac() 113{ 114 SendDestroyEvent(); 115 116 // deleting a window while it is shown invalidates the region 117 if ( IsShown() ) { 118 wxWindowMac* iter = this ; 119 while( iter ) { 120 if ( iter->IsTopLevel() ) 121 { 122 Refresh() ; 123 break ; 124 } 125 iter = iter->GetParent() ; 126 127 } 128 } 129 130 m_isBeingDeleted = true; 131 132#ifndef __WXUNIVERSAL__ 133 // VS: make sure there's no wxFrame with last focus set to us: 134 for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) 135 { 136 wxFrame *frame = wxDynamicCast(win, wxFrame); 137 if ( frame ) 138 { 139 if ( frame->GetLastFocus() == this ) 140 { 141 frame->SetLastFocus((wxWindow*)NULL); 142 } 143 break; 144 } 145 } 146#endif // __WXUNIVERSAL__ 147 148 if ( s_lastMouseWindow == this ) 149 { 150 s_lastMouseWindow = NULL ; 151 } 152 153 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ; 154 if ( frame ) 155 { 156 if ( frame->GetLastFocus() == this ) 157 frame->SetLastFocus( NULL ) ; 158 } 159 160 if ( gFocusWindow == this ) 161 { 162 gFocusWindow = NULL ; 163 } 164 165 DestroyChildren(); 166 167 // delete our drop target if we've got one 168#if wxUSE_DRAG_AND_DROP 169 if ( m_dropTarget != NULL ) 170 { 171 delete m_dropTarget; 172 m_dropTarget = NULL; 173 } 174#endif // wxUSE_DRAG_AND_DROP 175} 176 177// Constructor 178bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, 179 const wxPoint& pos, 180 const wxSize& size, 181 long style, 182 const wxString& name) 183{ 184 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); 185 186#if wxUSE_STATBOX 187 // wxGTK doesn't allow to create controls with static box as the parent so 188 // this will result in a crash when the program is ported to wxGTK - warn 189 // about it 190 // 191 // the correct solution is to create the controls as siblings of the 192 // static box 193 wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox), 194 _T("wxStaticBox can't be used as a window parent!") ); 195#endif // wxUSE_STATBOX 196 197 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) 198 return false; 199 200 parent->AddChild(this); 201 202 m_x = (int)pos.x; 203 m_y = (int)pos.y; 204 AdjustForParentClientOrigin(m_x, m_y, wxSIZE_USE_EXISTING); 205 m_width = WidthDefault( size.x ); 206 m_height = HeightDefault( size.y ) ; 207#ifndef __WXUNIVERSAL__ 208 // Don't give scrollbars to wxControls unless they ask for them 209 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) || 210 (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL))) 211 { 212 MacCreateScrollBars( style ) ; 213 } 214#endif 215 216 wxWindowCreateEvent event(this); 217 GetEventHandler()->AddPendingEvent(event); 218 219 return true; 220} 221 222void wxWindowMac::SetFocus() 223{ 224 if ( gFocusWindow == this ) 225 return ; 226 227 if ( AcceptsFocus() ) 228 { 229 if (gFocusWindow ) 230 { 231#if wxUSE_CARET 232 // Deal with caret 233 if ( gFocusWindow->m_caret ) 234 { 235 gFocusWindow->m_caret->OnKillFocus(); 236 } 237#endif // wxUSE_CARET 238#ifndef __WXUNIVERSAL__ 239 wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ; 240 if ( control && control->GetMacControl() ) 241 { 242 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNoPart ) ; 243 control->MacRedrawControl() ; 244 } 245#endif 246 // Without testing the window id, for some reason 247 // a kill focus event can still be sent to 248 // the control just being focussed. 249 int thisId = this->m_windowId; 250 int gFocusWindowId = gFocusWindow->m_windowId; 251 if (gFocusWindowId != thisId) 252 { 253 wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId); 254 event.SetEventObject(gFocusWindow); 255 gFocusWindow->GetEventHandler()->ProcessEvent(event) ; 256 } 257 } 258 gFocusWindow = this ; 259 { 260 #if wxUSE_CARET 261 // Deal with caret 262 if ( m_caret ) 263 { 264 m_caret->OnSetFocus(); 265 } 266 #endif // wxUSE_CARET 267 // panel wants to track the window which was the last to have focus in it 268 wxChildFocusEvent eventFocus(this); 269 GetEventHandler()->ProcessEvent(eventFocus); 270 271#ifndef __WXUNIVERSAL__ 272 wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ; 273 if ( control && control->GetMacControl() ) 274 { 275 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNextPart ) ; 276 } 277#endif 278 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); 279 event.SetEventObject(this); 280 GetEventHandler()->ProcessEvent(event) ; 281 } 282 } 283} 284 285bool wxWindowMac::Enable(bool enable) 286{ 287 if ( !wxWindowBase::Enable(enable) ) 288 return false; 289 290 MacSuperEnabled( enable ) ; 291 292 return true; 293} 294 295void wxWindowMac::DoCaptureMouse() 296{ 297 wxTheApp->s_captureWindow = this ; 298} 299 300wxWindow* wxWindowBase::GetCapture() 301{ 302 return wxTheApp->s_captureWindow ; 303} 304 305void wxWindowMac::DoReleaseMouse() 306{ 307 wxTheApp->s_captureWindow = NULL ; 308} 309 310#if wxUSE_DRAG_AND_DROP 311 312void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) 313{ 314 if ( m_dropTarget != 0 ) { 315 delete m_dropTarget; 316 } 317 318 m_dropTarget = pDropTarget; 319 if ( m_dropTarget != 0 ) 320 { 321 // TODO 322 } 323} 324 325#endif 326 327// Old style file-manager drag&drop 328void wxWindowMac::DragAcceptFiles(bool accept) 329{ 330 // TODO 331} 332 333// Get total size 334void wxWindowMac::DoGetSize(int *x, int *y) const 335{ 336 if(x) *x = m_width ; 337 if(y) *y = m_height ; 338} 339 340void wxWindowMac::DoGetPosition(int *x, int *y) const 341{ 342 int xx,yy; 343 344 xx = m_x ; 345 yy = m_y ; 346 if ( !IsTopLevel() && GetParent()) 347 { 348 wxPoint pt(GetParent()->GetClientAreaOrigin()); 349 xx -= pt.x; 350 yy -= pt.y; 351 } 352 if(x) *x = xx; 353 if(y) *y = yy; 354} 355 356#if wxUSE_MENUS 357bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) 358{ 359 menu->SetInvokingWindow(this); 360 menu->UpdateUI(); 361 362 if ( x == -1 && y == -1 ) 363 { 364 wxPoint mouse = wxGetMousePosition(); 365 x = mouse.x; y = mouse.y; 366 } 367 else 368 { 369 ClientToScreen( &x , &y ) ; 370 } 371 372 menu->MacBeforeDisplay( true ) ; 373 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; 374 if ( HiWord(menuResult) != 0 ) 375 { 376 MenuCommand id ; 377 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ; 378 wxMenuItem* item = NULL ; 379 wxMenu* realmenu ; 380 item = menu->FindItem(id, &realmenu) ; 381 if (item->IsCheckable()) 382 { 383 item->Check( !item->IsChecked() ) ; 384 } 385 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; 386 } 387 menu->MacAfterDisplay( true ) ; 388 389 menu->SetInvokingWindow(NULL); 390 391 return true; 392} 393#endif 394 395void wxWindowMac::DoScreenToClient(int *x, int *y) const 396{ 397 WindowRef window = (WindowRef) MacGetRootWindow() ; 398 399 Point localwhere = {0,0} ; 400 401 if(x) localwhere.h = * x ; 402 if(y) localwhere.v = * y ; 403 404 GrafPtr port ; 405 ::GetPort( &port ) ; 406 ::SetPort( UMAGetWindowPort( window ) ) ; 407 ::GlobalToLocal( &localwhere ) ; 408 ::SetPort( port ) ; 409 410 if(x) *x = localwhere.h ; 411 if(y) *y = localwhere.v ; 412 413 MacRootWindowToWindow( x , y ) ; 414 if ( x ) 415 *x -= MacGetLeftBorderSize() ; 416 if ( y ) 417 *y -= MacGetTopBorderSize() ; 418} 419 420void wxWindowMac::DoClientToScreen(int *x, int *y) const 421{ 422 WindowRef window = (WindowRef) MacGetRootWindow() ; 423 424 if ( x ) 425 *x += MacGetLeftBorderSize() ; 426 if ( y ) 427 *y += MacGetTopBorderSize() ; 428 429 MacWindowToRootWindow( x , y ) ; 430 431 Point localwhere = { 0,0 }; 432 if(x) localwhere.h = * x ; 433 if(y) localwhere.v = * y ; 434 435 GrafPtr port ; 436 ::GetPort( &port ) ; 437 ::SetPort( UMAGetWindowPort( window ) ) ; 438 439 ::LocalToGlobal( &localwhere ) ; 440 ::SetPort( port ) ; 441 if(x) *x = localwhere.h ; 442 if(y) *y = localwhere.v ; 443} 444 445void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const 446{ 447 wxPoint origin = GetClientAreaOrigin() ; 448 if(x) *x += origin.x ; 449 if(y) *y += origin.y ; 450 451 MacWindowToRootWindow( x , y ) ; 452} 453 454void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const 455{ 456 wxPoint origin = GetClientAreaOrigin() ; 457 MacRootWindowToWindow( x , y ) ; 458 if(x) *x -= origin.x ; 459 if(y) *y -= origin.y ; 460} 461 462void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const 463{ 464 if ( !IsTopLevel() ) 465 { 466 if(x) *x += m_x ; 467 if(y) *y += m_y ; 468 GetParent()->MacWindowToRootWindow( x , y ) ; 469 } 470} 471 472void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const 473{ 474 if ( !IsTopLevel() ) 475 { 476 if(x) *x -= m_x ; 477 if(y) *y -= m_y ; 478 GetParent()->MacRootWindowToWindow( x , y ) ; 479 } 480} 481 482bool wxWindowMac::SetCursor(const wxCursor& cursor) 483{ 484 if (m_cursor == cursor) 485 return false; 486 487 if (wxNullCursor == cursor) 488 { 489 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) 490 return false ; 491 } 492 else 493 { 494 if ( ! wxWindowBase::SetCursor( cursor ) ) 495 return false ; 496 } 497 498 wxASSERT_MSG( m_cursor.Ok(), 499 wxT("cursor must be valid after call to the base version")); 500 501 Point pt ; 502 wxWindowMac *mouseWin ; 503 GetMouse( &pt ) ; 504 505 // Change the cursor NOW if we're within the correct window 506 507 if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) ) 508 { 509 if ( mouseWin == this && !wxIsBusy() ) 510 { 511 m_cursor.MacInstall() ; 512 } 513 } 514 515 return true ; 516} 517 518 519// Get size *available for subwindows* i.e. excluding menu bar etc. 520void wxWindowMac::DoGetClientSize(int *x, int *y) const 521{ 522 int ww, hh; 523 ww = m_width ; 524 hh = m_height ; 525 526 ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ; 527 hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( ); 528 529 if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) ) 530 { 531 int x1 = 0 ; 532 int y1 = 0 ; 533 int w = m_width ; 534 int h = m_height ; 535 536 MacClientToRootWindow( &x1 , &y1 ) ; 537 MacClientToRootWindow( &w , &h ) ; 538 539 wxWindowMac *iter = (wxWindowMac*)this ; 540 541 int totW = 10000 , totH = 10000; 542 while( iter ) 543 { 544 if ( iter->IsTopLevel() ) 545 { 546 totW = iter->m_width ; 547 totH = iter->m_height ; 548 break ; 549 } 550 551 iter = iter->GetParent() ; 552 } 553 554 if (m_hScrollBar && m_hScrollBar->IsShown() ) 555 { 556 hh -= MAC_SCROLLBAR_SIZE; 557 if ( h-y1 >= totH ) 558 { 559 hh += 1 ; 560 } 561 } 562 if (m_vScrollBar && m_vScrollBar->IsShown() ) 563 { 564 ww -= MAC_SCROLLBAR_SIZE; 565 if ( w-x1 >= totW ) 566 { 567 ww += 1 ; 568 } 569 } 570 } 571 if(x) *x = ww; 572 if(y) *y = hh; 573} 574 575 576// ---------------------------------------------------------------------------- 577// tooltips 578// ---------------------------------------------------------------------------- 579 580#if wxUSE_TOOLTIPS 581 582void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) 583{ 584 wxWindowBase::DoSetToolTip(tooltip); 585 586 if ( m_tooltip ) 587 m_tooltip->SetWindow(this); 588} 589 590#endif // wxUSE_TOOLTIPS 591 592void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) 593{ 594 int former_x = m_x ; 595 int former_y = m_y ; 596 int former_w = m_width ; 597 int former_h = m_height ; 598 599 int actualWidth = width; 600 int actualHeight = height; 601 int actualX = x; 602 int actualY = y; 603 604 if ((m_minWidth != -1) && (actualWidth < m_minWidth)) 605 actualWidth = m_minWidth; 606 if ((m_minHeight != -1) && (actualHeight < m_minHeight)) 607 actualHeight = m_minHeight; 608 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth)) 609 actualWidth = m_maxWidth; 610 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) 611 actualHeight = m_maxHeight; 612 613 bool doMove = false ; 614 bool doResize = false ; 615 616 if ( actualX != former_x || actualY != former_y ) 617 { 618 doMove = true ; 619 } 620 if ( actualWidth != former_w || actualHeight != former_h ) 621 { 622 doResize = true ; 623 } 624 625 if ( doMove || doResize ) 626 { 627 // erase former position 628 629 bool partialRepaint = false ; 630 631 if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) 632 { 633 wxPoint oldPos( m_x , m_y ) ; 634 wxPoint newPos( actualX , actualY ) ; 635 MacWindowToRootWindow( &oldPos.x , &oldPos.y ) ; 636 MacWindowToRootWindow( &newPos.x , &newPos.y ) ; 637 if ( oldPos == newPos ) 638 { 639 partialRepaint = true ; 640 RgnHandle oldRgn,newRgn,diffRgn ; 641 oldRgn = NewRgn() ; 642 newRgn = NewRgn() ; 643 diffRgn = NewRgn() ; 644 645 // invalidate the differences between the old and the new area 646 647 SetRectRgn(oldRgn , oldPos.x , oldPos.y , oldPos.x + m_width , oldPos.y + m_height ) ; 648 SetRectRgn(newRgn , newPos.x , newPos.y , newPos.x + actualWidth , newPos.y + actualHeight ) ; 649 DiffRgn( newRgn , oldRgn , diffRgn ) ; 650 InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; 651 DiffRgn( oldRgn , newRgn , diffRgn ) ; 652 InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; 653 654 // we also must invalidate the border areas, someone might optimize this one day to invalidate only the really 655 // changing pixels... 656 657 if ( MacGetLeftBorderSize() != 0 || MacGetRightBorderSize() != 0 || 658 MacGetTopBorderSize() != 0 || MacGetBottomBorderSize() != 0 ) 659 { 660 RgnHandle innerOldRgn, innerNewRgn ; 661 innerOldRgn = NewRgn() ; 662 innerNewRgn = NewRgn() ; 663 664 SetRectRgn(innerOldRgn , oldPos.x + MacGetLeftBorderSize() , oldPos.y + MacGetTopBorderSize() , 665 oldPos.x + m_width - MacGetRightBorderSize() , oldPos.y + m_height - MacGetBottomBorderSize() ) ; 666 DiffRgn( oldRgn , innerOldRgn , diffRgn ) ; 667 InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; 668 669 SetRectRgn(innerNewRgn , newPos.x + MacGetLeftBorderSize() , newPos.y + MacGetTopBorderSize() , 670 newPos.x + actualWidth - MacGetRightBorderSize() , newPos.y + actualHeight - MacGetBottomBorderSize() ) ; 671 DiffRgn( newRgn , innerNewRgn , diffRgn ) ; 672 InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; 673 674 DisposeRgn( innerOldRgn ) ; 675 DisposeRgn( innerNewRgn ) ; 676 } 677 678 DisposeRgn(oldRgn) ; 679 DisposeRgn(newRgn) ; 680 DisposeRgn(diffRgn) ; 681 } 682 } 683 684 if ( !partialRepaint ) 685 Refresh() ; 686 687 m_x = actualX ; 688 m_y = actualY ; 689 m_width = actualWidth ; 690 m_height = actualHeight ; 691 692 // update any low-level frame-relative positions 693 694 MacUpdateDimensions() ; 695 // erase new position 696 697 if ( !partialRepaint ) 698 Refresh() ; 699 if ( doMove ) 700 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified 701 702 MacRepositionScrollBars() ; 703 if ( doMove ) 704 { 705 wxPoint point(m_x, m_y); 706 wxMoveEvent event(point, m_windowId); 707 event.SetEventObject(this); 708 GetEventHandler()->ProcessEvent(event) ; 709 } 710 if ( doResize ) 711 { 712 MacRepositionScrollBars() ; 713 wxSize size(m_width, m_height); 714 wxSizeEvent event(size, m_windowId); 715 event.SetEventObject(this); 716 GetEventHandler()->ProcessEvent(event); 717 } 718 } 719 720} 721 722// set the size of the window: if the dimensions are positive, just use them, 723// but if any of them is equal to -1, it means that we must find the value for 724// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 725// which case -1 is a valid value for x and y) 726// 727// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 728// the width/height to best suit our contents, otherwise we reuse the current 729// width/height 730void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) 731{ 732 // get the current size and position... 733 int currentX, currentY; 734 GetPosition(¤tX, ¤tY); 735 736 int currentW,currentH; 737 GetSize(¤tW, ¤tH); 738 739 // ... and don't do anything (avoiding flicker) if it's already ok 740 if ( x == currentX && y == currentY && 741 width == currentW && height == currentH ) 742 { 743 MacRepositionScrollBars() ; // we might have a real position shift 744 return; 745 } 746 747 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) 748 x = currentX; 749 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) 750 y = currentY; 751 752 AdjustForParentClientOrigin(x, y, sizeFlags); 753 754 wxSize size(-1, -1); 755 if ( width == -1 ) 756 { 757 if ( sizeFlags & wxSIZE_AUTO_WIDTH ) 758 { 759 size = DoGetBestSize(); 760 width = size.x; 761 } 762 else 763 { 764 // just take the current one 765 width = currentW; 766 } 767 } 768 769 if ( height == -1 ) 770 { 771 if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) 772 { 773 if ( size.x == -1 ) 774 { 775 size = DoGetBestSize(); 776 } 777 //else: already called DoGetBestSize() above 778 779 height = size.y; 780 } 781 else 782 { 783 // just take the current one 784 height = currentH; 785 } 786 } 787 788 DoMoveWindow(x, y, width, height); 789 790} 791// For implementation purposes - sometimes decorations make the client area 792// smaller 793 794wxPoint wxWindowMac::GetClientAreaOrigin() const 795{ 796 return wxPoint(MacGetLeftBorderSize( ) , MacGetTopBorderSize( ) ); 797} 798 799void wxWindowMac::SetLabel(const wxString& label) 800{ 801 m_label = label ; 802} 803 804wxString wxWindowMac::GetLabel() const 805{ 806 return m_label ; 807} 808 809bool wxWindowMac::Show(bool show) 810{ 811 if ( !wxWindowBase::Show(show) ) 812 return false; 813 814 MacSuperShown( show ) ; 815 Refresh() ; 816 817 return true; 818} 819 820void wxWindowMac::MacSuperShown( bool show ) 821{ 822 wxWindowListNode *node = GetChildren().GetFirst(); 823 while ( node ) 824 { 825 wxWindowMac *child = node->GetData(); 826 if ( child->m_isShown ) 827 child->MacSuperShown( show ) ; 828 node = node->GetNext(); 829 } 830} 831 832void wxWindowMac::MacSuperEnabled( bool enabled ) 833{ 834 if ( !IsTopLevel() ) 835 { 836 // to be absolutely correct we'd have to invalidate (with eraseBkground 837 // because unter MacOSX the frames are drawn with an addXXX mode) 838 // the borders area 839 } 840 wxWindowListNode *node = GetChildren().GetFirst(); 841 while ( node ) 842 { 843 wxWindowMac *child = (wxWindowMac *)node->GetData(); 844 if ( child->m_isShown ) 845 child->MacSuperEnabled( enabled ) ; 846 node = node->GetNext(); 847 } 848} 849 850bool wxWindowMac::MacIsReallyShown() const 851{ 852 if ( m_isShown && (m_parent != NULL && !IsTopLevel() ) ) { 853 return m_parent->MacIsReallyShown(); 854 } 855 return m_isShown; 856/* 857 bool status = m_isShown ; 858 wxWindowMac * win = this ; 859 while ( status && win->m_parent != NULL ) 860 { 861 win = win->m_parent ; 862 status = win->m_isShown ; 863 } 864 return status ; 865*/ 866} 867 868int wxWindowMac::GetCharHeight() const 869{ 870 wxClientDC dc ( (wxWindowMac*)this ) ; 871 return dc.GetCharHeight() ; 872} 873 874int wxWindowMac::GetCharWidth() const 875{ 876 wxClientDC dc ( (wxWindowMac*)this ) ; 877 return dc.GetCharWidth() ; 878} 879 880void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, 881 int *descent, int *externalLeading, const wxFont *theFont ) const 882{ 883 const wxFont *fontToUse = theFont; 884 if ( !fontToUse ) 885 fontToUse = &m_font; 886 887 wxClientDC dc( (wxWindowMac*) this ) ; 888 long lx,ly,ld,le ; 889 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; 890 if ( externalLeading ) 891 *externalLeading = le ; 892 if ( descent ) 893 *descent = ld ; 894 if ( x ) 895 *x = lx ; 896 if ( y ) 897 *y = ly ; 898} 899 900/* 901 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect 902 * we always intersect with the entire window, not only with the client area 903 */ 904 905void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) 906{ 907 if ( MacGetTopLevelWindow() == NULL ) 908 return ; 909 910 if ( !MacIsReallyShown() ) 911 return ; 912 913 wxPoint client = GetClientAreaOrigin(); 914 int x1 = -client.x; 915 int y1 = -client.y; 916 int x2 = m_width - client.x; 917 int y2 = m_height - client.y; 918 919 if (IsKindOf( CLASSINFO(wxButton))) 920 { 921 // buttons have an "aura" 922 y1 -= 5; 923 x1 -= 5; 924 y2 += 5; 925 x2 += 5; 926 } 927 928 Rect clientrect = { y1, x1, y2, x2 }; 929 930 if ( rect ) 931 { 932 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ; 933 SectRect( &clientrect , &r , &clientrect ) ; 934 } 935 936 if ( !EmptyRect( &clientrect ) ) 937 { 938 int top = 0 , left = 0 ; 939 940 MacClientToRootWindow( &left , &top ) ; 941 OffsetRect( &clientrect , left , top ) ; 942 943 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ; 944 } 945} 946 947wxWindowMac *wxGetActiveWindow() 948{ 949 // actually this is a windows-only concept 950 return NULL; 951} 952 953// Coordinates relative to the window 954void wxWindowMac::WarpPointer (int x_pos, int y_pos) 955{ 956 // We really don't move the mouse programmatically under Mac. 957} 958 959const wxBrush& wxWindowMac::MacGetBackgroundBrush() 960{ 961 if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) 962 { 963 m_macBackgroundBrush.SetMacTheme( kThemeBrushDocumentWindowBackground ) ; 964 } 965 else if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) ) 966 { 967 // on mac we have the difficult situation, that 3dface gray can be different colours, depending whether 968 // it is on a notebook panel or not, in order to take care of that we walk up the hierarchy until we have 969 // either a non gray background color or a non control window 970 971 WindowRef window = (WindowRef) MacGetRootWindow() ; 972 973 wxWindowMac* parent = GetParent() ; 974 while( parent ) 975 { 976 if ( parent->MacGetRootWindow() != (WXWindow) window ) 977 { 978 // we are in a different window on the mac system 979 parent = NULL ; 980 break ; 981 } 982 983 { 984 if ( parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) 985 && parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) 986 { 987 // if we have any other colours in the hierarchy 988 m_macBackgroundBrush.SetColour( parent->m_backgroundColour ) ; 989 break ; 990 } 991 // if we have the normal colours in the hierarchy but another control etc. -> use it's background 992 if ( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) )) 993 { 994 Rect extent = { 0 , 0 , 0 , 0 } ; 995 int x , y ; 996 x = y = 0 ; 997 wxSize size = parent->GetSize() ; 998 parent->MacClientToRootWindow( &x , &y ) ; 999 extent.left = x ; 1000 extent.top = y ; 1001 extent.top-- ; 1002 extent.right = x + size.x ; 1003 extent.bottom = y + size.y ; 1004 m_macBackgroundBrush.SetMacThemeBackground( kThemeBackgroundTabPane , (WXRECTPTR) &extent ) ; // todo eventually change for inactive 1005 break ; 1006 } 1007 } 1008 parent = parent->GetParent() ; 1009 } 1010 if ( !parent ) 1011 { 1012 m_macBackgroundBrush.SetMacTheme( kThemeBrushDialogBackgroundActive ) ; // todo eventually change for inactive 1013 } 1014 } 1015 else 1016 { 1017 m_macBackgroundBrush.SetColour( m_backgroundColour ) ; 1018 } 1019 1020 return m_macBackgroundBrush ; 1021} 1022 1023void wxWindowMac::OnEraseBackground(wxEraseEvent& event) 1024{ 1025 event.GetDC()->Clear() ; 1026} 1027 1028void wxWindowMac::OnNcPaint( wxNcPaintEvent& event ) 1029{ 1030 wxWindowDC dc(this) ; 1031 wxMacPortSetter helper(&dc) ; 1032 1033 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ; 1034} 1035 1036int wxWindowMac::GetScrollPos(int orient) const 1037{ 1038 if ( orient == wxHORIZONTAL ) 1039 { 1040 if ( m_hScrollBar ) 1041 return m_hScrollBar->GetThumbPosition() ; 1042 } 1043 else 1044 { 1045 if ( m_vScrollBar ) 1046 return m_vScrollBar->GetThumbPosition() ; 1047 } 1048 return 0; 1049} 1050 1051// This now returns the whole range, not just the number 1052// of positions that we can scroll. 1053int wxWindowMac::GetScrollRange(int orient) const 1054{ 1055 if ( orient == wxHORIZONTAL ) 1056 { 1057 if ( m_hScrollBar ) 1058 return m_hScrollBar->GetRange() ; 1059 } 1060 else 1061 { 1062 if ( m_vScrollBar ) 1063 return m_vScrollBar->GetRange() ; 1064 } 1065 return 0; 1066} 1067 1068int wxWindowMac::GetScrollThumb(int orient) const 1069{ 1070 if ( orient == wxHORIZONTAL ) 1071 { 1072 if ( m_hScrollBar ) 1073 return m_hScrollBar->GetThumbSize() ; 1074 } 1075 else 1076 { 1077 if ( m_vScrollBar ) 1078 return m_vScrollBar->GetThumbSize() ; 1079 } 1080 return 0; 1081} 1082 1083void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh) 1084{ 1085 if ( orient == wxHORIZONTAL ) 1086 { 1087 if ( m_hScrollBar ) 1088 m_hScrollBar->SetThumbPosition( pos ) ; 1089 } 1090 else 1091 { 1092 if ( m_vScrollBar ) 1093 m_vScrollBar->SetThumbPosition( pos ) ; 1094 } 1095} 1096 1097void wxWindowMac::MacPaintBorders( int left , int top ) 1098{ 1099 if( IsTopLevel() ) 1100 return ; 1101 1102 int major,minor; 1103 wxGetOsVersion( &major, &minor ); 1104 1105 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ; 1106 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ; 1107 1108 RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ; 1109 RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ; 1110 // OS X has lighter border edges than classic: 1111 if (major >= 10) 1112 { 1113 darkShadow.red = 0x8E8E; 1114 darkShadow.green = 0x8E8E; 1115 darkShadow.blue = 0x8E8E; 1116 lightShadow.red = 0xBDBD; 1117 lightShadow.green = 0xBDBD; 1118 lightShadow.blue = 0xBDBD; 1119 } 1120 1121 PenNormal() ; 1122 1123 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) 1124 { 1125#if wxMAC_USE_THEME_BORDER 1126 Rect rect = { top , left , m_height + top , m_width + left } ; 1127 SInt32 border = 0 ; 1128 /* 1129 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; 1130 InsetRect( &rect , border , border ); 1131 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; 1132 */ 1133 1134 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; 1135#else 1136 bool sunken = HasFlag( wxSUNKEN_BORDER ) ; 1137 RGBForeColor( &face ); 1138 MoveTo( left + 0 , top + m_height - 2 ); 1139 LineTo( left + 0 , top + 0 ); 1140 LineTo( left + m_width - 2 , top + 0 ); 1141 1142 MoveTo( left + 2 , top + m_height - 3 ); 1143 LineTo( left + m_width - 3 , top + m_height - 3 ); 1144 LineTo( left + m_width - 3 , top + 2 ); 1145 1146 RGBForeColor( sunken ? &face : &darkShadow ); 1147 MoveTo( left + 0 , top + m_height - 1 ); 1148 LineTo( left + m_width - 1 , top + m_height - 1 ); 1149 LineTo( left + m_width - 1 , top + 0 ); 1150 1151 RGBForeColor( sunken ? &lightShadow : &white ); 1152 MoveTo( left + 1 , top + m_height - 3 ); 1153 LineTo( left + 1, top + 1 ); 1154 LineTo( left + m_width - 3 , top + 1 ); 1155 1156 RGBForeColor( sunken ? &white : &lightShadow ); 1157 MoveTo( left + 1 , top + m_height - 2 ); 1158 LineTo( left + m_width - 2 , top + m_height - 2 ); 1159 LineTo( left + m_width - 2 , top + 1 ); 1160 1161 RGBForeColor( sunken ? &darkShadow : &face ); 1162 MoveTo( left + 2 , top + m_height - 4 ); 1163 LineTo( left + 2 , top + 2 ); 1164 LineTo( left + m_width - 4 , top + 2 ); 1165#endif 1166 } 1167 else if (HasFlag(wxSIMPLE_BORDER)) 1168 { 1169 Rect rect = { top , left , m_height + top , m_width + left } ; 1170 RGBForeColor( &darkShadow ) ; 1171 FrameRect( &rect ) ; 1172 } 1173} 1174 1175void wxWindowMac::RemoveChild( wxWindowBase *child ) 1176{ 1177 if ( child == m_hScrollBar ) 1178 m_hScrollBar = NULL ; 1179 if ( child == m_vScrollBar ) 1180 m_vScrollBar = NULL ; 1181 1182 wxWindowBase::RemoveChild( child ) ; 1183} 1184 1185// New function that will replace some of the above. 1186void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible, 1187 int range, bool refresh) 1188{ 1189 if ( orient == wxHORIZONTAL ) 1190 { 1191 if ( m_hScrollBar ) 1192 { 1193 if ( range == 0 || thumbVisible >= range ) 1194 { 1195 if ( m_hScrollBar->IsShown() ) 1196 m_hScrollBar->Show(false) ; 1197 } 1198 else 1199 { 1200 if ( !m_hScrollBar->IsShown() ) 1201 m_hScrollBar->Show(true) ; 1202 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; 1203 } 1204 } 1205 } 1206 else 1207 { 1208 if ( m_vScrollBar ) 1209 { 1210 if ( range == 0 || thumbVisible >= range ) 1211 { 1212 if ( m_vScrollBar->IsShown() ) 1213 m_vScrollBar->Show(false) ; 1214 } 1215 else 1216 { 1217 if ( !m_vScrollBar->IsShown() ) 1218 m_vScrollBar->Show(true) ; 1219 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; 1220 } 1221 } 1222 } 1223 MacRepositionScrollBars() ; 1224} 1225 1226// Does a physical scroll 1227void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) 1228{ 1229 if( dx == 0 && dy ==0 ) 1230 return ; 1231 1232 1233 { 1234 wxClientDC dc(this) ; 1235 wxMacPortSetter helper(&dc) ; 1236 1237 int width , height ; 1238 GetClientSize( &width , &height ) ; 1239 1240 Rect scrollrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , dc.YLOG2DEVMAC(height) , dc.XLOG2DEVMAC(width) } ; 1241 RgnHandle updateRgn = NewRgn() ; 1242 ClipRect( &scrollrect ) ; 1243 if ( rect ) 1244 { 1245 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) , 1246 dc.XLOG2DEVMAC(rect->x + rect->width) } ; 1247 SectRect( &scrollrect , &r , &scrollrect ) ; 1248 } 1249 ScrollRect( &scrollrect , dx , dy , updateRgn ) ; 1250 // we also have to scroll the update rgn in this rectangle 1251 // in order not to loose updates 1252 WindowRef rootWindow = (WindowRef) MacGetRootWindow() ; 1253 RgnHandle formerUpdateRgn = NewRgn() ; 1254 RgnHandle scrollRgn = NewRgn() ; 1255 RectRgn( scrollRgn , &scrollrect ) ; 1256 GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ; 1257 Point pt = {0,0} ; 1258 LocalToGlobal( &pt ) ; 1259 OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ; 1260 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; 1261 if ( !EmptyRgn( formerUpdateRgn ) ) 1262 { 1263 MacOffsetRgn( formerUpdateRgn , dx , dy ) ; 1264 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; 1265 InvalWindowRgn(rootWindow , formerUpdateRgn ) ; 1266 } 1267 InvalWindowRgn(rootWindow , updateRgn ) ; 1268 DisposeRgn( updateRgn ) ; 1269 DisposeRgn( formerUpdateRgn ) ; 1270 DisposeRgn( scrollRgn ) ; 1271 } 1272 1273 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1274 { 1275 wxWindowMac *child = node->GetData(); 1276 if (child == m_vScrollBar) continue; 1277 if (child == m_hScrollBar) continue; 1278 if (child->IsTopLevel()) continue; 1279 1280 int x,y; 1281 child->GetPosition( &x, &y ); 1282 int w,h; 1283 child->GetSize( &w, &h ); 1284 if (rect) 1285 { 1286 wxRect rc(x,y,w,h); 1287 if (rect->Intersects(rc)) 1288 child->SetSize( x+dx, y+dy, w, h ); 1289 } 1290 else 1291 { 1292 child->SetSize( x+dx, y+dy, w, h ); 1293 } 1294 } 1295 1296 Update() ; 1297 1298} 1299 1300void wxWindowMac::MacOnScroll(wxScrollEvent &event ) 1301{ 1302 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar ) 1303 { 1304 wxScrollWinEvent wevent; 1305 wevent.SetPosition(event.GetPosition()); 1306 wevent.SetOrientation(event.GetOrientation()); 1307 wevent.SetEventObject(this); 1308 1309 if (event.GetEventType() == wxEVT_SCROLL_TOP) 1310 wevent.SetEventType( wxEVT_SCROLLWIN_TOP ); 1311 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM) 1312 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM ); 1313 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP) 1314 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP ); 1315 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN) 1316 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN ); 1317 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP) 1318 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP ); 1319 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN) 1320 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN ); 1321 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) 1322 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK ); 1323 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE) 1324 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE ); 1325 1326 GetEventHandler()->ProcessEvent(wevent); 1327 } 1328} 1329 1330// Get the window with the focus 1331wxWindowMac *wxWindowBase::DoFindFocus() 1332{ 1333 return gFocusWindow ; 1334} 1335 1336void wxWindowMac::OnSetFocus(wxFocusEvent& event) 1337{ 1338 // panel wants to track the window which was the last to have focus in it, 1339 // so we want to set ourselves as the window which last had focus 1340 // 1341 // notice that it's also important to do it upwards the tree becaus 1342 // otherwise when the top level panel gets focus, it won't set it back to 1343 // us, but to some other sibling 1344 1345 // CS:don't know if this is still needed: 1346 //wxChildFocusEvent eventFocus(this); 1347 //(void)GetEventHandler()->ProcessEvent(eventFocus); 1348 1349 event.Skip(); 1350} 1351 1352// Setup background and foreground colours correctly 1353void wxWindowMac::SetupColours() 1354{ 1355 if ( GetParent() ) 1356 SetBackgroundColour(GetParent()->GetBackgroundColour()); 1357} 1358 1359void wxWindowMac::OnInternalIdle() 1360{ 1361 // This calls the UI-update mechanism (querying windows for 1362 // menu/toolbar/control state information) 1363 if (wxUpdateUIEvent::CanUpdate(this)) 1364 UpdateWindowUI(wxUPDATE_UI_FROMIDLE); 1365} 1366 1367// Raise the window to the top of the Z order 1368void wxWindowMac::Raise() 1369{ 1370} 1371 1372// Lower the window to the bottom of the Z order 1373void wxWindowMac::Lower() 1374{ 1375} 1376 1377void wxWindowMac::DoSetClientSize(int width, int height) 1378{ 1379 if ( width != -1 || height != -1 ) 1380 { 1381 1382 if ( width != -1 && m_vScrollBar ) 1383 width += MAC_SCROLLBAR_SIZE ; 1384 if ( height != -1 && m_vScrollBar ) 1385 height += MAC_SCROLLBAR_SIZE ; 1386 1387 width += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ; 1388 height += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ; 1389 1390 DoSetSize( -1 , -1 , width , height ) ; 1391 } 1392} 1393 1394 1395wxWindowMac* wxWindowMac::s_lastMouseWindow = NULL ; 1396 1397bool wxWindowMac::MacGetWindowFromPointSub( const wxPoint &point , wxWindowMac** outWin ) 1398{ 1399 if ( IsTopLevel() ) 1400 { 1401 if ((point.x < 0) || (point.y < 0) || 1402 (point.x > (m_width)) || (point.y > (m_height))) 1403 return false; 1404 } 1405 else 1406 { 1407 if ((point.x < m_x) || (point.y < m_y) || 1408 (point.x > (m_x + m_width)) || (point.y > (m_y + m_height))) 1409 return false; 1410 } 1411 1412 WindowRef window = (WindowRef) MacGetRootWindow() ; 1413 1414 wxPoint newPoint( point ) ; 1415 1416 if ( !IsTopLevel() ) 1417 { 1418 newPoint.x -= m_x; 1419 newPoint.y -= m_y; 1420 } 1421 1422 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1423 { 1424 wxWindowMac *child = node->GetData(); 1425 // added the m_isShown test --dmazzoni 1426 if ( child->MacGetRootWindow() == (WXWindow) window && child->m_isShown ) 1427 { 1428 if (child->MacGetWindowFromPointSub(newPoint , outWin )) 1429 return true; 1430 } 1431 } 1432 1433 *outWin = this ; 1434 return true; 1435} 1436 1437bool wxWindowMac::MacGetWindowFromPoint( const wxPoint &screenpoint , wxWindowMac** outWin ) 1438{ 1439 WindowRef window ; 1440 1441 Point pt = { screenpoint.y , screenpoint.x } ; 1442 if ( ::FindWindow( pt , &window ) == 3 ) 1443 { 1444 1445 wxWindowMac* win = wxFindWinFromMacWindow( (WXWindow) window ) ; 1446 if ( win ) 1447 { 1448 // No, this yields the CLIENT are, we need the whole frame. RR. 1449 // point = win->ScreenToClient( point ) ; 1450 1451 GrafPtr port; 1452 ::GetPort( &port ) ; 1453 ::SetPort( UMAGetWindowPort( window ) ) ; 1454 ::GlobalToLocal( &pt ) ; 1455 ::SetPort( port ) ; 1456 1457 wxPoint point( pt.h, pt.v ) ; 1458 1459 return win->MacGetWindowFromPointSub( point , outWin ) ; 1460 } 1461 } 1462 return false ; 1463} 1464 1465static wxWindow *gs_lastWhich = NULL; 1466 1467bool wxWindowMac::MacSetupCursor( const wxPoint& pt) 1468{ 1469 // first trigger a set cursor event 1470 1471 wxPoint clientorigin = GetClientAreaOrigin() ; 1472 wxSize clientsize = GetClientSize() ; 1473 wxCursor cursor ; 1474 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) ) 1475 { 1476 wxSetCursorEvent event( pt.x , pt.y ); 1477 1478 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event); 1479 if ( processedEvtSetCursor && event.HasCursor() ) 1480 { 1481 cursor = event.GetCursor() ; 1482 } 1483 else 1484 { 1485 1486 // the test for processedEvtSetCursor is here to prevent using m_cursor 1487 // if the user code caught EVT_SET_CURSOR() and returned nothing from 1488 // it - this is a way to say that our cursor shouldn't be used for this 1489 // point 1490 if ( !processedEvtSetCursor && m_cursor.Ok() ) 1491 { 1492 cursor = m_cursor ; 1493 } 1494 if ( wxIsBusy() ) 1495 { 1496 } 1497 else 1498 { 1499 if ( !GetParent() ) 1500 cursor = *wxSTANDARD_CURSOR ; 1501 } 1502 } 1503 if ( cursor.Ok() ) 1504 cursor.MacInstall() ; 1505 } 1506 return cursor.Ok() ; 1507} 1508 1509bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event) 1510{ 1511 if ((event.m_x < m_x) || (event.m_y < m_y) || 1512 (event.m_x > (m_x + m_width)) || (event.m_y > (m_y + m_height))) 1513 return false; 1514 1515 1516 if ( IsKindOf( CLASSINFO ( wxStaticBox ) ) /* || IsKindOf( CLASSINFO( wxSpinCtrl ) ) */) 1517 return false ; 1518 1519 WindowRef window = (WindowRef) MacGetRootWindow() ; 1520 1521 event.m_x -= m_x; 1522 event.m_y -= m_y; 1523 1524 int x = event.m_x ; 1525 int y = event.m_y ; 1526 1527 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1528 { 1529 wxWindowMac *child = node->GetData(); 1530 if ( child->MacGetRootWindow() == (WXWindow) window && child->IsShown() && child->IsEnabled() ) 1531 { 1532 if (child->MacDispatchMouseEvent(event)) 1533 return true; 1534 } 1535 } 1536 1537 wxWindow* cursorTarget = this ; 1538 wxPoint cursorPoint( x , y ) ; 1539 1540 while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) ) 1541 { 1542 cursorTarget = cursorTarget->GetParent() ; 1543 if ( cursorTarget ) 1544 cursorPoint += cursorTarget->GetPosition() ; 1545 } 1546 event.m_x = x ; 1547 event.m_y = y ; 1548 event.SetEventObject( this ) ; 1549 1550 if ( event.GetEventType() == wxEVT_LEFT_DOWN ) 1551 { 1552 // set focus to this window 1553 if (AcceptsFocus() && FindFocus()!=this) 1554 SetFocus(); 1555 } 1556 1557#if wxUSE_TOOLTIPS 1558 if ( event.GetEventType() == wxEVT_MOTION 1559 || event.GetEventType() == wxEVT_ENTER_WINDOW 1560 || event.GetEventType() == wxEVT_LEAVE_WINDOW ) 1561 wxToolTip::RelayEvent( this , event); 1562#endif // wxUSE_TOOLTIPS 1563 1564 if (gs_lastWhich != this) 1565 { 1566 gs_lastWhich = this; 1567 1568 // Double clicks must always occur on the same window 1569 if (event.GetEventType() == wxEVT_LEFT_DCLICK) 1570 event.SetEventType( wxEVT_LEFT_DOWN ); 1571 if (event.GetEventType() == wxEVT_RIGHT_DCLICK) 1572 event.SetEventType( wxEVT_RIGHT_DOWN ); 1573 1574 // Same for mouse up events 1575 if (event.GetEventType() == wxEVT_LEFT_UP) 1576 return true; 1577 if (event.GetEventType() == wxEVT_RIGHT_UP) 1578 return true; 1579 } 1580 1581 GetEventHandler()->ProcessEvent( event ) ; 1582 1583 return true; 1584} 1585 1586wxString wxWindowMac::MacGetToolTipString( wxPoint &pt ) 1587{ 1588 if ( m_tooltip ) 1589 { 1590 return m_tooltip->GetTip() ; 1591 } 1592 return wxEmptyString ; 1593} 1594 1595void wxWindowMac::Update() 1596{ 1597 wxRegion visRgn = MacGetVisibleRegion( false ) ; 1598 int top = 0 , left = 0 ; 1599 MacWindowToRootWindow( &left , &top ) ; 1600 WindowRef rootWindow = (WindowRef) MacGetRootWindow() ; 1601 RgnHandle updateRgn = NewRgn() ; 1602 // getting the update region in macos local coordinates 1603 GetWindowUpdateRgn( rootWindow , updateRgn ) ; 1604 GrafPtr port ; 1605 ::GetPort( &port ) ; 1606 ::SetPort( UMAGetWindowPort( rootWindow ) ) ; 1607 Point pt = {0,0} ; 1608 LocalToGlobal( &pt ) ; 1609 ::SetPort( port ) ; 1610 OffsetRgn( updateRgn , -pt.h , -pt.v ) ; 1611 // translate to window local coordinates 1612 OffsetRgn( updateRgn , -left , -top ) ; 1613 SectRgn( updateRgn , (RgnHandle) visRgn.GetWXHRGN() , updateRgn ) ; 1614 MacRedraw( updateRgn , 0 , true ) ; 1615 // for flushing and validating we need macos-local coordinates again 1616 OffsetRgn( updateRgn , left , top ) ; 1617#if TARGET_API_MAC_CARBON 1618 if ( QDIsPortBuffered( GetWindowPort( rootWindow ) ) ) 1619 { 1620 QDFlushPortBuffer( GetWindowPort( rootWindow ) , updateRgn ) ; 1621 } 1622#endif 1623 ValidWindowRgn( rootWindow , updateRgn ) ; 1624 DisposeRgn( updateRgn ) ; 1625} 1626 1627wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const 1628{ 1629 wxTopLevelWindowMac* win = NULL ; 1630 WindowRef window = (WindowRef) MacGetRootWindow() ; 1631 if ( window ) 1632 { 1633 win = wxFindWinFromMacWindow( (WXWindow) window ) ; 1634 } 1635 return win ; 1636} 1637 1638const wxRegion& wxWindowMac::MacGetVisibleRegion( bool respectChildrenAndSiblings ) 1639{ 1640 RgnHandle visRgn = NewRgn() ; 1641 RgnHandle tempRgn = NewRgn() ; 1642 RgnHandle tempStaticBoxRgn = NewRgn() ; 1643 1644 if ( MacIsReallyShown() ) 1645 { 1646 SetRectRgn( visRgn , 0 , 0 , m_width , m_height ) ; 1647 1648 //TODO : as soon as the new scheme has proven to work correctly, move this to wxStaticBox 1649 if ( IsKindOf( CLASSINFO( wxStaticBox ) ) ) 1650 { 1651 int borderTop = 14 ; 1652 int borderOther = 4 ; 1653 if ( UMAGetSystemVersion() >= 0x1030 ) 1654 borderTop += 2 ; 1655 1656 SetRectRgn( tempStaticBoxRgn , borderOther , borderTop , m_width - borderOther , m_height - borderOther ) ; 1657 DiffRgn( visRgn , tempStaticBoxRgn , visRgn ) ; 1658 } 1659 1660 if ( !IsTopLevel() ) 1661 { 1662 wxWindow* parent = GetParent() ; 1663 while( parent ) 1664 { 1665 wxSize size = parent->GetSize() ; 1666 int x , y ; 1667 x = y = 0 ; 1668 parent->MacWindowToRootWindow( &x, &y ) ; 1669 MacRootWindowToWindow( &x , &y ) ; 1670 1671 SetRectRgn( tempRgn , 1672 x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() , 1673 x + size.x - parent->MacGetRightBorderSize(), 1674 y + size.y - parent->MacGetBottomBorderSize()) ; 1675 1676 SectRgn( visRgn , tempRgn , visRgn ) ; 1677 if ( parent->IsTopLevel() ) 1678 break ; 1679 parent = parent->GetParent() ; 1680 } 1681 } 1682 if ( respectChildrenAndSiblings ) 1683 { 1684 if ( GetWindowStyle() & wxCLIP_CHILDREN ) 1685 { 1686 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1687 { 1688 wxWindowMac *child = node->GetData(); 1689 1690 if ( !child->IsTopLevel() && child->IsShown() ) 1691 { 1692 SetRectRgn( tempRgn , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ; 1693 if ( child->IsKindOf( CLASSINFO( wxStaticBox ) ) ) 1694 { 1695 int borderTop = 14 ; 1696 int borderOther = 4 ; 1697 if ( UMAGetSystemVersion() >= 0x1030 ) 1698 borderTop += 2 ; 1699 1700 SetRectRgn( tempStaticBoxRgn , child->m_x + borderOther , child->m_y + borderTop , child->m_x + child->m_width - borderOther , child->m_y + child->m_height - borderOther ) ; 1701 DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ; 1702 } 1703 DiffRgn( visRgn , tempRgn , visRgn ) ; 1704 } 1705 } 1706 } 1707 1708 if ( (GetWindowStyle() & wxCLIP_SIBLINGS) && GetParent() ) 1709 { 1710 bool thisWindowThrough = false ; 1711 for (wxWindowListNode *node = GetParent()->GetChildren().GetFirst(); node; node = node->GetNext()) 1712 { 1713 wxWindowMac *sibling = node->GetData(); 1714 if ( sibling == this ) 1715 { 1716 thisWindowThrough = true ; 1717 continue ; 1718 } 1719 if( !thisWindowThrough ) 1720 { 1721 continue ; 1722 } 1723 1724 if ( !sibling->IsTopLevel() && sibling->IsShown() ) 1725 { 1726 SetRectRgn( tempRgn , sibling->m_x - m_x , sibling->m_y - m_y , sibling->m_x + sibling->m_width - m_x , sibling->m_y + sibling->m_height - m_y ) ; 1727 if ( sibling->IsKindOf( CLASSINFO( wxStaticBox ) ) ) 1728 { 1729 int borderTop = 14 ; 1730 int borderOther = 4 ; 1731 if ( UMAGetSystemVersion() >= 0x1030 ) 1732 borderTop += 2 ; 1733 1734 SetRectRgn( tempStaticBoxRgn , sibling->m_x - m_x + borderOther , sibling->m_y - m_y + borderTop , sibling->m_x + sibling->m_width - m_x - borderOther , sibling->m_y + sibling->m_height - m_y - borderOther ) ; 1735 DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ; 1736 } 1737 DiffRgn( visRgn , tempRgn , visRgn ) ; 1738 } 1739 } 1740 } 1741 } 1742 } 1743 m_macVisibleRegion = visRgn ; 1744 DisposeRgn( visRgn ) ; 1745 DisposeRgn( tempRgn ) ; 1746 DisposeRgn( tempStaticBoxRgn ) ; 1747 return m_macVisibleRegion ; 1748} 1749 1750void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) 1751{ 1752 RgnHandle updatergn = (RgnHandle) updatergnr ; 1753 // updatergn is always already clipped to our boundaries 1754 // it is in window coordinates, not in client coordinates 1755 1756 WindowRef window = (WindowRef) MacGetRootWindow() ; 1757 1758 { 1759 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates 1760 RgnHandle ownUpdateRgn = NewRgn() ; 1761 CopyRgn( updatergn , ownUpdateRgn ) ; 1762 1763 SectRgn( ownUpdateRgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , ownUpdateRgn ) ; 1764 1765 // newupdate is the update region in client coordinates 1766 RgnHandle newupdate = NewRgn() ; 1767 wxSize point = GetClientSize() ; 1768 wxPoint origin = GetClientAreaOrigin() ; 1769 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ; 1770 SectRgn( newupdate , ownUpdateRgn , newupdate ) ; 1771 OffsetRgn( newupdate , -origin.x , -origin.y ) ; 1772 m_updateRegion = newupdate ; 1773 DisposeRgn( newupdate ) ; // it's been cloned to m_updateRegion 1774 1775 if ( erase && !EmptyRgn(ownUpdateRgn) ) 1776 { 1777 wxWindowDC dc(this); 1778 if (!EmptyRgn(ownUpdateRgn)) 1779 dc.SetClippingRegion(wxRegion(ownUpdateRgn)); 1780 wxEraseEvent eevent( GetId(), &dc ); 1781 eevent.SetEventObject( this ); 1782 GetEventHandler()->ProcessEvent( eevent ); 1783 1784 wxNcPaintEvent eventNc( GetId() ); 1785 eventNc.SetEventObject( this ); 1786 GetEventHandler()->ProcessEvent( eventNc ); 1787 } 1788 DisposeRgn( ownUpdateRgn ) ; 1789 if ( !m_updateRegion.Empty() ) 1790 { 1791 wxWindowList hiddenWindows ; 1792 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1793 { 1794 wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ; 1795 1796 if ( child && child->MacGetRootWindow() == (WXWindow) window && child->IsShown() && child->GetMacControl() ) 1797 { 1798 SetControlVisibility( (ControlHandle) child->GetMacControl() , false , false ) ; 1799 hiddenWindows.Append( child ) ; 1800 } 1801 } 1802 1803 wxPaintEvent event; 1804 event.SetTimestamp(time); 1805 event.SetEventObject(this); 1806 GetEventHandler()->ProcessEvent(event); 1807 1808 for (wxWindowListNode *node = hiddenWindows.GetFirst(); node; node = node->GetNext()) 1809 { 1810 wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ; 1811 1812 if ( child && child->GetMacControl() ) 1813 { 1814 SetControlVisibility( (ControlHandle) child->GetMacControl() , true , false ) ; 1815 } 1816 } 1817 } 1818 } 1819 1820 // now intersect for each of the children their rect with the updateRgn and call MacRedraw recursively 1821 1822 RgnHandle childupdate = NewRgn() ; 1823 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) 1824 { 1825 // calculate the update region for the child windows by intersecting the window rectangle with our own 1826 // passed in update region and then offset it to be client-wise window coordinates again 1827 wxWindowMac *child = node->GetData(); 1828 SetRectRgn( childupdate , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ; 1829 SectRgn( childupdate , updatergn , childupdate ) ; 1830 OffsetRgn( childupdate , -child->m_x , -child->m_y ) ; 1831 if ( child->MacGetRootWindow() == (WXWindow) window && child->IsShown() && !EmptyRgn( childupdate ) ) 1832 { 1833 // because dialogs may also be children 1834 child->MacRedraw( childupdate , time , erase ) ; 1835 } 1836 } 1837 DisposeRgn( childupdate ) ; 1838 // eventually a draw grow box here 1839 1840} 1841 1842WXWindow wxWindowMac::MacGetRootWindow() const 1843{ 1844 wxWindowMac *iter = (wxWindowMac*)this ; 1845 1846 while( iter ) 1847 { 1848 if ( iter->IsTopLevel() ) 1849 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ; 1850 1851 iter = iter->GetParent() ; 1852 } 1853 wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ; 1854 return NULL ; 1855} 1856 1857void wxWindowMac::MacCreateScrollBars( long style ) 1858{ 1859 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; 1860 1861 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ; 1862 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ; 1863 int width, height ; 1864 GetClientSize( &width , &height ) ; 1865 1866 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ; 1867 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ; 1868 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ; 1869 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ; 1870 1871 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint, 1872 vSize , wxVERTICAL); 1873 1874 if ( style & wxVSCROLL ) 1875 { 1876 1877 } 1878 else 1879 { 1880 m_vScrollBar->Show(false) ; 1881 } 1882 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint, 1883 hSize , wxHORIZONTAL); 1884 if ( style & wxHSCROLL ) 1885 { 1886 } 1887 else 1888 { 1889 m_hScrollBar->Show(false) ; 1890 } 1891 1892 // because the create does not take into account the client area origin 1893 MacRepositionScrollBars() ; // we might have a real position shift 1894} 1895 1896void wxWindowMac::MacRepositionScrollBars() 1897{ 1898 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ; 1899 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ; 1900 1901 // get real client area 1902 1903 int width = m_width ; 1904 int height = m_height ; 1905 1906 width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); 1907 height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); 1908 1909 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ; 1910 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ; 1911 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ; 1912 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ; 1913 1914 int x = 0 ; 1915 int y = 0 ; 1916 int w = m_width ; 1917 int h = m_height ; 1918 1919 MacClientToRootWindow( &x , &y ) ; 1920 MacClientToRootWindow( &w , &h ) ; 1921 1922 wxWindowMac *iter = (wxWindowMac*)this ; 1923 1924 int totW = 10000 , totH = 10000; 1925 while( iter ) 1926 { 1927 if ( iter->IsTopLevel() ) 1928 { 1929 totW = iter->m_width ; 1930 totH = iter->m_height ; 1931 break ; 1932 } 1933 1934 iter = iter->GetParent() ; 1935 } 1936 1937 if ( x == 0 ) 1938 { 1939 hPoint.x = -1 ; 1940 hSize.x += 1 ; 1941 } 1942 if ( y == 0 ) 1943 { 1944 vPoint.y = -1 ; 1945 vSize.y += 1 ; 1946 } 1947 1948 if ( w-x >= totW ) 1949 { 1950 hSize.x += 1 ; 1951 vPoint.x += 1 ; 1952 } 1953 1954 if ( h-y >= totH ) 1955 { 1956 vSize.y += 1 ; 1957 hPoint.y += 1 ; 1958 } 1959 1960 if ( m_vScrollBar ) 1961 { 1962 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE); 1963 } 1964 if ( m_hScrollBar ) 1965 { 1966 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE); 1967 } 1968} 1969 1970bool wxWindowMac::AcceptsFocus() const 1971{ 1972 return MacCanFocus() && wxWindowBase::AcceptsFocus(); 1973} 1974 1975WXWidget wxWindowMac::MacGetContainerForEmbedding() 1976{ 1977 return GetParent()->MacGetContainerForEmbedding() ; 1978} 1979 1980void wxWindowMac::MacSuperChangedPosition() 1981{ 1982 // only window-absolute structures have to be moved i.e. controls 1983 1984 wxWindowListNode *node = GetChildren().GetFirst(); 1985 while ( node ) 1986 { 1987 wxWindowMac *child = node->GetData(); 1988 child->MacSuperChangedPosition() ; 1989 node = node->GetNext(); 1990 } 1991} 1992 1993void wxWindowMac::MacTopLevelWindowChangedPosition() 1994{ 1995 // only screen-absolute structures have to be moved i.e. glcanvas 1996 1997 wxWindowListNode *node = GetChildren().GetFirst(); 1998 while ( node ) 1999 { 2000 wxWindowMac *child = node->GetData(); 2001 child->MacTopLevelWindowChangedPosition() ; 2002 node = node->GetNext(); 2003 } 2004} 2005long wxWindowMac::MacGetLeftBorderSize( ) const 2006{ 2007 if( IsTopLevel() ) 2008 return 0 ; 2009 2010 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER ) 2011 { 2012 SInt32 border = 3 ; 2013#if wxMAC_USE_THEME_BORDER 2014#if TARGET_CARBON 2015 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; 2016#endif 2017#endif 2018 return border ; 2019 } 2020 else if ( m_windowStyle &wxDOUBLE_BORDER) 2021 { 2022 SInt32 border = 3 ; 2023#if wxMAC_USE_THEME_BORDER 2024#if TARGET_CARBON 2025 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; 2026#endif 2027#endif 2028 return border ; 2029 } 2030 else if (m_windowStyle &wxSIMPLE_BORDER) 2031 { 2032 return 1 ; 2033 } 2034 return 0 ; 2035} 2036 2037long wxWindowMac::MacGetRightBorderSize( ) const 2038{ 2039 // they are all symmetric in mac themes 2040 return MacGetLeftBorderSize() ; 2041} 2042 2043long wxWindowMac::MacGetTopBorderSize( ) const 2044{ 2045 // they are all symmetric in mac themes 2046 return MacGetLeftBorderSize() ; 2047} 2048 2049long wxWindowMac::MacGetBottomBorderSize( ) const 2050{ 2051 // they are all symmetric in mac themes 2052 return MacGetLeftBorderSize() ; 2053} 2054 2055long wxWindowMac::MacRemoveBordersFromStyle( long style ) 2056{ 2057 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ; 2058} 2059 2060// Find the wxWindowMac at the current mouse position, returning the mouse 2061// position. 2062wxWindowMac* wxFindWindowAtPointer(wxPoint& pt) 2063{ 2064 pt = wxGetMousePosition(); 2065 wxWindowMac* found = wxFindWindowAtPoint(pt); 2066 return found; 2067} 2068 2069// Get the current mouse position. 2070wxPoint wxGetMousePosition() 2071{ 2072 int x, y; 2073 wxGetMousePosition(& x, & y); 2074 return wxPoint(x, y); 2075} 2076 2077void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) 2078{ 2079 if ( event.GetEventType() == wxEVT_RIGHT_DOWN ) 2080 { 2081 // copied from wxGTK : CS 2082 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN 2083 // except that: 2084 // 2085 // (a) it's a command event and so is propagated to the parent 2086 // (b) under MSW it can be generated from kbd too 2087 // (c) it uses screen coords (because of (a)) 2088 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, 2089 this->GetId(), 2090 this->ClientToScreen(event.GetPosition())); 2091 if ( ! GetEventHandler()->ProcessEvent(evtCtx) ) 2092 event.Skip() ; 2093 } 2094 else 2095 { 2096 event.Skip() ; 2097 } 2098} 2099