/* * PanedWindow.cpp * * Copyright (C) 1999 Stephen F. White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #include "stdafx.h" #include "swt.h" #include "PanedWindow.h" #define SASH_WIDTH 5 enum { NORMAL, TRACK_TOP, TRACK_BOTTOM, TRACK_LEFT, TRACK_RIGHT }; PanedWindow::PanedWindow(Scene *scene, SWND wnd, bool sashes) : SceneView(scene, wnd) { _sashes = sashes; _top = _left = _bottom = _right = _center = NULL; _state = NORMAL; _cursorH = swLoadCursor(SW_CURSOR_DBL_ARROW_HORZ); _cursorV = swLoadCursor(SW_CURSOR_DBL_ARROW_VERT); _cursorNormal = swLoadCursor(SW_CURSOR_ARROW); } PanedWindow::~PanedWindow() { swDestroyCursor(_cursorH); swDestroyCursor(_cursorV); swDestroyCursor(_cursorNormal); } void PanedWindow::OnSize(int width, int height) { Layout(); } void PanedWindow::Layout(bool maximize) { int width, height, rw, rh; int w, h, left = 0, top = 0; #ifdef WIN32 if (maximize) { swGetScreenSize(&width, &height); swSetSize(_wnd,width,height); } else { swGetSize(_wnd, &width, &height); // otherwise problems with iconify/deiconify ... if ((width==0) && (height==0)) swGetScreenSize(&width, &height); } // return; #else swGetSize(_wnd, &width, &height); #endif bool showTop = _top && swIsVisible(_top->GetWindow()); bool showBottom = _bottom && swIsVisible(_bottom->GetWindow()); bool showLeft = _left && swIsVisible(_left->GetWindow()); bool showRight = _right && swIsVisible(_right->GetWindow()); bool showCenter = _center && swIsVisible(_center->GetWindow()); swInvalidateRect(_wnd, 0, 0, width, height); rw = width; rh = height; if (showLeft && _sashes) rw -= SASH_WIDTH; if (showRight && _sashes) rw -= SASH_WIDTH; if (rw < 0) rw = 0; if (showTop && _sashes) rh -= SASH_WIDTH; if (showBottom && _sashes) rh -= SASH_WIDTH; if (rh < 0) rh = 0; if (showTop) { swGetSize(_top->GetWindow(), &w, &h); if (h > rh) h = rh; swSetSize(_top->GetWindow(), width, h); top = h; if (_sashes) top += SASH_WIDTH; rh -= h; if (rh < 1) rh = 1; } if (showBottom) { swGetSize(_bottom->GetWindow(), &w, &h); if (h > rh) h = rh; swMoveWindow(_bottom->GetWindow(), 0, height - h, width, h); rh -= h; if (rh < 1) rh = 1; } if (showLeft) { swGetSize(_left->GetWindow(), &w, &h); if (w > rw) w = rw; swMoveWindow(_left->GetWindow(), 0, top, w, rh); left = w; if (_sashes) left += SASH_WIDTH; rw -= w; if (rw < 1) rw = 1; } if (showRight) { swGetSize(_right->GetWindow(), &w, &h); if (w > rw) w = rw; swMoveWindow(_right->GetWindow(), width - w, top, w, rh); rw -= w; if (rw < 1) rw = 1; } if (showCenter) { swMoveWindow(_center->GetWindow(), left, top, rw, rh); } } void PanedWindow::SetPane(SceneView *pane, int direction) { switch (direction) { case PW_TOP: _top = pane; break; case PW_BOTTOM: _bottom = pane; break; case PW_LEFT: _left = pane; break; case PW_RIGHT: _right = pane; break; case PW_CENTER: _center = pane; break; } } int PanedWindow::HitTest(int x, int y) { int width, height; int twidth = 0, theight = 0; int bwidth = 0, bheight = 0; int lwidth = 0, lheight = 0; int rwidth = 0, rheight = 0; swGetSize(_wnd, &width, &height); if (_top) swGetSize(_top->GetWindow(), &twidth, &theight); if (_bottom) swGetSize(_bottom->GetWindow(), &bwidth, &bheight); if (_left) swGetSize(_left->GetWindow(), &lwidth, &lheight); if (_right) swGetSize(_right->GetWindow(), &rwidth, &rheight); if (_top && y >= theight && y < theight + SASH_WIDTH) { return TRACK_TOP; } else if (_bottom && y >= height - bheight - SASH_WIDTH && y < height - bheight) { return TRACK_BOTTOM; } else if (_left && x >= lwidth && x < lwidth + SASH_WIDTH) { return TRACK_LEFT; } else if (_right && x >= width - rwidth - SASH_WIDTH && x < width - rwidth) { return TRACK_RIGHT; } else { return NORMAL; } } void PanedWindow::UpdateCursor(int state) { #ifndef WIN32 if (!TheApp->useStereo()) { if (state == TRACK_TOP || state == TRACK_BOTTOM) { swSetCursor(_wnd, _cursorV); } else if (state == TRACK_LEFT || state == TRACK_RIGHT) { swSetCursor(_wnd, _cursorH); } else { swSetCursor(_wnd, _cursorNormal); } } #endif } void PanedWindow::OnMouseMove(int x, int y, int modifiers) { int width, height; int lwidth = 0, lheight = 0; if (!_sashes) return; if (_state == NORMAL) { UpdateCursor(HitTest(x, y)); } else { swGetSize(_wnd, &width, &height); x = CLAMP(x, 1, width - 1); y = CLAMP(y, 1, height - 1); if (_left) swGetSize(_left->GetWindow(), &lwidth, &lheight); if (_state == TRACK_TOP) { swSetSize(_top->GetWindow(), width, y); } else if (_state == TRACK_BOTTOM) { swSetSize(_bottom->GetWindow(), width, height - y); } else if (_state == TRACK_LEFT) { swSetSize(_left->GetWindow(), x, lheight); } else if (_state == TRACK_RIGHT) { int rwidth, rheight; swGetSize(_right->GetWindow(), &rwidth, &rheight); swSetSize(_right->GetWindow(), width - x, rheight); } Layout(); } } void PanedWindow::OnMouseLeave() { UpdateCursor(_state); } void PanedWindow::OnLButtonDown(int x, int y, int modifiers) { if (!_sashes) return; _state = HitTest(x, y); UpdateCursor(_state); if (_state != NORMAL) swSetCapture(_wnd); } void PanedWindow::OnLButtonUp(int x, int y, int modifiers) { if (!_sashes) return; _state = NORMAL; swReleaseCapture(_wnd); swSetCursor(_wnd, _cursorNormal); } void PanedWindow::OnDraw(int x, int y, int width, int height) { if (!_sashes) return; int top = 0; SDC dc = swCreateDC(_wnd); swGetSize(_wnd, &width, &height); if (_top && swIsVisible(_top->GetWindow())) { int w, h; swGetSize(_top->GetWindow(), &w, &h); DrawHSash(dc, 0, h, width, SASH_WIDTH); top = h + SASH_WIDTH; } if (_bottom && swIsVisible(_bottom->GetWindow())) { int w, h; swGetSize(_bottom->GetWindow(), &w, &h); DrawHSash(dc, 0, height - h - SASH_WIDTH, width, SASH_WIDTH); } if (_left && swIsVisible(_left->GetWindow())) { int w, h; swGetSize(_left->GetWindow(), &w, &h); DrawVSash(dc, w, top, SASH_WIDTH, h); } if (_right && swIsVisible(_right->GetWindow())) { int w, h; swGetSize(_right->GetWindow(), &w, &h); DrawVSash(dc, width - w - SASH_WIDTH, top, SASH_WIDTH, h); } swDestroyDC(dc); } void PanedWindow::DrawVSash(SDC dc, int x, int y, int w, int h) { swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_TSHADOW)); swDrawLine(dc, x, y, x, y + h - 1); swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_BSHADOW)); swDrawLine(dc, x + w - 1, y, x + w - 1, y + h - 1); swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_FACE)); swFillRect(dc, x + 1, y, w - 2, h - 1); } void PanedWindow::DrawHSash(SDC dc, int x, int y, int w, int h) { swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_TSHADOW)); swDrawLine(dc, x, y, x + w - 1, y); swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_BSHADOW)); swDrawLine(dc, x, y + h - 1, x + w - 1, y + h - 1); swSetFGColor(dc, swGetWindowColor(_wnd, SW_COLOR_FACE)); swFillRect(dc, x, y + 1, w - 1, h - 2); }