|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: H T
Length: 18592 (0x48a0) Types: TextFile Names: »HPane.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/Toolkit/DECToolkit/src/HPane.c«
/* * $Source: /u1/X/DECToolkit/src/RCS/HPane.c,v $ * $Header: HPane.c,v 1.1 86/12/17 09:01:58 swick Exp $ */ #ifndef lint static char *rcsid_HPane_c = "$Header: HPane.c,v 1.1 86/12/17 09:01:58 swick Exp $"; #endif lint #ifndef lint static char *sccsid = "@(#)HPane.c 1.4 12/11/86"; #endif lint /* * COPYRIGHT 1986 * DIGITAL EQUIPMENT CORPORATION * MAYNARD, MASSACHUSETTS * ALL RIGHTS RESERVED. * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT * SET FORTH ABOVE. * * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting documentation, * and that the name of Digital Equipment Corporation not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. */ /* Basic code outline by Smokey Wallace modification by Harry Hersh */ #include <stdio.h> #include <X/Xlib.h> #include "Toolkit.h" #include "horiz_arrow.cursor" #include "horiz_arrow_mask.cursor" /* Paned window are a major organizing device for application programs. * They consist of an overall frame, within which tiled subwindows can be * added, removed, and varied in width, both by the user and by the program. * The subwindows extend the full height of the window frame. The subwindows * within a paned window frame are completely general: they are typically * used as variable windows for text or graphics editing and for other * applications where a user would want direct control over the relative * size of windows. */ /* Private Definitions */ /* -----> Defines */ #define BORDERWIDTH 1 #define KNOBWIDTH 9 #define KNOBHEIGHT 9 typedef struct { Window w; /* Subwindow */ int x; /* Location in master window */ int min, max; /* Minimum and maximum width. */ short autochange; /* Whether we're allowed this subwindow's width without an explicite command from the user. */ int width; /* Current width. */ int dwidth; /* Desired width. */ Window knob; /* The knob for this subwindow. */ } PanelInfo, *PanelPtr; typedef struct { Window window; /* Window containing everything. */ int width, height; /* Dimension of master window. */ int widthused; /* Total width used by subwindows. */ int numpanels; /* How many windows within it. */ PanelInfo *sub; /* Array of info about the sub windows. */ int whichtracking; /* Which knob we are tracking, if any */ int tracklocation; /* The current track line. */ int refiguremode; /* Whether to refigure things right now. */ } WindowFrameInfo, *WindowFramePtr; /* -----> Static Variables */ static int initialized = FALSE; static int WindowFrameEntry; static Initialize() { WindowFrameEntry = UniqueEntryType(); initialized = TRUE; } /* -----> Utilities */ static WindowFramePtr WindowFramePtrFromWindow(w) Window w; { WindowFramePtr ctx; if (FindEntry(w, WindowFrameEntry, &ctx) != ERRNONE) return FALSE; return ctx; } static TryResize(ctx, newwidth, newheight) WindowFramePtr ctx; int newwidth, newheight; { WindowBox requestBox, replyBox; int result; requestBox.x = 0; requestBox.y = 0; if (newwidth < 1) newwidth = 1; if (newheight < 1) newheight = 1; requestBox.w = newwidth; requestBox.h = newheight; result = TMakeGeometryRequest(ctx->window, resize, &requestBox, &replyBox); if (result == REQUESTALMOST) { requestBox = replyBox; result = TMakeGeometryRequest(ctx->window, resize, &requestBox, &replyBox); } if (result == REQUESTYES) { ctx->width = replyBox.w; ctx->height = replyBox.h; return TRUE; } return FALSE; } static RefigureHLocations(ctx, position) WindowFramePtr ctx; int position; { PanelPtr sub; int i, old, x, kx, ky; if (ctx->numpanels == 0 || !ctx->refiguremode) return; ctx->widthused = 0; for (i = 0, sub = ctx->sub; i < ctx->numpanels; i++, sub++) { if (sub->dwidth < sub->min) sub->dwidth = sub->min; if (sub->dwidth > sub->max) sub->dwidth = sub->max; ctx->widthused += sub->dwidth; } ctx->widthused += BORDERWIDTH * (ctx->numpanels - 1); sub = &(ctx->sub[position]); while (ctx->widthused != ctx->width) { if (sub->autochange) { old = sub->dwidth; sub->dwidth = ctx->width - ctx->widthused + old; if (sub->dwidth < sub->min) sub->dwidth = sub->min; if (sub->dwidth > sub->max) sub->width = sub->max; ctx->widthused += (sub->dwidth - old); } sub++; if (sub - ctx->sub == ctx->numpanels) sub = ctx->sub; if (sub - ctx->sub == position) break; } if (ctx->widthused != ctx->width) TryResize(ctx, ctx->width, ctx->height); x = -BORDERWIDTH; for (i = 0, sub = ctx->sub; i < ctx->numpanels; i++, sub++) { if (x != sub->x || sub->dwidth != sub->width) { if (sub->dwidth == sub->width) XMoveWindow(sub->w, x, -BORDERWIDTH); else XConfigureWindow(sub->w, x, -BORDERWIDTH, sub->dwidth, ctx->height); sub->x = x; sub->width = sub->dwidth; } x += sub->dwidth + BORDERWIDTH; } ky = ctx->height - KNOBHEIGHT; for (i = 0, sub = ctx->sub; i < ctx->numpanels; i++, sub++) { kx = sub->x + sub->width - (KNOBWIDTH / 2); if (i == ctx->numpanels - 1) kx = -99; XMoveWindow(sub->knob, kx, ky); } } static DrawHTrackLine(ctx) WindowFramePtr ctx; { XLine(ctx->window, ctx->tracklocation, 0, ctx->tracklocation, ctx->height, 1, 1, ~0, GXinvert, AllPlanes); } /* =================================================================== */ /* Semi-Public Procedures. */ static WindowFrameGeometryRequest() { return REQUESTNO; } static HandleExposeWindow(event) XExposeWindowEvent *event; { WindowFramePtr ctx; int i; if (event->type == ResizeWindow && event->subwindow == 0) { ctx = WindowFramePtrFromWindow(event->window); if (!ctx) return ERRNOTFOUND; if (ctx->height != event->height || ctx->width != event->width) { if (ctx->height != event->height) { for (i = 0; i < ctx->numpanels; i++) { XChangeWindow(ctx->sub[i].w, ctx->sub[i].width, event->height); } } ctx->width = event->width; ctx->height = event->height; for (i = ctx->numpanels - 1; i > 0 && !(ctx->sub[i].autochange); i--); RefigureHLocations(ctx, i); } return PROCESSED; } return NOTHANDLED; } static HandleKnob(event) XButtonEvent *event; { WindowFramePtr ctx; int position, diff, x, y; Window subw; ctx = WindowFramePtrFromWindow(event->window); if (!ctx) return ERRNOTFOUND; for (position = 0; position < ctx->numpanels; position++) if (ctx->sub[position].knob == event->window) break; if (position >= ctx->numpanels) return NOTHANDLED; XInterpretLocator(ctx->window, &x, &y, &subw, event->location); switch (event->type) { case ButtonPressed: if (ctx->whichtracking != -1) return NOTHANDLED; ctx->whichtracking = position; ctx->tracklocation = -99; XClipDrawThrough(ctx->window); /* Fall through */ case MouseMoved: case ButtonReleased: if (ctx->whichtracking == -1) return NOTHANDLED; DrawHTrackLine(ctx); /* Erase old line */ ctx->tracklocation = x; if (event->type != ButtonReleased) { DrawHTrackLine(ctx);/* Draw new line */ return PROCESSED; } position = ctx->whichtracking; diff = ctx->tracklocation - (ctx->sub[position].x + ctx->sub[position].width); ctx->sub[position].dwidth += diff; if (position == ctx->numpanels - 2) ctx->sub[position + 1].dwidth -= diff; XClipClipped(ctx->window); RefigureHLocations(ctx, position + 1); ctx->whichtracking = -1; return PROCESSED; } return NOTHANDLED; } /* =================================================================== */ /* Public Procedures. */ /* * This procedure makes a paned window frame from an existing window * for one or more horizontally arranged tiled windows. */ Status TMakeHWindowFrame(w) Window w; { WindowFramePtr ctx; WindowInfo info; /* -----> Perform initialization */ if (!initialized) Initialize(); /* -----> Set up data frame data structure */ ctx = (WindowFramePtr) Tmalloc(sizeof(WindowFrameInfo)); SaveEntry(w, WindowFrameEntry, ctx); XQueryWindow(w, &info); ctx->window = w; ctx->width = info.width; ctx->height = info.height; ctx->widthused = 0; ctx->numpanels = 0; ctx->sub = (PanelInfo *) Tmalloc(1); ctx->whichtracking = -1; ctx->refiguremode = TRUE; TSetXEventDispatch(w, HandleExposeWindow, ExposeWindow, 0); } /* ================================================================= */ /* * Deletes the paned window Frame, including the OpaqueFrame * structure associated with it. */ Status TDeleteHWindowFrame(w) Window w; { WindowFramePtr ctx; int i; ctx = WindowFramePtrFromWindow(w); if(!ctx) return ERRNOTFOUND; XUnmapWindow(w); for (i=ctx->numpanels-1 ; i>=0 ; i--) TDeleteFromHWindowFrame(w, ctx->sub[i].w); DeleteEntry(w, WindowFrameEntry); free(ctx->numpanels); free(ctx); } /* ================================================================= */ /* * Adds a sub-window to the paned window in a particular location by * readjusting the height of any permitted sub-windows within their * specified bounds. */ Window TAddToHWindowFrame(w, arglist) Window w; /* Window frame */ Targ * arglist; { WindowFramePtr ctx; Window pw; int i, needed, position; int status; PanelPtr sub; Pixmap border, bkground; int x; int min, max; short autochange; int width; int dwidth; ctx = WindowFramePtrFromWindow(w); if(!ctx) return ERRNOTFOUND; ctx->numpanels++; ctx->sub = (PanelPtr) Trealloc(ctx->sub, ctx->numpanels * sizeof(PanelInfo)); /* -----> Set Defaults */ pw = NULL; position = ctx -> numpanels - 1; border = BlackPixmap; bkground = WhitePixmap; x = ctx -> width; width = ctx -> width / ctx -> numpanels; min = KNOBWIDTH + 1; max = ctx -> width; autochange = TRUE; /* -----> Parse Arguments */ while (arglist -> name) { switch (arglist -> name) { case T_PANED_WINDOW: pw = (Window) arglist -> data; break; case T_PANED_ORIENT: break; case T_PANED_POSITION: position = (int) arglist -> data; break; case T_PANED_HEIGHT: break; case T_PANED_WIDTH: width = (int) arglist -> data; break; case T_PANED_MIN: min = (int) arglist -> data; break; case T_PANED_MAX: max = (int) arglist -> data; break; case T_PANED_AUTOCHANGE: autochange = (short) arglist -> data; break; case T_PANED_BRCOLOR: border = (int) arglist -> data; break; case T_PANED_BACKGROUND: bkground = (int) arglist -> data; break; default: break; } arglist++; } for (i = ctx->numpanels - 1; i > position; i--) ctx->sub[i] = ctx->sub[i - 1]; sub = &(ctx->sub[position]); sub->w = pw; sub->x = x; sub->width = sub->dwidth = width; sub->autochange = autochange; sub->min = min; sub->max = max; /* -----> Create Window Pane */ if (sub->w == NULL) sub->w = XCreateWindow(w, sub->x, -BORDERWIDTH, sub->width, ctx->height, BORDERWIDTH, border, bkground); else XConfigureWindow(sub->w, sub->x, -BORDERWIDTH, sub->width, ctx->height); needed = sub->width + BORDERWIDTH + ctx->widthused; if (needed > ctx->width) TryResize(ctx, needed, ctx->height); TSetGeometryRequest(sub->w, WindowFrameGeometryRequest); sub->knob = XCreateWindow(ctx->window, -99, -99, KNOBWIDTH, KNOBHEIGHT, 0, 0, BlackPixmap); SaveEntry(sub->knob, WindowFrameEntry, ctx); #ifdef CURSORS XDefineCursor(sub->knob, GetCursor("horiz_arrow")); #else XDefineCursor(sub->knob, XCreateCursor( horiz_arrow_width, horiz_arrow_height, horiz_arrow_bits, horiz_arrow_mask_bits, horiz_arrow_x_hot, horiz_arrow_y_hot, BlackPixel, WhitePixel, GXcopy)); #endif XMapWindow(sub->w); if (min != max) XMapWindow(sub->knob); TSetXEventDispatch(sub->knob, HandleKnob, knobMask, 0); RefigureHLocations(ctx, position); for (i=0 ; i<ctx->numpanels; i++) XRaiseWindow(ctx->sub[i].knob); return(sub->w); } /* ================================================================= */ /* * Removes a sub-window from the paned window and readjust any permitted * sub-windows within their specified bounds. */ Status TDeleteFromHWindowFrame(w, subwindow) Window w, subwindow; { WindowFramePtr ctx; int i, j, r; ctx = WindowFramePtrFromWindow(w); if (!ctx) return ERRNOTFOUND; j = FALSE; for (i = 0; i < ctx->numpanels; i++) { if (ctx->sub[i].w == subwindow) { j = TRUE; DeleteEntry(ctx->sub[i].knob, WindowFrameEntry); XDestroyWindow(ctx->sub[i].knob); r = TryResize(ctx, ctx->width - ctx->sub[i].width - BORDERWIDTH, ctx->height); } if (j && i < ctx->numpanels - 1) ctx->sub[i] = ctx->sub[i + 1]; } if (!j) return; ctx->numpanels--; if (ctx->numpanels > 0) { ctx->sub = (PanelPtr) Trealloc(ctx->sub, ctx->numpanels * sizeof(PanelInfo)); } for (i=ctx->numpanels - 1; i>0 ; i--) if (ctx->sub[i].autochange) break; RefigureHLocations(ctx, i); } /* =================================================================== */ /* * Enables or disables adjustments to pane boundaries. * */ TPanedHRefigureMode(window, mode) Window window; short mode; { WindowFramePtr ctx; int i; ctx = WindowFramePtrFromWindow(window); if (ctx) { ctx->refiguremode = mode; if (mode) { for (i = ctx->numpanels - 1; i > 0; i--) if (ctx->sub[i].autochange) break; RefigureHLocations(ctx, i); } } } /* =================================================================== */ /* * This procedure returns the currently set of arguments, and * other state information. If any errors are detected * during the parsing of the input arguments, an exit will occur. * */ Status TGetHPaneAttr (tw, arglist) Window tw; /* tool window (pane) */ Targ *arglist; { int return_code; /* return code from window creation */ int i; WindowFramePtr ctx; Window *parent, **children; int *nchildren; PanelPtr pane; /* -----> First find parent, then the frame, then the right pane */ return_code = XQueryTree(tw, parent, nchildren, children); if (!return_code) return ERRNOTFOUND; ctx = WindowFramePtrFromWindow(parent); if (!ctx) return ERRNOTFOUND; for (i = 0; i < ctx->numpanels; i++) if(ctx->sub[i].w == tw) pane = &(ctx->sub[i]); if (!pane) return ERRNOTFOUND; /* -----> Parsing input parameters */ while (arglist -> name) { switch (arglist -> name) { case T_PANED_ORIENT: arglist -> data = (caddr_t) FALSE; break; case T_PANED_POSITION: arglist -> data = (caddr_t) FALSE; break; case T_PANED_HEIGHT: arglist -> data = (caddr_t) ctx -> height; break; case T_PANED_WIDTH: arglist -> data = (caddr_t) pane -> width; break; case T_PANED_MIN: arglist -> data = (caddr_t) pane -> min; break; case T_PANED_MAX: arglist -> data = (caddr_t) pane -> max; break; case T_PANED_AUTOCHANGE: arglist -> data = (caddr_t) pane ->autochange; break; default: break; } arglist++; } } /* =================================================================== */ /* * This procedure sets or changes arguments for a paned window. * If any errors are detected during the parsing of the input arguments, * an exit will occur. */ Status TSetHPaneAttr (tw, arglist) Window tw; /* tool window */ Targ *arglist; { int return_code; /* return code from window creation */ int i; WindowFramePtr ctx; Window *parent, **children; int *nchildren; PanelPtr pane; /* -----> First find parent, then the frame, then the right pane */ return_code = XQueryTree(tw, parent, nchildren, children); if (!return_code) return ERRNOTFOUND; ctx = WindowFramePtrFromWindow(parent); if (!ctx) return ERRNOTFOUND; for (i = 0; i < ctx->numpanels; i++) if(ctx->sub[i].w == tw) pane = &(ctx->sub[i]); if (!pane) return ERRNOTFOUND; /* -----> Parsing input parameters */ while (arglist -> name) { switch (arglist -> name) { case T_PANED_ORIENT: arglist -> data = (caddr_t) HORIZONTAL; break; case T_PANED_POSITION: arglist -> data = (caddr_t) FALSE; break; case T_PANED_HEIGHT: arglist -> data = (caddr_t) ctx -> height; break; case T_PANED_WIDTH: arglist -> data = (caddr_t) pane -> width; break; case T_PANED_MIN: arglist -> data = (caddr_t) pane -> min; break; case T_PANED_MAX: arglist -> data = (caddr_t) pane -> max; break; case T_PANED_AUTOCHANGE: arglist -> data = (caddr_t) pane ->autochange; break; default: break; } arglist++; } RefigureHLocations (ctx, 1); }