/* * Pane * Handles all those many problems you get with panes * * v. 1.100 (25 July 1993) * * © 1993-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Steel library. * * Steel 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, or (at your option) * any later version. * * Steel 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 Steel. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "wimp.h" #include "wimpt.h" #include "pane.h" #include "werr.h" #include "msgs.h" #include "mem.h" #include "win.h" #include typedef enum { pane__WINDOW, pane__LISTBOX } pane__paneType; typedef union { list l; } pane__handle; typedef struct pane__paneItem { struct pane__paneItem *next; wimp_w pane; pane__paneType type; pane__handle handle; wimp_box box; } pane__paneItem; typedef struct pane__panestr { wimp_w tool; pane__paneItem *panes; } pane__panestr; /* * pane pane_create(wimp_w tool) * * Use * Sets up a structure for a pane, and returns a handle. * * Parameters * wimp_w tool == the window handle of the tool window (the one that isn't * a pane) * * Returns * An abstract handle to the pane. */ pane pane_create(wimp_w tool) { pane newPane=(pane)mem_alloc(sizeof(pane__panestr)); if (newPane) { newPane->tool=tool; newPane->panes=0; } else werr(FALSE,msgs_lookup("paneNEM:Not enough memory to register pane.")); return (newPane); } /* * void pane_addPane(pane p,wimp_w w) * * Use * Registers a new pane as being associated with the tool window given in * pane_create(). * * Parameters * pane p == the pane handle for the tool window * wimp_w w == the window handle of the new pane */ void pane_addPane(pane p,wimp_w w) { pane__paneItem *new; wimp_wstate ts; wimp_wstate ps; if (p==0) return; if (new=mem_alloc(sizeof(pane__paneItem)),!new) return; new->pane=w; new->type=pane__WINDOW; wimpt_noerr(wimp_get_wind_state(w,&ps)); wimpt_noerr(wimp_get_wind_state(p->tool,&ts)); new->box.x0=ps.o.box.x0-ts.o.box.x0; new->box.y0=ps.o.box.y0-ts.o.box.y0; new->box.x1=ps.o.box.x1-ts.o.box.x0; new->box.y1=ps.o.box.y1-ts.o.box.y0; new->next=p->panes; p->panes=new; } /* * void pane_addListbox(pane p,list l) * * Use * Adds a listbox to the tool window. Handles things properly, so that * scroll bars and things appear at the right time. * * Parameters * pane p == the pane to add to * list l == the list to add */ void pane_addListbox(pane p,list l) { wimp_w w=list_syshandle(l); pane__paneItem *new; wimp_wstate ts; wimp_wstate ps; list_isPane(l,p); if (p==0) return; if (new=mem_alloc(sizeof(pane__paneItem)),!new) return; new->pane=w; new->type=pane__LISTBOX; new->handle.l=l; wimpt_noerr(wimp_get_wind_state(w,&ps)); wimpt_noerr(wimp_get_wind_state(p->tool,&ts)); new->box.x0=ps.o.box.x0-ts.o.box.x0; new->box.y0=ps.o.box.y0-ts.o.box.y0; new->box.x1=ps.o.box.x1-ts.o.box.x0; new->box.y1=ps.o.box.y1-ts.o.box.y0; new->next=p->panes; p->panes=new; } /* * void pane_delete(pane p) * * Use * Destroys and mem_free()s the memory occupied by a pane structure. * * Parameters * pane p == the pane's handle */ void pane_delete(pane p) { pane__paneItem *itm=p->panes; pane__paneItem *i; while (itm) { i=itm; itm=i->next; switch (i->type) { case pane__LISTBOX: list_isPane(i->handle.l,0); break; } mem_free(i); } mem_free(p); } /* * void pane_removePane(pane p,wimp_w w) * * Use * Removes the specified pane from the structure. * * Parameters * pane p == the pane in question * wimp_w w == the window to remove */ void pane_removePane(pane p,wimp_w w) { pane__paneItem *i=(pane__paneItem *)(&p->panes); pane__paneItem *it; while (i->next) { if (i->next->pane==w) { it=i->next; i->next=it->next; switch (it->type) { case pane__LISTBOX: list_isPane(it->handle.l,0); break; } mem_free(it); return; } i=i->next; } } /* * void pane__doMove(pane p,wimp_openstr *o) * * Use * Moves a set of panes to the place specified. * * Parameters * pane p == the pane handle * wimp_openstr *o == where to put them */ static void pane__doMove(pane p,wimp_openstr *o) { pane__paneItem *i=p->panes; wimp_wstate state; wimp_w behind; behind=o->behind; if (behind==-2) { wimpt_noerr(wimp_open_wind(o)); wimpt_noerr(wimp_get_wind_state(o->w,&state)); behind=state.o.behind; i=p->panes; if (behind==i->pane) { wimpt_noerr(wimp_get_wind_state(i->pane,&state)); behind=state.o.behind; } } i=p->panes; while (i) { wimpt_noerr(wimp_get_wind_state(i->pane,&state)); state.o.box.x0=o->box.x0+i->box.x0; state.o.box.y0=o->box.y0+i->box.y0; state.o.box.x1=o->box.x0+i->box.x1; state.o.box.y1=o->box.y0+i->box.y1; state.o.behind=behind; behind=i->pane; wimpt_noerr(wimp_open_wind(&state.o)); i=i->next; } o->behind=behind; wimpt_noerr(wimp_open_wind(o)); } /* * void pane_updatePanes(pane p) * * Use * Updates position of panes attached to the main window after it has been * moved. * * Parameters * pane p == the pane handle */ void pane_updatePanes(pane p) { wimp_wstate s; wimpt_noerr(wimp_get_wind_state(p->tool,&s)); pane__doMove(p,&s.o); } /* * void pane_moved(pane p) * * Use * Asks the pane segment to reopen a pane in response to an wimp_EOPEN * event. * * Parameters * pane p == the pane handle */ void pane_moved(pane p) { wimp_eventstr *e=wimpt_last_event(); if (e->e!=wimp_EOPEN || e->data.o.w!=p->tool) { werr ( TRUE, msgs_lookup("paneIPH:(pane_moved, caller fault): " "not a wimp_EOPEN event or with wrong pane handle.") ); return; } if (wimpt_justChangedMode()) win_adjustBox(&e->data.o); pane__doMove(p,&e->data.o); } /* * void pane_front(pane p) * * Use * Moves a tool window and associated panes to the front of the screen. * * Parameters * pane p == the pane handle */ void pane_front(pane p) { wimp_wstate s; wimpt_noerr(wimp_get_wind_state(p->tool,&s)); s.o.behind=-1; pane__doMove(p,&s.o); } /* * void pane_close(pane p) * * Use * This routine will close all the windows attached to the pane structure. * * Parameters * pane p == the pane handle */ void pane_close(pane p) { pane__paneItem *i=p->panes; wimpt_noerr(wimp_close_wind(p->tool)); while (i) { wimpt_noerr(wimp_close_wind(i->pane)); i=i->next; } }