Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

barholder.cpp

Go to the documentation of this file.
00001 
00002 // Name:        barholder.cpp
00003 // Purpose:     wxBarHolder implementation.
00004 // Author:      Mark McCormack
00005 // Modified by:
00006 // Created:     25/05/04
00007 // RCS-ID:      $Id: barholder.cpp,v 1.5 2005/05/12 14:04:45 frm Exp $
00008 // Copyright:   (c) 2004 Mark McCormack
00009 // Licence:     wxWindows license
00011 
00012 #include <wx/barholder.h>
00013 #include <wx/gripper.h>
00014 #include <wx/slidebar.h>
00015 #include <wx/dcclient.h>
00016 
00017 // ----------------------------------------------------------------------------
00018 // wxBarHolder constants & wx-macros
00019 // ----------------------------------------------------------------------------
00020 
00021 DEFINE_EVENT_TYPE( wxEVT_BARHOLDER_RIGHTDOWN )
00022 
00023 BEGIN_EVENT_TABLE( wxBarHolder, wxWindow )
00024     EVT_ERASE_BACKGROUND( wxBarHolder::OnErase )
00025     EVT_PAINT( wxBarHolder::OnPaint )
00026     EVT_GRIP_LEFTDOWN( wxBarHolder::OnGripBegin )
00027     EVT_GRIP_LEFTUP( wxBarHolder::OnGripEnd )
00028     EVT_GRIP_MOTION( wxBarHolder::OnGripMotion )
00029 END_EVENT_TABLE()
00030 
00031 IMPLEMENT_DYNAMIC_CLASS( wxBarHolder, wxWindow )
00032 
00033 const int DEFAULT_MARGIN = 2;
00034 const int GRIP_SIZE = 6;
00035 
00036 // ----------------------------------------------------------------------------
00037 // wxBarHolder implementation
00038 // ----------------------------------------------------------------------------
00039 
00040 void wxBarHolder::Init() {
00041     pSlideBar_ = NULL;
00042     pOurBar_ = NULL;
00043     pGripWindow_= NULL;
00044     showGripper_ = true;
00045     margin_ = DEFAULT_MARGIN;
00046     heightOverride_ = -1;
00047     widthOverride_ = -1;
00048     flags_ = wxBF_DEFAULT;
00049     moving_ = false;
00050 }
00051 
00052 bool wxBarHolder::Create( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) {
00053     wxASSERT(parent);
00054     // create the wxWindow control
00055     if( !wxWindow::Create( parent, id, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name ) ) {
00056         return FALSE;
00057     }
00058 
00059     // create sub-controls
00060     pGripWindow_ = new wxGripWindow( this, wxHORIZONTAL, wxGdi::wxGRIP_STYLE_MOVE );
00061 
00062     // assign the cursor for hover over the gripper
00063     pGripWindow_->SetCursor( g_gdi.GetMoveCursor() );
00064 
00065     return TRUE;
00066 }
00067 
00068 wxBarHolder::~wxBarHolder() {
00069 }
00070 
00071 void wxBarHolder::AddWindow( wxWindow * pWindow, const wxString & label, unsigned int flags ) {
00072     // add a window
00073     wxASSERT(pWindow);
00074     flags_ = flags;
00075     originalSize_ = getClientBestSize( pWindow );
00076     label_ = label;
00077     pGripWindow_->SetLabel( label );
00078 
00079     if( wxDynamicCast( pWindow, wxToolBar ) ) {
00080         // enforce the wxTB_NODIVIDER style for toolbars
00081         long windowStyle = pWindow->GetWindowStyle();
00082         windowStyle |= wxTB_NODIVIDER;
00083         pWindow->SetWindowStyle( windowStyle );
00084     }
00085 
00086     // take ownership
00087     pOurBar_ = pWindow;
00088     pWindow->Reparent( this );
00089     UpdateSize();
00090 }
00091 
00092 void wxBarHolder::SetSlideBar( wxSlideBar * pSlideBar ) {
00093     pSlideBar_ = pSlideBar;
00094 }
00095 
00096 void wxBarHolder::ShowGripper( bool state ) {
00097     showGripper_ = state;
00098     UpdateSize();
00099 }
00100 
00101 wxSize wxBarHolder::DoGetBestSize() const {
00102     // calc the minimum size for this holder
00103     wxSize barSize = originalSize_;
00104 
00105     // add margin
00106     int gripSize = showGripper_ ? GRIP_SIZE : 0;
00107     barSize.x += (margin_*2);
00108     barSize.y += (margin_*2);
00109 
00110     wxSize clientSize = barSize;
00111     clientSize.x += gripSize;
00112 
00113     // add our non-client area to the size
00114     clientSize = clientSize + getNonClientSize();
00115 
00116     return clientSize;
00117 }
00118 
00119 void wxBarHolder::UpdateSize() {
00120     if( !pOurBar_ ) return;
00121 
00122     wxSize barSize = originalSize_;
00123     wxSize clientSize = barSize;
00124 
00125     int ho = heightOverride_, wo = widthOverride_;
00126     // remove the non-client area from the sizes
00127     ho -= getNonClientSize().GetHeight();
00128     wo -= getNonClientSize().GetWidth();
00129 
00130     // fit ourselves around the owned bar
00131     clientSize.x += (margin_*2);
00132     clientSize.y += (margin_*2);
00133     int gripSize = showGripper_ ? GRIP_SIZE : 0;
00134     clientSize.x += gripSize;
00135     if( heightOverride_ != -1 ) clientSize.y = ho;
00136     if( widthOverride_ != -1 ) clientSize.x = wo;
00137 
00138     SetClientSize( clientSize );
00139     wxRect br;
00140     // expand in the y-axis?
00141     if( flags_ & wxBF_EXPAND_Y ) {
00142         br.y = margin_;
00143         br.height = clientSize.GetY() - (margin_*2);
00144     }
00145     else {
00146         br.y = (clientSize.GetY()/2) - (barSize.GetHeight()/2);
00147         br.height = barSize.GetHeight();
00148     }
00149     // expand in the x-axis?
00150     br.x = (margin_ + gripSize);
00151     if( flags_ & wxBF_EXPAND_X ) {
00152         br.width = clientSize.GetX() - ((margin_*2) + gripSize);
00153     }
00154     else {
00155         br.width = barSize.GetWidth();
00156     }
00157     pOurBar_->SetSize( br.x, br.y, br.width, br.height );
00158 
00159     // size the gripper
00160     pGripWindow_->Show( showGripper_ );
00161     pGripWindow_->SetSize( margin_, margin_, gripSize, clientSize.GetHeight() - (margin_*2) );
00162 
00163     return;
00164 }
00165 
00166 void wxBarHolder::SetHeightOverride( int override ) {
00167     heightOverride_ = override;        
00168 }
00169 
00170 void wxBarHolder::SetWidthOverride( int override ) {
00171     widthOverride_ = override;        
00172 }
00173 
00174 void wxBarHolder::SetFlags( unsigned int flags ) {
00175     flags_ = flags;
00176 }
00177 
00178 unsigned int wxBarHolder::GetFlags() {
00179     return flags_;
00180 }
00181 
00182 wxString wxBarHolder::GetLabel() {
00183  return label_;
00184 }
00185 
00186 void wxBarHolder::OnErase( wxEraseEvent & WXUNUSED(event) ) {
00187 }
00188 
00189 void wxBarHolder::OnPaint( wxPaintEvent & WXUNUSED(event) ) {
00190     wxPaintDC dc(this);
00191 
00192  // create a clipping region to exclude the child window
00193  dc.DestroyClippingRegion();
00194     wxRect cr = GetClientRect();
00195  wxRegion region( cr );
00196  wxRect sr = pOurBar_->GetRect();
00197  region.Subtract( sr );
00198  dc.SetClippingRegion( region );
00199 
00200  // draw background
00201     g_gdi.DrawBackground( dc, cr );
00202     g_gdi.DrawEdge( dc, cr, moving_ );
00203 }
00204 
00205 void wxBarHolder::OnGripBegin( wxMouseEvent & WXUNUSED(event) ) {
00206     // we want all mouse moves
00207     pGripWindow_->CaptureMouse();
00208 
00209     moving_ = true;
00210     Refresh();
00211 }
00212 
00213 void wxBarHolder::OnGripEnd( wxMouseEvent & WXUNUSED(event) ) {
00214     // release mouse
00215     if( moving_ ) {
00216         pGripWindow_->ReleaseMouse();
00217     }
00218 
00219     moving_ = false;
00220     Refresh();
00221 }
00222 
00223 void wxBarHolder::OnGripMotion( wxMouseEvent &event ) {
00224     if( !moving_ ) {
00225         return;
00226     }
00227     if( !pSlideBar_ ) {
00228         // can't do anything without owner
00229         return;
00230     }
00231 
00232     // convert from gripper local coordinates to parent local coordinates
00233     wxPoint pt = event.GetPosition();
00234     pt = pGripWindow_->ClientToScreen( pt );
00235     pt = pSlideBar_->ScreenToClient( pt );
00236 
00237     wxASSERT(pSlideBar_);
00238 
00239     wxBarHolder * pHoverBar = pSlideBar_->GetBarHolderAt( pt );
00240  if( !pHoverBar || pHoverBar == this ) {
00241   return;
00242  }
00243     Refresh();
00244 
00245  // swap this bar with the bar under the cursor
00246     pSlideBar_->SwapBarHolders( this, pHoverBar );
00247 
00248  // re-calculate what the layout would be
00249  BarPlacementArray &bpl = pSlideBar_->CalcBarPlacement( -1 );
00250 
00251  // is the cursor over where we would move to?
00252  if( pSlideBar_->GetBarHolderAt( bpl, pt ) == this ) {
00253   // accept swap
00254      pSlideBar_->UpdateLayout();
00255   return;
00256  }
00257 
00258  // else, undo swap
00259     pSlideBar_->SwapBarHolders( this, pHoverBar );
00260 }
00261 
00262 // ----------------------------------------------------------------------------
00263 
00264 wxSize wxBarHolder::getNonClientSize() const {
00265     // work out the size of the non-client border
00266     wxSize cs = GetClientSize();
00267     wxSize s = GetSize();
00268     return (s - cs);
00269 }
00270 
00271 wxSize wxBarHolder::getClientBestSize( wxWindow * pClient ) const {
00272     if( wxDynamicCast( pClient, wxToolBar ) ) {
00273         wxSize toolBarSize = pClient->GetBestSize();
00274 #if defined(__WXMSW__)
00275 // NOTE: that there is a bug in (wxMSW) wxToolBar::GetBestSize() which means that the returned size is
00276 // usually be too large in the x and too small in the y
00277         toolBarSize.y++;
00278 #endif
00279         return toolBarSize;
00280     }
00281     return pClient->GetSize();
00282 }

Generated on Sat May 14 14:54:38 2005 for wxDockIt by  doxygen 1.4.2