wxRectTracker
RectTracker.cpp
Go to the documentation of this file.
00001 /* ****************************************************************************
00002  * RectTracker.cpp                                                            *
00003  *                                                                            *
00004  * (c) 2004-2008 - Rémi Peyronnet <remi+rphoto@via.ecp.fr>                    *
00005  *                                                                            *
00006  * RectTracker was originally designed for RPhoto, but can be used separately *
00007  * It is a control similar to the CRectTracker of MS MFC.                     *
00008  *                                                                            *
00009  * Licence : wxWindows (based on L-GPL)                                       *
00010  *                                                                            *
00011  * ************************************************************************** */
00012 
00013 #include "RectTracker.h"
00014 
00015 IMPLEMENT_CLASS(wxRectTracker, wxEvtHandler)
00016 
00017 static const wxRect NullRect(0, 0, -1, -1);
00018 
00019 wxRectTracker::wxRectTracker(wxWindow* wnd, wxFrame* frame) : 
00020     wxEvtHandler(), m_wnd(wnd), m_frame(frame)
00021 {
00022     m_iHandlerWidth = 5;
00023     m_cursorMove = new wxCursor(wxCURSOR_SIZING);
00024     m_state = 0;
00025     m_Rect = m_maxRect = NullRect;
00026     m_iHandlerMask = RT_MASK_ALL;
00027     if (wnd) wnd->PushEventHandler(this);
00028 }
00029 
00030 wxRectTracker::~wxRectTracker()
00031 {
00032     if (m_wnd) m_wnd->RemoveEventHandler(this);
00033     delete m_cursorMove;
00034 }
00035 
00036 BEGIN_EVENT_TABLE(wxRectTracker, wxEvtHandler)
00037    EVT_PAINT(wxRectTracker::OnPaint)
00038    EVT_MOTION(wxRectTracker::OnMouseMotion)
00039    EVT_LEFT_DOWN(wxRectTracker::OnMouseLeftDown)
00040    EVT_LEFT_UP(wxRectTracker::OnMouseLeftUp)
00041    EVT_CHAR(wxRectTracker::OnKey)
00042 END_EVENT_TABLE()
00043 
00044 const wxEventType wxEVT_TRACKER_CHANGED = wxNewEventType();
00045 const wxEventType wxEVT_TRACKER_CHANGING = wxNewEventType();
00046 
00047 void wxRectTracker::OnPaint(wxPaintEvent& event)
00048 {
00049     this->GetNextHandler()->ProcessEvent(event);
00050     wxClientDC dc(m_wnd);
00051     if (wxDynamicCast(m_wnd,wxScrolledWindow))
00052     {
00053         wxDynamicCast(m_wnd,wxScrolledWindow)->DoPrepareDC(dc);
00054     }   
00055     OnDraw(&dc);
00056 }
00057 
00058 void wxRectTracker::OnDraw(wxDC* dc)
00059 {
00060    if ((m_state & RT_STATE_DISABLED) != 0) return;
00061    int w = m_Rect.width, h = m_Rect.height;
00062    if ((w >=0) && (h >= 0)) DrawRect(*dc, m_Rect.GetLeft(), m_Rect.GetTop(), w, h);
00063 }
00064 
00065 // DrawRect operates with a wxPaintDC => Window coordinates
00066 void wxRectTracker::DrawRect(wxDC & dc, int x, int y, int w, int h)
00067 {
00068     // Rect
00069     dc.SetBrush(*wxTRANSPARENT_BRUSH);
00070     dc.SetPen(*wxBLACK_PEN);
00071     dc.DrawRectangle(x,y,w,h);
00072     dc.SetPen(wxPen(*wxWHITE,1,wxDOT));
00073     dc.DrawRectangle(x,y,w,h);
00074 
00075     // Handlers
00076     int z = m_iHandlerWidth;
00077     if (m_iHandlerMask != RT_MASK_NONE)
00078     {
00079         dc.SetBrush(*wxBLACK_BRUSH);
00080         dc.SetPen(*wxBLACK_PEN);
00081         
00082         if (m_iHandlerMask & RT_MASK_TOP_LEFT) dc.DrawRectangle(x+1    , y+1    , z, z);
00083         if (m_iHandlerMask & RT_MASK_TOP_RIGHT) dc.DrawRectangle(x-1+w-z, y+1    , z, z);
00084         if (m_iHandlerMask & RT_MASK_BOTTOM_LEFT) dc.DrawRectangle(x+1    , y-1+h-z, z, z);
00085         if (m_iHandlerMask & RT_MASK_BOTTOM_RIGHT) dc.DrawRectangle(x-1+w-z, y-1+h-z, z, z);
00086         
00087         if (m_iHandlerMask & RT_MASK_TOP_MID) dc.DrawRectangle(x+(w-z)/2, y+1    , z, z);
00088         if (m_iHandlerMask & RT_MASK_BOTTOM_MID) dc.DrawRectangle(x+(w-z)/2, y+h-z-1, z, z);
00089         if (m_iHandlerMask & RT_MASK_MID_LEFT) dc.DrawRectangle(x+1    , y+(h-z)/2, z, z);
00090         if (m_iHandlerMask & RT_MASK_MID_RIGHT) dc.DrawRectangle(x+w-z-1, y+(h-z)/2, z, z);
00091     }       
00092 }
00093 
00094 void wxRectTracker::DrawRect(wxDC & dc, wxRect rect)
00095 {
00096     DrawRect(dc, rect.x, rect.y, rect.width, rect.height);
00097 }
00098 
00099 // DrawTracker operates with the parent's wxWindowDC => Parent coordinates
00100 void wxRectTracker::DrawTracker(wxDC & dc, int x, int y, int w, int h)
00101 {
00102     // Convert coordinates if scrolled
00103     if (wxDynamicCast(m_wnd,wxScrolledWindow) != NULL)
00104     {
00105         wxDynamicCast(m_wnd,wxScrolledWindow)->CalcScrolledPosition(x, y, &x, &y);
00106     }
00107     // Inverted Rect
00108     dc.SetLogicalFunction(wxINVERT);
00109     dc.SetBrush(*wxTRANSPARENT_BRUSH);
00110     dc.SetPen(*wxGREY_PEN);
00111     dc.DrawRectangle(x,y,w,h);
00112     dc.SetLogicalFunction(wxCOPY);
00113 }
00114 
00115 void wxRectTracker::DrawTracker(wxDC & dc, const wxRect& rect)
00116 {
00117     DrawTracker(dc, rect.x, rect.y, rect.width, rect.height);
00118 }
00119 
00120 
00121 void wxRectTracker::OnKey(wxKeyEvent & event)
00122 {
00123     if ( ((m_state & RT_STATE_DISABLED) != 0) || !IsShown()) { event.Skip(); return; } 
00124     
00125     int incr = 0, dx = 0, dy = 0;
00126     int handler;
00127     wxRect tmpRect;
00128     tmpRect = GetUnscrolledRect();
00129 
00130     if ((tmpRect.width <= 0) || (tmpRect.height <= 0)) { event.Skip(); return; } 
00131     
00132     if (event.ControlDown()) incr = 10; else incr = 1;
00133 
00134     switch(event.GetKeyCode())
00135     {
00136     case WXK_ESCAPE :
00137             if ((m_state & RT_STATE_MOUSE_CAPTURED) != 0)
00138             {
00139                 m_wnd->ReleaseMouse();
00140                 m_state ^= RT_STATE_MOUSE_CAPTURED;
00141                 Update();
00142             }
00143             else
00144             {
00145                 Hide();
00146             }
00147             break;
00148     case WXK_LEFT   : dx -= incr; break;
00149     case WXK_UP     : dy -= incr; break;
00150     case WXK_RIGHT  : dx += incr; break;
00151     case WXK_DOWN   : dy += incr; break;
00152     default:
00153         event.Skip();
00154     }
00155 
00156     if ((dx != 0) || (dy != 0))
00157     {
00158         if (event.ShiftDown())
00159         {
00160             tmpRect.width += dx;
00161             tmpRect.height += dy;
00162             handler = (dx == 0)?RT_HANDLER_BOTTOM_MID:RT_HANDLER_MID_RIGHT;
00163         }
00164         else
00165         {
00166             tmpRect.x += dx;
00167             tmpRect.y += dy;
00168             handler = 0;
00169         }
00170         AdjustTrackerRect(tmpRect, handler);
00171         SetUnscrolledRect(tmpRect);
00172         Update();
00173     }
00174 
00175 }
00176 
00177 void wxRectTracker::OnMouseMotion(wxMouseEvent & event)
00178 {
00179     int hit;
00180     int dx, dy;
00181 
00182     if ((m_state & RT_STATE_DISABLED) != 0) return;
00183 
00184     wxMouseEvent mouse(event);
00185 
00186     if (wxDynamicCast(m_wnd,wxScrolledWindow))
00187     {
00188         wxDynamicCast(m_wnd,wxScrolledWindow)->CalcUnscrolledPosition(mouse.m_x, mouse.m_y, &mouse.m_x, &mouse.m_y);
00189     }
00190     
00191     if (m_frame && IsShown())
00192     {
00193         m_frame->SetStatusText(wxString::Format(_("Mouse position : %d, %d / RectSize : %d,%d->%d,%d(+%d,%d)"),
00194                 event.m_x, event.m_y, 
00195                 m_Rect.GetLeft(), m_Rect.GetTop(), m_Rect.GetRight(), m_Rect.GetBottom(), m_Rect.GetWidth(), m_Rect.GetHeight()));
00196     }
00197     
00198     // Just moving ?
00199     if (!event.Dragging())
00200     {
00201         hit = HitTest(mouse.m_x, mouse.m_y);
00202         switch (hit)
00203         {
00204         case RT_HANDLER_TOP_MID:
00205         case RT_HANDLER_BOTTOM_MID:
00206             m_wnd->SetCursor(wxCursor(wxCURSOR_SIZENS));
00207             break;
00208         case RT_HANDLER_MID_LEFT:
00209         case RT_HANDLER_MID_RIGHT:
00210             m_wnd->SetCursor(wxCursor(wxCURSOR_SIZEWE));
00211             break;
00212         case RT_HANDLER_TOP_LEFT:
00213         case RT_HANDLER_BOTTOM_RIGHT:
00214             m_wnd->SetCursor(wxCursor(wxCURSOR_SIZENWSE));
00215             break;
00216         case RT_HANDLER_TOP_RIGHT:
00217         case RT_HANDLER_BOTTOM_LEFT:
00218             m_wnd->SetCursor(wxCursor(wxCURSOR_SIZENESW));
00219             break;
00220         case RT_HANDLER_NONE:
00221             m_wnd->SetCursor(wxCursor(wxCURSOR_HAND /* *m_cursorMove */));
00222             break;
00223         case RT_HANDLER_OUTSIDE:
00224             m_wnd->SetCursor(wxCursor(wxCURSOR_ARROW));
00225             break;
00226         default:
00227             m_wnd->SetCursor(wxCursor(wxCURSOR_ARROW));
00228         }
00229     }
00230     else if ((m_state & RT_STATE_DRAGGING))
00231     {
00232         // Dragging
00233 
00234         wxASSERT(m_wnd!=NULL);
00235 
00236         // Drawing Tracker Rect
00237         wxClientDC dc(m_wnd);
00238         if (wxDynamicCast(m_wnd,wxScrolledWindow))
00239         {
00240             wxDynamicCast(m_wnd,wxScrolledWindow)->DoPrepareDC(dc);
00241         } 
00242 
00243         dx = 0; dy = 0;
00244         dc.SetDeviceOrigin(dx, dy);
00245 
00246 
00247         if ((m_state & RT_STATE_FIRSTDRAG) == 0)
00248         {
00249             m_state |= RT_STATE_FIRSTDRAG;
00250         }
00251         else
00252         {
00253             // Erase previous Tracker
00254             DrawTracker(dc, m_prevRect);
00255         }
00256 
00257         // Update the new position
00258         // - Which Tracker ?
00259         hit = HitTest(m_leftClick.x, m_leftClick.y);
00260         // - Default Rect values
00261         if (hit != RT_HANDLER_OUTSIDE) 
00262         {
00263             m_curRect = GetUnscrolledRect();
00264         }
00265         else
00266         {
00267             m_curRect = wxRect(m_leftClick, m_leftClick);
00268             hit = RT_HANDLER_BOTTOM_RIGHT;
00269         }
00270         
00271         dx = (mouse.m_x - m_leftClick.x);
00272         dy = (mouse.m_y - m_leftClick.y);
00273 
00274         if (hit == RT_HANDLER_OUTSIDE)
00275         {
00276             m_curRect.width += dx;
00277             m_curRect.height += dy;
00278         }
00279         else    if (hit == RT_HANDLER_NONE)
00280         {
00281             m_curRect.x += dx;
00282             m_curRect.y += dy;
00283         }
00284         else
00285         {
00286             // Use bit combination of handler values to update position
00287             if ( (hit & RT_HANDLER_MID_RIGHT) != 0)
00288             {
00289                 m_curRect.width += dx;
00290             }
00291             if ( (hit & RT_HANDLER_BOTTOM_MID) != 0)
00292             {
00293                 m_curRect.height += dy;
00294             }
00295             if ( (hit & RT_HANDLER_MID_LEFT) != 0)
00296             {
00297                 m_curRect.x += dx;
00298                 m_curRect.width -= dx;
00299             }
00300             if ( (hit & RT_HANDLER_TOP_MID) != 0)
00301             {
00302                 m_curRect.y += dy;
00303                 m_curRect.height -= dy;
00304             }
00305         }
00306         if (m_frame)
00307         {
00308             m_frame->SetStatusText(wxString::Format(_("Mouse click : %d, %d / Hit : %d / RectSize : %d,%d->%d,%d(+%d,%d)"),
00309                 m_leftClick.x, m_leftClick.y, 
00310                 hit,
00311                 m_Rect.GetLeft(), m_Rect.GetTop(), m_Rect.GetRight(), m_Rect.GetBottom(), m_Rect.GetWidth(), m_Rect.GetHeight()));
00312         }
00313         // Correct Orientation (size and virtual handler)
00314         if (m_curRect.width < 0) 
00315         { 
00316             m_curRect.width = - m_curRect.width; 
00317             m_curRect.x -= m_curRect.width; 
00318             if ((hit & RT_HANDLER_MID_LEFT) != 0) hit = (hit ^ RT_HANDLER_MID_LEFT) | RT_HANDLER_MID_RIGHT;
00319             else if ((hit & RT_HANDLER_MID_RIGHT) != 0) hit = (hit ^ RT_HANDLER_MID_RIGHT) | RT_HANDLER_MID_LEFT;
00320         }
00321         if (m_curRect.height < 0) 
00322         { 
00323             m_curRect.height = - m_curRect.height; 
00324             m_curRect.y -= m_curRect.height; 
00325             if ((hit & RT_HANDLER_TOP_MID) != 0) hit = (hit ^ RT_HANDLER_TOP_MID) | RT_HANDLER_BOTTOM_MID;
00326             else if ((hit & RT_HANDLER_BOTTOM_MID) != 0) hit = (hit ^ RT_HANDLER_BOTTOM_MID) | RT_HANDLER_TOP_MID;
00327         }
00328 
00329         // Adjust current Tracker size
00330         AdjustTrackerRect(m_curRect, hit);
00331 
00332         // Draw current Tracker
00333         DrawTracker(dc, m_curRect);
00334 
00335         // Update Parent's Status Bar
00336         m_prevRect = m_curRect;
00337         wxCommandEvent evt(wxEVT_TRACKER_CHANGING, m_wnd->GetId());
00338         m_wnd->GetEventHandler()->ProcessEvent(evt);
00339     }
00340     
00341     // Check there is no abuse mouse capture
00342     if (!(event.LeftIsDown()) && ((m_state & RT_STATE_MOUSE_CAPTURED) != 0))
00343     {
00344         m_wnd->ReleaseMouse();
00345         m_state ^= RT_STATE_MOUSE_CAPTURED;
00346     }
00347     
00348     // Update prev_move
00349     m_prevMove = mouse.GetPosition();
00350 
00351    event.Skip();
00352 }
00353 
00354 void wxRectTracker::OnMouseLeftDown(wxMouseEvent & event)
00355 {
00356     m_state |= RT_STATE_DRAGGING;
00357     m_leftClick = event.GetPosition();
00358     if (wxDynamicCast(m_wnd,wxScrolledWindow))
00359     {
00360         wxDynamicCast(m_wnd,wxScrolledWindow)->CalcUnscrolledPosition(m_leftClick.x, m_leftClick.y, &m_leftClick.x, &m_leftClick.y);
00361     }
00362     if (HitTest(m_leftClick.x, m_leftClick.y) == RT_HANDLER_OUTSIDE) 
00363     {
00364         Hide();
00365         Update();
00366     }
00367     
00368     if ((m_state & RT_STATE_MOUSE_CAPTURED) == 0)
00369     {
00370         m_wnd->CaptureMouse();
00371         m_state |= RT_STATE_MOUSE_CAPTURED;
00372     }
00373 
00374     event.Skip();
00375 }
00376 
00377 void wxRectTracker::OnMouseLeftUp(wxMouseEvent & event)
00378 {
00379     if ((m_state & RT_STATE_MOUSE_CAPTURED) != 0)
00380     {
00381         m_wnd->ReleaseMouse();
00382         m_state ^= RT_STATE_MOUSE_CAPTURED;
00383     }
00384     if ((m_state & RT_STATE_DRAGGING) != 0)
00385     {
00386         SetUnscrolledRect(m_prevRect);
00387         m_state ^= RT_STATE_DRAGGING;
00388         m_state ^= RT_STATE_FIRSTDRAG;
00389         m_leftClick = wxPoint(0, 0);
00390         Update();
00391     }
00392    event.Skip();
00393 }
00394 
00395 int wxRectTracker::HitTest(int x, int y) const
00396 {
00397     int w, h;
00398     int z = m_iHandlerWidth;
00399     
00400     w = m_Rect.GetWidth();
00401     h = m_Rect.GetHeight();
00402     x = x - m_Rect.GetLeft();
00403     y = y - m_Rect.GetTop();
00404 
00405     if ( (y < 0) || (y > h) || (x < 0) || (x > w) ) return RT_HANDLER_OUTSIDE;
00406     
00407     // Split vertically, then horizontally
00408     if ( (y <= h) && (y >= h-z) )
00409     {
00410         // Bottom line
00411         if ( (x >= w-z) && (x <= w) )
00412         {
00413             // Bottom Right
00414             return RT_HANDLER_BOTTOM_RIGHT;
00415         }
00416         else if ( (x >= (w-z)/2) && (x <= (w+z)/2) )
00417         {
00418             // Bottom Mid
00419             return RT_HANDLER_BOTTOM_MID;
00420         }
00421         else if ( (x >= 0) && (x <= z) )
00422         {
00423             // Bottom left
00424             return RT_HANDLER_BOTTOM_LEFT;
00425         }
00426     }
00427     else if ( (y >= (h-z)/2 ) && (y <= (h+z)/2) )
00428     {
00429         // Mid line
00430         if ( (x >= w-z) && (x <= w) )
00431         {
00432             // Mid Right
00433             return RT_HANDLER_MID_RIGHT;
00434         }
00435         else if ( (x >= 0) && (x <= z) )
00436         {
00437             // Mid left
00438             return RT_HANDLER_MID_LEFT;
00439         }
00440     }
00441     else if ( (y >= 0) && (y <= z) )
00442     {
00443         // Top line
00444         if ( (x >= w-z) && (x <= w) )
00445         {
00446             // Top Right
00447             return RT_HANDLER_TOP_RIGHT;
00448         }
00449         else if ( (x >= (w-z)/2) && (x <= (w+z)/2) )
00450         {
00451             // Top Mid
00452             return RT_HANDLER_TOP_MID;
00453         }
00454         else if ( (x >= 0) && (x <= z) )
00455         {
00456             // Top left
00457             return RT_HANDLER_TOP_LEFT;
00458         }
00459     }
00460     return RT_HANDLER_NONE;
00461 }
00462 
00463 void wxRectTracker::AdjustTrackerRectMax(wxRect &m_curRect, int handler)
00464 {
00465 
00466     // Adjust m_maxRect 
00467     if ((m_maxRect.width < 0) || (m_maxRect.height < 0)) return;
00468 
00469     // - Left X
00470     if (m_curRect.x < m_maxRect.x)
00471     {
00472         if (handler != RT_HANDLER_NONE) m_curRect.width -= m_maxRect.x - m_curRect.x; 
00473         m_curRect.x = m_maxRect.x;
00474     }
00475     // - Right X
00476     if ((m_curRect.x + m_curRect.width) > (m_maxRect.x + m_maxRect.width))
00477     {
00478         if (handler != RT_HANDLER_NONE) m_curRect.width = m_maxRect.x + m_maxRect.width - m_curRect.x; 
00479         m_curRect.x = m_maxRect.x + m_maxRect.width - m_curRect.width;
00480     }
00481     // - Top Y
00482     if (m_curRect.y < m_maxRect.y)
00483     {
00484         if (handler != RT_HANDLER_NONE) m_curRect.height -= m_maxRect.y - m_curRect.y; 
00485         m_curRect.y = m_maxRect.y;
00486     }
00487     // - Bottom Y
00488     if ((m_curRect.y + m_curRect.height) > (m_maxRect.y + m_maxRect.height))
00489     {
00490         if (handler != RT_HANDLER_NONE) m_curRect.height = m_maxRect.y + m_maxRect.height - m_curRect.y; 
00491         m_curRect.y = m_maxRect.y + m_maxRect.height - m_curRect.height;
00492     }
00493 
00494 }
00495 
00496 void wxRectTracker::AdjustTrackerRect(wxRect &curRect, int handler)
00497 {
00498     AdjustTrackerRectMax(curRect, handler);
00499 }
00500 
00501 void wxRectTracker::SetMaxRect(const wxRect& maxRect)
00502 {
00503     this->m_maxRect = maxRect;
00504     if (this->m_maxRect.height < 0) this->m_maxRect.height = - this->m_maxRect.height;
00505     if (this->m_maxRect.width < 0)  this->m_maxRect.width  = - this->m_maxRect.width;
00506     Update();
00507 }
00508 
00509 void wxRectTracker::Update()
00510 {
00511     m_curRect = GetUnscrolledRect();
00512     AdjustTrackerRect(m_curRect, -1);
00513     if (m_curRect != GetUnscrolledRect())
00514     {
00515         SetUnscrolledRect(m_curRect);
00516     }
00517     m_wnd->Refresh();
00518     wxCommandEvent evt(wxEVT_TRACKER_CHANGED, m_wnd->GetId());
00519     m_wnd->GetEventHandler()->ProcessEvent(evt);
00520 }
00521 
00522 
00523 // TODO : rename this function, as it is now returning the scrolled rect
00524 wxRect wxRectTracker::GetUnscrolledRect() const
00525 {
00526     return m_Rect;
00527 }
00528 
00529 void wxRectTracker::SetUnscrolledRect(const wxRect &rect_ref)
00530 {
00531     m_Rect = rect_ref;
00532 }
00533 
00534 
00535 /*
00536 wxRect wxRectTracker::GetUnscrolledRect()
00537 {
00538     wxRect rect;
00539     rect = m_wnd->GetRect();
00540    //rect = m_Rect;
00541 
00542     // Convert coordinates if scrolled
00543     if (wxDynamicCast(m_wnd,wxScrolledWindow))
00544     {
00545         wxDynamicCast(m_wnd,wxScrolledWindow)->CalcUnscrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
00546     }
00547     return rect;
00548 }
00549 
00550 void wxRectTracker::SetUnscrolledRect(const wxRect& rect_ref)
00551 {
00552    wxRect rect = rect_ref;
00553    
00554     // Convert coordinates if scrolled
00555     if (wxDynamicCast(m_wnd,wxScrolledWindow))
00556     {
00557         wxDynamicCast(m_wnd,wxScrolledWindow)->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
00558     }
00559     m_wnd->SetSize(rect);
00560     
00561    //m_Rect = rect;
00562 }
00563 */
00564 
00565 void wxRectTracker::Enable()
00566 {
00567     this->SetEvtHandlerEnabled(TRUE);
00568     m_state &= ~RT_STATE_DISABLED;
00569 }
00570 
00571 void wxRectTracker::Disable()
00572 {
00573     this->SetEvtHandlerEnabled(FALSE);
00574     if ((m_state & RT_STATE_MOUSE_CAPTURED) != 0)
00575     {
00576         m_wnd->ReleaseMouse();
00577         m_state ^= RT_STATE_MOUSE_CAPTURED;
00578     }
00579     //SetSize(wxRect(0, 0, 0, 0));
00580     Update();
00581     m_state |= RT_STATE_DISABLED;
00582 }
00583 
00584 bool wxRectTracker::IsShown() const
00585 {
00586     return (m_Rect != NullRect);
00587 }
00588 
00589 void wxRectTracker::Hide()
00590 {
00591     m_Rect = NullRect;
00592     m_prevRect = NullRect;
00593     m_wnd->Refresh(false);
00594 }