/** * Copyright Mikael Högdahl - triyana@users.sourceforge.net * * This source is distributed under the terms of the Q Public License version 1.0, * created by Trolltech (www.trolltech.com). */ #include #include #include #include #include /** * Create new border layout * @param int - BORDER, HORIZONTAL, HORIZONTAL_SPLIT, VERTICAL, VERTICAL_SPLIT * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ Fl_Layout::Fl_Layout (int layout, int x, int y, int w, int h) : Fl_Group (x, y, w, h, 0) { aLayout = layout; aWidgets[NORTH] = 0; aWidgets[SOUTH] = 0; aWidgets[WEST] = 0; aWidgets[EAST] = 0; aWidgets[CENTER] = 0; aWidget1 = 0; aWidget2 = 0; aSize = 0; aDrag = 0; aOff = false; for (int f = 0; f < 6; f++) aSpace[f] = 0; resizable (0); } /** * Add child widget */ void Fl_Layout::add (int position, Fl_Widget* widget) { if (aLayout == BORDER) { switch (position) { case NORTH: if (aWidgets[NORTH]) remove (aWidgets[NORTH]); delete aWidgets[NORTH]; Fl_Group::add (widget); aWidgets[NORTH] = widget; break; case SOUTH: if (aWidgets[SOUTH]) remove (aWidgets[SOUTH]); delete aWidgets[SOUTH]; Fl_Group::add (widget); aWidgets[SOUTH] = widget; break; case WEST: if (aWidgets[WEST]) remove (aWidgets[WEST]); delete aWidgets[WEST]; Fl_Group::add (widget); aWidgets[WEST] = widget; break; case EAST: if (aWidgets[EAST]) remove (aWidgets[EAST]); delete aWidgets[EAST]; Fl_Group::add (widget); aWidgets[EAST] = widget; break; case CENTER: if (aWidgets[CENTER]) remove (aWidgets[CENTER]); delete aWidgets[CENTER]; Fl_Group::add (widget); aWidgets[CENTER] = widget; break; default: exit(0); } } else if (aLayout == HORIZONTAL_SPLIT) { if (position == WEST) { delete aWidget1; Fl_Group::add (widget); aWidget1 = widget; aSize = aWidget1->w(); } else if (position == EAST) { delete aWidget2; Fl_Group::add (widget); aWidget2 = widget; } else { delete widget; } } else if (aLayout == VERTICAL_SPLIT) { if (position == NORTH) { delete aWidget1; Fl_Group::add (widget); aWidget1 = widget; aSize = aWidget1->h(); } else if (position == SOUTH) { delete aWidget2; Fl_Group::add (widget); aWidget2 = widget; } else { delete widget; } } else exit(0); } /** * All events goes here, but only for HORIZONTAL_SPLIT and VERTICA_SPLIT * @param int - Event * @return int - 1 for handled event 0 for not */ int Fl_Layout::handle (int event) { if (aLayout != HORIZONTAL_SPLIT && aLayout != VERTICAL_SPLIT) return Fl_Group::handle (event); if (!aWidget1 || !aWidget2) return Fl_Group::handle (event); switch (event) { case FL_DRAG: if (aDrag == HORIZONTAL_SPLIT) { aSize = Fl::event_x() - x(); aWidget1->resize (0, 0, 0, 0); resize (x(), y(), w(), h()); Fl::redraw (); } else if (aDrag == VERTICAL_SPLIT) { aSize = Fl::event_y() - y(); aWidget1->resize (0, 0, 0, 0); resize (x(), y(), w(), h()); Fl::redraw (); } return 1; case FL_LEAVE: fl_cursor (FL_CURSOR_DEFAULT); aDrag = 0; return 0; case FL_MOVE: if (aLayout == HORIZONTAL_SPLIT) { if (Fl::event_x() > (aWidget1->x() + aWidget1->w() - aSpace[0]) && Fl::event_x() < (aWidget1->x() + aWidget1->w() + aSpace[0]) + 2) { fl_cursor (FL_CURSOR_WE); aDrag = HORIZONTAL_SPLIT; } else { fl_cursor (FL_CURSOR_DEFAULT); aDrag = 0; } } else if (aLayout == VERTICAL_SPLIT) { if (Fl::event_y() > (aWidget1->y() + aWidget1->h() - aSpace[0]) && Fl::event_y() < (aWidget1->y() + aWidget1->h() + aSpace[0] + 2)) { fl_cursor (FL_CURSOR_NS); aDrag = VERTICAL_SPLIT; } else { fl_cursor (FL_CURSOR_DEFAULT); aDrag = 0; } } Fl_Group::handle (event); return 0; case FL_PUSH: if (!aDrag) Fl_Group::handle (event); return 1; default: return Fl_Group::handle (event); } } /** * Resize layout and all children * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resize (int x, int y, int w, int h) { if (w == 0 && h == 0) return; //printf ("%4d, %4d %4d, %4d\n", x, y, w, h); Fl_Widget::resize (x, y, w, h); if (aOff == true) return; switch (aLayout) { case BORDER: resizeBorder (x, y, w, h); break; case HORIZONTAL: resizeHorizontal (x, y, w, h); break; case HORIZONTAL_SPLIT: resizeHorizontalSplit (x, y, w, h); break; case VERTICAL: resizeVertical (x, y, w, h); break; case VERTICAL_SPLIT: resizeVerticalSplit (x, y, w, h); break; } } /** * Resize layout and all children * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resizeBorder (int xpos, int ypos, int width, int height) { if (aWidgets[NORTH]) { aWidgets[NORTH]->resize (xpos, ypos, width, aWidgets[NORTH]->h()); ypos += aWidgets[NORTH]->h(); height -= aWidgets[NORTH]->h(); } if (aWidgets[SOUTH]) { aWidgets[SOUTH]->resize (xpos, y() + h() - aWidgets[SOUTH]->h(), width, aWidgets[SOUTH]->h()); height -= aWidgets[SOUTH]->h(); } if (aWidgets[WEST]) { aWidgets[WEST]->resize (xpos, ypos + aSpace[1], aWidgets[WEST]->w(), height - aSpace[1] - aSpace[2]); xpos += aWidgets[WEST]->w(); width -= aWidgets[WEST]->w(); } if (aWidgets[EAST]) { aWidgets[EAST]->resize (x() + w() - aWidgets[EAST]->w(), ypos + aSpace[1], aWidgets[EAST]->w(), height - aSpace[1] - aSpace[2]); width -= aWidgets[EAST]->w(); } if (aWidgets[CENTER]) { aWidgets[CENTER]->resize (xpos + aSpace[3], ypos + aSpace[1], width - aSpace[3] - aSpace[4], height - aSpace[1] - aSpace[2]); } } /** * Resize horizontal layout and all children, set children height to layout height * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resizeHorizontal (int xpos, int ypos, int width, int height) { xpos += aSpace[0]; for (int f = 0; f < children(); f++) { Fl_Widget* w = child (f); if ((xpos + w->w()) > (x() + width)) w->hide (); else w->show (); w->resize (xpos, ypos + aSpace[1], w->w(), height - aSpace[1] * 2); xpos += w->w() + aSpace[0]; } } /** * Resize horizontal split layout and its two child widgets * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resizeHorizontalSplit (int xpos, int ypos, int width, int height) { if (aWidget1 && aWidget2) { if (aSize < 5) aSize = 5; if (aSize > (w() - (5 + aSpace[0]))) aSize = w() - (5 + aSpace[0]); aWidget1->resize (xpos, ypos, aSize, height); aWidget2->resize (xpos + aSize + aSpace[0], ypos, width - (aSize + aSpace[0]), height); } else if (aWidget1) { aWidget1->resize (xpos, ypos, width, height); } } /** * Resize vertical layout and all children, set children width to layout width * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resizeVertical (int xpos, int ypos, int width, int height) { ypos += aSpace[0]; for (int f = 0; f < children(); f++) { Fl_Widget* w = child (f); if ((ypos + w->h()) > (y() + height)) w->hide (); else w->show (); w->resize (xpos + aSpace[1], ypos, width - aSpace[1] * 2, w->h()); ypos += w->h() + aSpace[0]; } } /** * Resize vertical split layout and its two child widgets * @param int - X pos * @param int - Y pos * @param int - Width * @param int - Height */ void Fl_Layout::resizeVerticalSplit (int xpos, int ypos, int width, int height) { if (aWidget1 && aWidget2) { if (aSize < 5) aSize = 5; if (aSize > (h() - (5 + aSpace[0]))) aSize = h() - (5 + aSpace[0]); aWidget1->resize (xpos, ypos, width, aSize); aWidget2->resize (xpos, ypos + aSize + aSpace[0], width, height - (aSize + aSpace[0])); } else if (aWidget1) { aWidget1->resize (xpos, ypos, width, height); } }