]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/window.mm
add maps for the old/new names
[wxWidgets.git] / src / cocoa / window.mm
CommitLineData
fb896a32
DE
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/cocoa/window.mm
3// Purpose: wxWindowCocoa
4// Author: David Elliott
5// Modified by:
6// Created: 2002/12/26
7// RCS-ID: $Id:
8// Copyright: (c) 2002 David Elliott
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/window.h"
13#include "wx/log.h"
14
7fc77f30
DE
15#include "wx/cocoa/autorelease.h"
16
fb896a32 17#import <Appkit/NSView.h>
69dbb709 18#import <AppKit/NSEvent.h>
fb896a32 19
a82b8141
DE
20// ========================================================================
21// wxWindowCocoaHider
22// ========================================================================
23class wxWindowCocoaHider: protected wxCocoaNSView
24{
25 DECLARE_NO_COPY_CLASS(wxWindowCocoaHider)
26public:
27 wxWindowCocoaHider(wxWindow *owner);
28 virtual ~wxWindowCocoaHider();
29 inline WX_NSView GetNSView() { return m_dummyNSView; }
30protected:
31 wxWindowCocoa *m_owner;
32 WX_NSView m_dummyNSView;
33 virtual void Cocoa_FrameChanged(void);
34private:
35 wxWindowCocoaHider();
36};
37
38// ========================================================================
39// wxWindowCocoaHider
40// ========================================================================
41wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
42: m_owner(owner)
43{
44 wxASSERT(owner);
45 wxASSERT(owner->GetNSViewForHiding());
46 m_dummyNSView = [[NSView alloc]
47 initWithFrame:[owner->GetNSViewForHiding() frame]];
48 AssociateNSView(m_dummyNSView);
49}
50
51wxWindowCocoaHider::~wxWindowCocoaHider()
52{
53 DisassociateNSView(m_dummyNSView);
54 [m_dummyNSView release];
55}
56
57void wxWindowCocoaHider::Cocoa_FrameChanged(void)
58{
59 // Keep the real window in synch with the dummy
60 wxASSERT(m_dummyNSView);
61 [m_owner->GetNSViewForHiding() setFrame:[m_dummyNSView frame]];
62}
63
64// ========================================================================
65// wxWindowCocoa
66// ========================================================================
fb896a32
DE
67// normally the base classes aren't included, but wxWindow is special
68#ifdef __WXUNIVERSAL__
69IMPLEMENT_ABSTRACT_CLASS(wxWindowCocoa, wxWindowBase)
70#else
71IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
72#endif
73
74BEGIN_EVENT_TABLE(wxWindowCocoa, wxWindowBase)
75END_EVENT_TABLE()
76
b9505233
DE
77wxWindow *wxWindowCocoa::sm_capturedWindow = NULL;
78
fb896a32
DE
79// Constructor
80void wxWindowCocoa::Init()
81{
82 InitBase();
83
84 m_cocoaNSView = NULL;
a82b8141 85 m_cocoaHider = NULL;
fb896a32 86 m_isBeingDeleted = FALSE;
55c5be5e 87 m_isInPaint = FALSE;
fb896a32
DE
88}
89
90// Constructor
91bool wxWindow::Create(wxWindow *parent, wxWindowID winid,
92 const wxPoint& pos,
93 const wxSize& size,
94 long style,
95 const wxString& name)
96{
97 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
98 return false;
99
100 // TODO: create the window
fb896a32 101 m_cocoaNSView = NULL;
d139c3a8 102 SetNSView([[NSView alloc] initWithFrame: MakeDefaultNSRect(size)]);
fb896a32
DE
103 [m_cocoaNSView release];
104
105 if (m_parent)
106 {
107 m_parent->AddChild(this);
108 m_parent->CocoaAddChild(this);
109 }
d139c3a8 110 SetInitialFrameRect(pos,size);
fb896a32
DE
111
112 return TRUE;
113}
114
115// Destructor
116wxWindow::~wxWindow()
117{
7fc77f30 118 wxAutoNSAutoreleasePool pool;
fb896a32
DE
119 DestroyChildren();
120
121 if(m_parent)
122 m_parent->RemoveChild(this);
123
124 CocoaRemoveFromParent();
a82b8141 125 delete m_cocoaHider;
fb896a32
DE
126 SetNSView(NULL);
127}
128
129void wxWindowCocoa::CocoaAddChild(wxWindowCocoa *child)
130{
a82b8141
DE
131 NSView *childView = child->GetNSViewForSuperview();
132
133 wxASSERT(childView);
134 [m_cocoaNSView addSubview: childView];
135 child->m_isShown = !m_cocoaHider;
fb896a32
DE
136}
137
138void wxWindowCocoa::CocoaRemoveFromParent(void)
139{
a82b8141 140 [GetNSViewForSuperview() removeFromSuperview];
fb896a32
DE
141}
142
143void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
144{
145 bool need_debug = cocoaNSView || m_cocoaNSView;
146 if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [m_cocoaNSView=%p retainCount]=%d",this,m_cocoaNSView,[m_cocoaNSView retainCount]);
bac6f234 147 DisassociateNSView(m_cocoaNSView);
fb896a32
DE
148 [cocoaNSView retain];
149 [m_cocoaNSView release];
150 m_cocoaNSView = cocoaNSView;
bac6f234 151 AssociateNSView(m_cocoaNSView);
fb896a32
DE
152 if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d",this,cocoaNSView,[cocoaNSView retainCount]);
153}
154
a82b8141
DE
155WX_NSView wxWindowCocoa::GetNSViewForSuperview() const
156{
157 return m_cocoaHider
158 ? m_cocoaHider->GetNSView()
159 : m_cocoaNSView;
160}
161
162WX_NSView wxWindowCocoa::GetNSViewForHiding() const
163{
164 return m_cocoaNSView;
165}
166
8ea5271e
DE
167bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
168{
169 wxLogDebug("Cocoa_drawRect");
55c5be5e
DE
170 // Recursion can happen if the event loop runs from within the paint
171 // handler. For instance, if an assertion dialog is shown.
172 // FIXME: This seems less than ideal.
173 if(m_isInPaint)
174 {
175 wxLogDebug("Paint event recursion!");
176 return false;
177 }
8ea5271e 178 //FIXME: should probably turn that rect into the update region
55c5be5e 179 m_isInPaint = TRUE;
8ea5271e
DE
180 wxPaintEvent event(m_windowId);
181 event.SetEventObject(this);
55c5be5e
DE
182 bool ret = GetEventHandler()->ProcessEvent(event);
183 m_isInPaint = FALSE;
184 return ret;
8ea5271e
DE
185}
186
69dbb709
DE
187void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent)
188{
a82b8141
DE
189 wxASSERT_MSG([m_cocoaNSView window]==[cocoaEvent window],"Mouse event for different NSWindow");
190 NSPoint cocoaPoint = [m_cocoaNSView convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil];
191 NSRect cocoaRect = [m_cocoaNSView frame];
69dbb709
DE
192 const wxPoint &clientorigin = GetClientAreaOrigin();
193 event.m_x = (wxCoord)cocoaPoint.x - clientorigin.x;
194 event.m_y = (wxCoord)(cocoaRect.size.height - cocoaPoint.y) - clientorigin.y;
195
196 event.m_shiftDown = [cocoaEvent modifierFlags] & NSShiftKeyMask;
197 event.m_controlDown = [cocoaEvent modifierFlags] & NSControlKeyMask;
198 event.m_altDown = [cocoaEvent modifierFlags] & NSAlternateKeyMask;
199 event.m_metaDown = [cocoaEvent modifierFlags] & NSCommandKeyMask;
200
201 // TODO: set timestamp?
202 event.SetEventObject(this);
203 event.SetId(GetId());
204}
205
206bool wxWindowCocoa::Cocoa_mouseMoved(WX_NSEvent theEvent)
207{
208 wxMouseEvent event(wxEVT_MOTION);
209 InitMouseEvent(event,theEvent);
210 wxLogDebug("Mouse Drag @%d,%d",event.m_x,event.m_y);
211 return GetEventHandler()->ProcessEvent(event);
212}
213
214bool wxWindowCocoa::Cocoa_mouseEntered(WX_NSEvent theEvent)
215{
216 return false;
217}
218
219bool wxWindowCocoa::Cocoa_mouseExited(WX_NSEvent theEvent)
220{
221 return false;
222}
223
224bool wxWindowCocoa::Cocoa_mouseDown(WX_NSEvent theEvent)
225{
226 wxMouseEvent event([theEvent clickCount]<2?wxEVT_LEFT_DOWN:wxEVT_LEFT_DCLICK);
227 InitMouseEvent(event,theEvent);
228 wxLogDebug("Mouse Down @%d,%d num clicks=%d",event.m_x,event.m_y,[theEvent clickCount]);
229 return GetEventHandler()->ProcessEvent(event);
230}
231
232bool wxWindowCocoa::Cocoa_mouseDragged(WX_NSEvent theEvent)
233{
234 wxMouseEvent event(wxEVT_MOTION);
235 InitMouseEvent(event,theEvent);
236 event.m_leftDown = true;
237 wxLogDebug("Mouse Drag @%d,%d",event.m_x,event.m_y);
238 return GetEventHandler()->ProcessEvent(event);
239}
240
241bool wxWindowCocoa::Cocoa_mouseUp(WX_NSEvent theEvent)
242{
243 wxMouseEvent event(wxEVT_LEFT_UP);
244 InitMouseEvent(event,theEvent);
245 wxLogDebug("Mouse Up @%d,%d",event.m_x,event.m_y);
246 return GetEventHandler()->ProcessEvent(event);
247}
248
249bool wxWindowCocoa::Cocoa_rightMouseDown(WX_NSEvent theEvent)
250{
251 return false;
252}
253
254bool wxWindowCocoa::Cocoa_rightMouseDragged(WX_NSEvent theEvent)
255{
256 return false;
257}
258
259bool wxWindowCocoa::Cocoa_rightMouseUp(WX_NSEvent theEvent)
260{
261 return false;
262}
263
264bool wxWindowCocoa::Cocoa_otherMouseDown(WX_NSEvent theEvent)
265{
266 return false;
267}
268
269bool wxWindowCocoa::Cocoa_otherMouseDragged(WX_NSEvent theEvent)
270{
271 return false;
272}
273
274bool wxWindowCocoa::Cocoa_otherMouseUp(WX_NSEvent theEvent)
275{
276 return false;
277}
278
fb896a32
DE
279void wxWindowCocoa::Cocoa_FrameChanged(void)
280{
281 wxLogDebug("Cocoa_FrameChanged");
282 wxSizeEvent event(GetSize(), m_windowId);
283 event.SetEventObject(this);
284 GetEventHandler()->ProcessEvent(event);
285}
286
287bool wxWindow::Close(bool force)
288{
289 return false;
290}
291
a82b8141
DE
292void wxWindow::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
293{
294 [[oldView superview] replaceSubview:oldView with:newView];
295}
296
fb896a32
DE
297bool wxWindow::Show(bool show)
298{
7fc77f30 299 wxAutoNSAutoreleasePool pool;
fb896a32
DE
300 // If the window is marked as visible, then it shouldn't have a dummy view
301 // If the window is marked hidden, then it should have a dummy view
addbdd29
DE
302 // wxSpinCtrl (generic) abuses m_isShown, don't use it for any logic
303// wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),"wxWindow: m_isShown does not agree with m_dummyNSView");
fb896a32 304 // Return false if there isn't a window to show or hide
a82b8141
DE
305 NSView *cocoaView = GetNSViewForHiding();
306 if(!cocoaView)
fb896a32 307 return false;
fb896a32
DE
308 if(show)
309 {
addbdd29 310 // If state isn't changing, return false
a82b8141 311 if(!m_cocoaHider)
addbdd29 312 return false;
a82b8141
DE
313 CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
314 wxASSERT(![m_cocoaHider->GetNSView() superview]);
315 delete m_cocoaHider;
316 m_cocoaHider = NULL;
317 wxASSERT([cocoaView superview]);
fb896a32
DE
318 }
319 else
320 {
addbdd29 321 // If state isn't changing, return false
a82b8141 322 if(m_cocoaHider)
addbdd29 323 return false;
a82b8141
DE
324 m_cocoaHider = new wxWindowCocoaHider(this);
325 // NOTE: replaceSubview:with will cause m_cocaNSView to be
326 // (auto)released which balances out addSubview
327 CocoaReplaceView(cocoaView, m_cocoaHider->GetNSView());
fb896a32 328 // m_coocaNSView is now only retained by us
a82b8141
DE
329 wxASSERT([m_cocoaHider->GetNSView() superview]);
330 wxASSERT(![cocoaView superview]);
fb896a32 331 }
a6b4ff2e
DE
332 m_isShown = show;
333 return true;
fb896a32
DE
334}
335
336void wxWindowCocoa::DoSetSize(int x, int y, int width, int height, int sizeFlags)
337{
ddf7346a 338// wxLogDebug("wxWindow=%p::DoSetSizeWindow(%d,%d,%d,%d,Auto: %s%s)",this,x,y,width,height,(sizeFlags&wxSIZE_AUTO_WIDTH)?"W":".",sizeFlags&wxSIZE_AUTO_HEIGHT?"H":".");
fb896a32
DE
339 int currentX, currentY;
340 int currentW, currentH;
341 DoGetPosition(&currentX, &currentY);
342 DoGetSize(&currentW, &currentH);
343 if((x==-1) && !(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
344 x=currentX;
345 if((y==-1) && !(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
346 y=currentY;
347
348 AdjustForParentClientOrigin(x,y,sizeFlags);
349
350 wxSize size(-1,-1);
351
352 if((width==-1)&&!(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
353 {
354 if(sizeFlags&wxSIZE_AUTO_WIDTH)
355 {
356 size=DoGetBestSize();
357 width=size.x;
358 }
359 else
360 width=currentW;
361 }
362 if((height==-1)&&!(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
363 {
364 if(sizeFlags&wxSIZE_AUTO_HEIGHT)
365 {
366 if(size.x==-1)
367 size=DoGetBestSize();
368 height=size.y;
369 }
370 else
371 height=currentH;
372 }
373 DoMoveWindow(x,y,width,height);
374}
375
376void wxWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
377{
ddf7346a 378// wxLogDebug("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
fb896a32 379
a82b8141 380 NSView *nsview = GetNSViewForSuperview();
d449cf47 381 NSView *superview = [nsview superview];
fb896a32
DE
382 wxCHECK_RET(superview,"NSView does not have a superview");
383 NSRect parentRect = [superview frame];
384
385 NSRect cocoaRect = NSMakeRect(x,parentRect.size.height-(y+height),width,height);
a82b8141 386 [nsview setFrame: cocoaRect];
fb896a32
DE
387}
388
d139c3a8
DE
389void wxWindowCocoa::SetInitialFrameRect(const wxPoint& pos, const wxSize& size)
390{
391 NSView *nsview = GetNSViewForSuperview();
392 NSView *superview = [nsview superview];
393 wxCHECK_RET(superview,"NSView does not have a superview");
394 NSRect parentRect = [superview frame];
395 NSRect frameRect = [nsview frame];
396 if(size.x!=-1)
397 frameRect.size.width = size.x;
398 if(size.y!=-1)
399 frameRect.size.height = size.y;
400 frameRect.origin.x = pos.x;
401 frameRect.origin.y = parentRect.size.height-(pos.y+size.y);
402 [nsview setFrame: frameRect];
403}
404
fb896a32
DE
405// Get total size
406void wxWindow::DoGetSize(int *w, int *h) const
407{
a82b8141 408 NSRect cocoaRect = [GetNSViewForSuperview() frame];
fb896a32
DE
409 if(w)
410 *w=(int)cocoaRect.size.width;
411 if(h)
412 *h=(int)cocoaRect.size.height;
ddf7346a 413// wxLogDebug("wxWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
fb896a32
DE
414}
415
416void wxWindow::DoGetPosition(int *x, int *y) const
417{
a82b8141 418 NSView *nsview = GetNSViewForSuperview();
576a1544 419 NSView *superview = [nsview superview];
fb896a32
DE
420 wxCHECK_RET(superview,"NSView does not have a superview");
421 NSRect parentRect = [superview frame];
422
576a1544 423 NSRect cocoaRect = [nsview frame];
fb896a32
DE
424 if(x)
425 *x=(int)cocoaRect.origin.x;
426 if(y)
427 *y=(int)(parentRect.size.height-(cocoaRect.origin.y+cocoaRect.size.height));
ddf7346a 428// wxLogDebug("wxWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
fb896a32
DE
429}
430
431WXWidget wxWindow::GetHandle() const
432{
433 return m_cocoaNSView;
434}
435
ddf7346a
DE
436void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
437{
438 [m_cocoaNSView setNeedsDisplay:YES];
439}
440
fb896a32
DE
441void wxWindow::SetFocus()
442{
443 // TODO
444}
445
446void wxWindow::DoCaptureMouse()
447{
448 // TODO
b9505233 449 sm_capturedWindow = this;
fb896a32
DE
450}
451
452void wxWindow::DoReleaseMouse()
453{
454 // TODO
b9505233 455 sm_capturedWindow = NULL;
fb896a32
DE
456}
457
458void wxWindow::DoScreenToClient(int *x, int *y) const
459{
460 // TODO
461}
462
463void wxWindow::DoClientToScreen(int *x, int *y) const
464{
465 // TODO
466}
467
468// Get size *available for subwindows* i.e. excluding menu bar etc.
469void wxWindow::DoGetClientSize(int *x, int *y) const
470{
471 wxLogDebug("DoGetClientSize:");
472 wxWindowCocoa::DoGetSize(x,y);
473 // TODO: Actually account for menubar, borders, etc...
474}
475
476void wxWindow::DoSetClientSize(int width, int height)
477{
478 wxLogDebug("DoSetClientSize=(%d,%d)",width,height);
479 // TODO
480}
481
482int wxWindow::GetCharHeight() const
483{
484 // TODO
485 return 0;
486}
487
488int wxWindow::GetCharWidth() const
489{
490 // TODO
491 return 0;
492}
493
494void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
495 int *descent, int *externalLeading, const wxFont *theFont) const
496{
497 // TODO
498}
499
fb896a32
DE
500// Coordinates relative to the window
501void wxWindow::WarpPointer (int x_pos, int y_pos)
502{
503 // TODO
504}
505
506int wxWindow::GetScrollPos(int orient) const
507{
508 // TODO
509 return 0;
510}
511
512// This now returns the whole range, not just the number
513// of positions that we can scroll.
514int wxWindow::GetScrollRange(int orient) const
515{
516 // TODO
517 return 0;
518}
519
520int wxWindow::GetScrollThumb(int orient) const
521{
522 // TODO
523 return 0;
524}
525
526void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
527{
528 // TODO
529}
530
531// New function that will replace some of the above.
532void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
533 int range, bool refresh)
534{
535 // TODO
536}
537
538// Does a physical scroll
539void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
540{
541 // TODO
542}
543
544bool wxWindow::SetFont(const wxFont& font)
545{
546 // TODO
547 return TRUE;
548}
549
4328a6ba
DE
550static int CocoaRaiseWindowCompareFunction(id first, id second, void *target)
551{
552 // first should be ordered higher
553 if(first==target)
554 return NSOrderedDescending;
555 // second should be ordered higher
556 if(second==target)
557 return NSOrderedAscending;
558 return NSOrderedSame;
559}
560
fb896a32
DE
561// Raise the window to the top of the Z order
562void wxWindow::Raise()
563{
4328a6ba 564// wxAutoNSAutoreleasePool pool;
a82b8141 565 NSView *nsview = GetNSViewForSuperview();
4328a6ba
DE
566 [[nsview superview] sortSubviewsUsingFunction:
567 CocoaRaiseWindowCompareFunction
568 context: nsview];
569}
570
571static int CocoaLowerWindowCompareFunction(id first, id second, void *target)
572{
573 // first should be ordered lower
574 if(first==target)
575 return NSOrderedAscending;
576 // second should be ordered lower
577 if(second==target)
578 return NSOrderedDescending;
579 return NSOrderedSame;
fb896a32
DE
580}
581
582// Lower the window to the bottom of the Z order
583void wxWindow::Lower()
584{
4328a6ba
DE
585 NSView *nsview = GetNSViewForSuperview();
586 [[nsview superview] sortSubviewsUsingFunction:
587 CocoaLowerWindowCompareFunction
588 context: nsview];
fb896a32
DE
589}
590
591bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
592{
593 return FALSE;
594}
595
596// Get the window with the focus
597wxWindow *wxWindowBase::FindFocus()
598{
599 // TODO
600 return NULL;
601}
602
603/* static */ wxWindow *wxWindowBase::GetCapture()
604{
605 // TODO
b9505233 606 return wxWindowCocoa::sm_capturedWindow;
fb896a32
DE
607}
608
609wxWindow *wxGetActiveWindow()
610{
611 // TODO
612 return NULL;
613}
614
7c9428ab
DE
615wxPoint wxGetMousePosition()
616{
617 // TODO
618 return wxDefaultPosition;
619}
620
621wxWindow* wxFindWindowAtPointer(wxPoint& pt)
622{
623 pt = wxGetMousePosition();
624 return NULL;
625}
626