00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include <wx/exsplitter.h>
00013 #include <wx/gdi.h>
00014 #include <wx/dockhost.h>
00015
00016 #include <wx/dcscreen.h>
00017
00018
00019
00020
00021
00022 IMPLEMENT_CLASS( wxExSplitter, wxWindow )
00023 DEFINE_EVENT_TYPE( wxEVT_SPLITTER_MOVED )
00024
00025 BEGIN_EVENT_TABLE( wxExSplitter, wxWindow )
00026 EVT_LEFT_DOWN( wxExSplitter::OnLeftDown )
00027 EVT_MOTION( wxExSplitter::OnMouseMove )
00028 EVT_LEFT_UP( wxExSplitter::OnLeftUp )
00029 EVT_ERASE_BACKGROUND( wxExSplitter::OnErase )
00030 EVT_PAINT( wxExSplitter::OnPaint )
00031 END_EVENT_TABLE()
00032
00033 void wxExSplitter::Init() {
00034 memset(&pWindow_, 0, sizeof(pWindow_));
00035 pOwner_ = NULL;
00036 bounded_ = false;
00037 dragging_ = false;
00038 minSize_ = wxMINIMUM_WINDOW_SIZE;
00039 flags_ = 0x0000;
00040 startPosition_.x = startPosition_.y = 0;
00041 }
00042
00043 bool wxExSplitter::Create( wxWindow * parent, wxOrientation orientation, wxWindow * win1, wxWindow * win2, unsigned int flags ) {
00044 wxASSERT(parent);
00045 bool r = wxWindow::Create( parent, -1, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE );
00046
00047
00048 pOwner_ = parent;
00049 pWindow_[0] = win1;
00050 pWindow_[1] = win2;
00051 orientation_ = orientation;
00052 flags_ = flags;
00053
00054
00055 if( orientation_ == wxHORIZONTAL ) {
00056 SetCursor( g_gdi.GetHSplitCursor() );
00057 }
00058 else {
00059 SetCursor( g_gdi.GetVSplitCursor() );
00060 }
00061
00062 return r;
00063 }
00064
00065 void wxExSplitter::SetWindows( wxWindow * pWin1, wxWindow * pWin2 ) {
00066
00067 pWindow_[0] = pWin1;
00068 pWindow_[1] = pWin2;
00069 }
00070
00071 void wxExSplitter::SetFlags( unsigned int flags ) {
00072 flags_ = flags;
00073 }
00074
00075 void wxExSplitter::OnLeftDown( wxMouseEvent& event ) {
00076
00077 startPosition_ = ClientToScreen( event.GetPosition() );
00078 dragging_ = true;
00079
00080
00081 startRect_[0] = pWindow_[0] ? pWindow_[0]->GetRect() : wxRect();
00082 startRect_[1] = pWindow_[1] ? pWindow_[1]->GetRect() : wxRect();
00083 startRectUs_ = GetRect();
00084 endRectUs_ = startRectUs_;
00085
00086
00087 SetBoundaries();
00088
00089
00090 lastDrawnRect_ = wxRect();
00091 #ifndef __WXGTK__
00092
00093
00094 draw( startRectUs_ );
00095 #endif
00096
00097
00098 CaptureMouse();
00099 }
00100
00101 void wxExSplitter::OnMouseMove( wxMouseEvent& event ) {
00102 if( dragging_ ) {
00103 wxPoint pos = ClientToScreen( event.GetPosition() );
00104
00105 if (bounded_) {
00106
00107 if ((pos.x < boundary[0].x) ||
00108 (pos.x > boundary[1].x) ||
00109 (pos.y < boundary[0].y) ||
00110 (pos.y > boundary[1].y)) {
00111 return;
00112 }
00113 }
00114
00115 wxRect r0 = startRect_[0], r1 = startRect_[1], r = startRectUs_;
00116 if( orientation_ == wxHORIZONTAL ) {
00117
00118 int dx = pos.x - startPosition_.x;
00119 if( pWindow_[0] && (r0.width + dx) < minSize_ ) dx = minSize_ - r0.width;
00120 if( pWindow_[1] && (r1.width - dx) < minSize_ ) dx = r1.width - minSize_;
00121
00122 r0.width += dx;
00123 r1.width -= dx;
00124 r1.x += dx;
00125 r.x += dx;
00126 }
00127 else {
00128
00129 int dy = pos.y - startPosition_.y;
00130 if( pWindow_[0] && (r0.height + dy) < minSize_ ) dy = minSize_ - r0.height;
00131 if( pWindow_[1] && (r1.height - dy) < minSize_ ) dy = r1.height - minSize_;
00132
00133 r0.height += dy;
00134 r1.height -= dy;
00135 r1.y += dy;
00136 r.y += dy;
00137 }
00138
00139
00140 if( flags_ & wxESF_LIVE_UPDATE ) {
00141
00142 if( pWindow_[0] ) pWindow_[0]->SetSize( r0 );
00143 if( pWindow_[1] ) pWindow_[1]->SetSize( r1 );
00144 if( !pWindow_[0] ) {
00145
00146 r.x = startRectUs_.x;
00147 r.y = startRectUs_.y;
00148 }
00149 SetSize( r );
00150
00151
00152 wxCommandEvent e( wxEVT_SPLITTER_MOVED, GetId() );
00153 e.SetEventObject( this );
00154 GetEventHandler()->ProcessEvent( e );
00155 }
00156 else {
00157
00158 if( lastDrawnRect_.GetWidth() && lastDrawnRect_.GetHeight() ) {
00159 draw( lastDrawnRect_ );
00160 }
00161 draw( r );
00162
00163
00164 endRect_[0] = r0;
00165 endRect_[1] = r1;
00166 endRectUs_ = r;
00167 if( !pWindow_[0] ) {
00168
00169 endRectUs_.x = startRectUs_.x;
00170 endRectUs_.y = startRectUs_.y;
00171 }
00172 }
00173 }
00174 }
00175
00176 void wxExSplitter::OnErase( wxEraseEvent& WXUNUSED(event) ) {
00177
00178 }
00179
00180 void wxExSplitter::OnPaint( wxPaintEvent& WXUNUSED(event) ) {
00181 wxPaintDC dc(this);
00182
00183 wxRect cr = GetClientRect();
00184
00185
00186 if( flags_ & wxESF_DRAW_GRIPPER ) {
00187 g_gdi.DrawSplitter( dc, cr, orientation_ );
00188 }
00189 else {
00190 g_gdi.DrawBackground( dc, cr );
00191 }
00192 }
00193
00194 void wxExSplitter::OnLeftUp( wxMouseEvent& WXUNUSED(event) ) {
00195 if( !dragging_ ) return;
00196
00197
00198 ReleaseMouse();
00199 dragging_ = false;
00200
00201
00202 if( !(flags_ & wxESF_LIVE_UPDATE) ) {
00203
00204 draw( lastDrawnRect_ );
00205
00206 if( endRectUs_.GetWidth() || endRectUs_.GetHeight() ) {
00207
00208 for( int i=0; i<wxSPLITTER_WINDOWS; i++ ) {
00209
00210 if( pWindow_[i] ) {
00211
00212 if( endRect_[i].GetWidth() || endRect_[i].GetHeight() ) {
00213 pWindow_[i]->SetSize( endRect_[i] );
00214 }
00215 }
00216 }
00217 SetSize( endRectUs_ );
00218 }
00219 }
00220
00221
00222 wxCommandEvent e(wxEVT_SPLITTER_MOVED, GetId());
00223 e.SetEventObject(this);
00224 GetEventHandler()->ProcessEvent(e);
00225 }
00226
00227 void wxExSplitter::draw( wxRect r ) {
00228 if( flags_ & wxESF_LIVE_UPDATE ) return;
00229
00230
00231 wxScreenDC dc;
00232
00233 wxRect screenRect = r;
00234 screenRect.SetPosition( pOwner_->ClientToScreen( screenRect.GetPosition() ) );
00235 g_gdi.DrawPattern( dc, screenRect );
00236 lastDrawnRect_ = r;
00237 }
00238
00239 void wxExSplitter::SetBoundaries() {
00240 bounded_ = false;
00241
00242 if ((pWindow_[0] && pWindow_[1]) || (!pWindow_[0] && !pWindow_[1])) {
00243 return;
00244 }
00245
00246 wxDockHost* dh = wxDynamicCast(pOwner_, wxDockHost);
00247
00248 if (!dh || (dh -> GetSizingSplitter() != this)) {
00249 return;
00250 }
00251
00252 bounded_ = true;
00253
00254 wxWindow* parent = dh -> GetParent();
00255 wxLayoutManager* pLayoutManager = dh -> GetLayoutManager();
00256 wxSize clientSize = parent -> GetClientSize();
00257
00258 if (pLayoutManager) {
00259 wxRect dockArea = pLayoutManager->GetDockArea();
00260 boundary[0] = dockArea.GetPosition();
00261 clientSize = dockArea.GetSize();
00262 }
00263 else {
00264 boundary[0] = wxPoint(0, 0);
00265 clientSize = parent->GetClientSize();
00266 }
00267 boundary[0] = parent->ClientToScreen(boundary[0]);
00268
00269 boundary[0].x += wxSPLITTER_SIZE;
00270 boundary[0].y += wxSPLITTER_SIZE;
00271
00272 boundary[1] = boundary[0];
00273
00274 boundary[1].x += (clientSize.GetWidth() - (wxSPLITTER_SIZE * 2));
00275 boundary[1].y += (clientSize.GetHeight() - (wxSPLITTER_SIZE * 2));
00276
00277 if (!pLayoutManager) {
00278 return;
00279 }
00280
00281
00282 wxDirection ldir = wxALL;
00283
00284 switch (dh -> GetDirection()) {
00285 case wxLEFT :
00286 ldir = wxRIGHT; break;
00287 case wxRIGHT :
00288 ldir = wxLEFT; break;
00289 case wxTOP :
00290 ldir = wxBOTTOM; break;
00291 case wxBOTTOM :
00292 ldir = wxTOP; break;
00293 default :
00294 ldir = wxALL; break;
00295 }
00296
00297 if (ldir == wxALL) {
00298 return;
00299 }
00300
00301 wxDockHost* dockhost = pLayoutManager -> GetDockHost(ldir);
00302 if (dockhost && !dockhost -> IsEmpty()) {
00303 wxRect hr = dockhost -> GetScreenArea();
00304
00305 switch (ldir) {
00306 case wxLEFT :
00307 boundary[0].x = hr.GetRight() + wxSPLITTER_SIZE; break;
00308 case wxRIGHT :
00309 boundary[1].x = hr.GetLeft() - wxSPLITTER_SIZE; break;
00310 case wxTOP :
00311 boundary[0].y = hr.GetBottom() + wxSPLITTER_SIZE; break;
00312 case wxBOTTOM :
00313 boundary[1].y = hr.GetTop() - wxSPLITTER_SIZE; break;
00314 case wxALL :
00315 wxASSERT(false); break;
00316 }
00317 }
00318 }