Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

PanedWindow.cpp

/*
 * 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);
}

Generated by  Doxygen 1.6.0   Back to index