/* view.c console view object Copyright (C) 2003 Bill Currie Author: Bill Currie Date: 2003/5/5 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; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif static __attribute__ ((unused)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include "QF/view.h" view_t * view_new (int xp, int yp, int xl, int yl, grav_t grav) { view_t *view = calloc (1, sizeof (view_t)); view->xpos = xp; view->ypos = yp; view->xlen = xl; view->ylen = yl; view->gravity = grav; view->visible = 1; view->draw = view_draw; return view; } static void setgeometry (view_t *view) { int i; view_t *par = view->parent; if (!par) { view->xabs = view->xrel = view->xpos; view->yabs = view->yrel = view->ypos; for (i = 0; i < view->num_children; i++) setgeometry (view->children[i]); return; } switch (view->gravity) { case grav_center: view->xrel = view->xpos + (par->xlen - view->xlen) / 2; view->yrel = view->ypos + (par->ylen - view->ylen) / 2; break; case grav_north: view->xrel = view->xpos + (par->xlen - view->xlen) / 2; view->yrel = view->ypos; break; case grav_northeast: view->xrel = par->xlen - view->xpos - view->xlen; view->yrel = view->ypos; break; case grav_east: view->xrel = par->xlen - view->xpos - view->xlen; view->yrel = view->ypos + (par->ylen - view->ylen) / 2; break; case grav_southeast: view->xrel = par->xlen - view->xpos - view->xlen; view->yrel = par->ylen - view->ypos - view->ylen; break; case grav_south: view->xrel = view->xpos + (par->xlen - view->xlen) / 2; view->yrel = par->ylen - view->ypos - view->ylen; break; case grav_southwest: view->xrel = view->xpos; view->yrel = par->ylen - view->ypos - view->ylen; break; case grav_west: view->xrel = view->xpos; view->yrel = view->ypos + (par->ylen - view->ylen) / 2; break; case grav_northwest: view->xrel = view->xpos; view->yrel = view->ypos; break; } view->xabs = par->xabs + view->xrel; view->yabs = par->yabs + view->yrel; for (i = 0; i < view->num_children; i++) setgeometry (view->children[i]); } void view_insert (view_t *par, view_t *view, int pos) { view->parent = par; if (pos < 0) pos = par->num_children + 1 + pos; if (pos < 0) pos = 0; if (pos > par->num_children) pos = par->num_children; if (par->num_children == par->max_children) { par->max_children += 8; par->children = realloc (par->children, par->max_children * sizeof (view_t *)); memset (par->children + par->num_children, 0, (par->max_children - par->num_children) * sizeof (view_t *)); } memmove (par->children + pos + 1, par->children + pos, (par->num_children - pos) * sizeof (view_t *)); par->num_children++; par->children[pos] = view; setgeometry (view); } void view_add (view_t *par, view_t *view) { view_insert (par, view, -1); } void view_remove (view_t *par, view_t *view) { int i; for (i = 0; i < par->num_children; i++) { if (par->children[i] == view) { memcpy (par->children + i, par->children + i + 1, (par->num_children - i - 1) * sizeof (view_t *)); par->children [par->num_children--] = 0; break; } } } void view_delete (view_t *view) { if (view->parent) view_remove (view->parent, view); while (view->num_children) view_delete (view->children[0]); free (view); } void view_draw (view_t *view) { int i; for (i = 0; i < view->num_children; i++) { view_t *v = view->children[i]; if (v->visible && v->draw) v->draw (v); } } static void _resize (view_t *view, int xl, int yl) { int i, xd, yd; xd = xl - view->xlen; yd = yl - view->ylen; view->xlen = xl; view->ylen = yl; for (i = 0; i < view->num_children; i++) { view_t *v = view->children[i]; if (v->resize_x && v->resize_y) { _resize (v, v->xlen + xd, v->ylen + yd); } else if (v->resize_x) { _resize (v, v->xlen + xd, v->ylen); } else if (v->resize_y) { _resize (v, v->xlen, v->ylen + yd); } } } void view_resize (view_t *view, int xl, int yl) { _resize (view, xl, yl); setgeometry (view); } void view_move (view_t *view, int xp, int yp) { view->xpos = xp; view->ypos = yp; setgeometry (view); }