home *** CD-ROM | disk | FTP | other *** search
- /* code to manage the stuff on the sky view filter display.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #if defined(__STDC__)
- #include <stdlib.h>
- #endif
- #include <X11/Xlib.h>
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/DrawingA.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/RowColumn.h>
- #include <Xm/ToggleB.h>
- #include <Xm/Text.h>
- #include <Xm/Scale.h>
- #include <Xm/Separator.h>
- #include "astro.h"
- #include "circum.h"
-
- /* info for each filter option toggle */
- typedef struct {
- char *label; /* label on the toggle button */
- char *name; /* name of toggle button, for resource setting */
- int type; /* as in Obj.type */
- char class; /* as in Obj.f.f_class */
- char state; /* 0 or 1 depending on whether this class is on */
- Widget tbw; /* the toggle button widget */
- } FilterTB;
-
- /* info for a set of filters forming a category */
- typedef struct {
- char *label; /* label for this category */
- FilterTB *ftb; /* array of toggle button filters in this class */
- int nftb; /* entries in ftb[] */
- Widget pbw; /* the category "toggle" pushbutton */
- } FilterCat;
-
- #if defined(__STDC__) || defined(__cplusplus)
- #define P_(s) s
- #else
- #define P_(s) ()
- #endif
-
- extern Now *mm_get_now P_((void));
- extern void get_something P_((Widget w, char *resource, char *value));
- extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
- extern void sv_all P_((Now *np, int preclr));
- extern void sv_draw_obj P_((Display *dsp, Drawable win, GC gc, Obj *op, int x, int y, int diam, int dotsonly));
-
- void svf_create P_((void));
- void svf_manage_toggle P_((void));
- void svf_manage P_((void));
- void svf_unmanage P_((void));
- int svf_filter_ok P_((Obj *op));
- void svf_cursor P_((Cursor c));
- static void svf_create_filter P_((Widget mainrc, FilterCat *fcp));
- static void svf_reset P_((void));
- static void svf_apply P_((void));
- static void svf_da_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_draw_symbol P_((FilterTB *ftbp, Widget daw));
- static void svf_apply_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_ok_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_close_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_all_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_reset_cb P_((Widget w, XtPointer client, XtPointer call));
- static void svf_cat_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
-
- #undef P_
-
- extern Widget toplevel_w;
- #define XtD XtDisplay(toplevel_w)
-
- static FilterTB solsys_f[] = {
- {"Planets", "Planets", PLANET, 0},
- {"Elliptical", "Elliptical", ELLIPTICAL, 0},
- {"Hyperbolic", "Hyperbolic", HYPERBOLIC, 0},
- {"Parabolic", "Parabolic", PARABOLIC, 0}
- };
-
- static FilterTB other_f[] = {
- {"Q Quasars", "Quasars", FIXED, 'Q'},
- {"T Stellar", "Stellar", FIXED, 'T'},
- {"Undefined", "Undefined", FIXED, '\0'}
- };
-
- static FilterTB stars_f[] = {
- {"S Single", "Stars", FIXED, 'S'},
- {"B Binary", "Binary", FIXED, 'B'},
- {"D Double", "Double", FIXED, 'D'},
- {"M Multiple", "Multiple", FIXED, 'M'},
- {"V Variable", "Variable", FIXED, 'V'}
- };
-
- static FilterTB nebulea_f[] = {
- {"N Bright", "BrightNeb", FIXED, 'N'},
- {"F Diffuse", "DiffuseNeb", FIXED, 'F'},
- {"K Dark", "DarkNeb", FIXED, 'K'},
- {"P Planetary", "PlanetaryNeb", FIXED, 'P'}
- };
-
- static FilterTB galaxies_f[] = {
- {"G Spiral", "SpiralGal", FIXED, 'G'},
- {"H Spherical", "SphericalGal", FIXED, 'H'},
- {"A Clusters", "GalClusters", FIXED, 'A'}
- };
-
- static FilterTB clusters_f[] = {
- {"C Globular", "GlobularCl", FIXED, 'C'},
- {"O Open", "OpenCl", FIXED, 'O'},
- {"U in Nebula", "ClInNeb", FIXED, 'U'}
- };
-
- static FilterCat filters[] = {
- {"Solar System:", solsys_f, XtNumber(solsys_f)},
- {"Clusters:", clusters_f, XtNumber(clusters_f)},
- {"Galaxies:", galaxies_f, XtNumber(galaxies_f)},
- {"Nebulea:", nebulea_f, XtNumber(nebulea_f)},
- {"Stars:", stars_f, XtNumber(stars_f)},
- {"Other:", other_f, XtNumber(other_f)}
- };
-
- /* these form rapid lookup tables for the state of an object.
- * they can be directly indexed by Obj.type and Obj.f.f_class, respectively.
- */
- static char fclass_table[128];
- static char type_table[10];
-
- static Widget filter_w;
-
- /* create, but do not manage, the filter dialog.
- * we also apply its state info immediately to the initial resource
- * settings of the toggle buttons are used to set up the real filter
- * right away.
- */
- void
- svf_create()
- {
- static struct {
- char *name;
- void (*cb)();
- } ctls[] = {
- {"Ok", svf_ok_cb},
- {"Apply", svf_apply_cb},
- {"All", svf_all_cb},
- {"Toggle All", svf_toggle_cb},
- {"Reset", svf_reset_cb},
- {"Close", svf_close_cb}
- };
- Arg args[20];
- XmString str;
- Widget w;
- Widget ctlf_w;
- Widget topsep_w, botsep_w;
- Widget hrc_w;
- int n;
- int i;
-
- /* create form */
- n = 0;
- XtSetArg (args[n], XmNautoUnmanage, False); n++;
- XtSetArg (args[n], XmNdefaultPosition, False); n++;
- filter_w = XmCreateFormDialog (toplevel_w, "SkyFilter", args, n);
- XtAddCallback (filter_w, XmNmapCallback, prompt_map_cb, NULL);
-
- /* set some stuff in the parent DialogShell.
- * setting XmNdialogTitle in the Form didn't work..
- */
- n = 0;
- XtSetArg (args[n], XmNtitle, "xephem Sky view Filter"); n++;
- XtSetValues (XtParent(filter_w), args, n);
-
- /* make a separator across the top */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- topsep_w = XmCreateSeparator (filter_w, "TopSep", args, n);
- XtManageChild (topsep_w);
-
- /* make a form for bottom control panel */
-
- n = 0;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNfractionBase, 25); n++;
- XtSetArg (args[n], XmNverticalSpacing, 5); n++;
- ctlf_w = XmCreateForm (filter_w, "SVControlF", args, n);
- XtManageChild (ctlf_w);
-
- /* add the control buttons */
-
- for (i = 0; i < XtNumber(ctls); i++) {
- str = XmStringCreateLtoR(ctls[i].name,XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 1+i*4); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 4+i*4); n++;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreatePushButton (ctlf_w, "FilterCB", args, n);
- XtManageChild(w);
- XmStringFree (str);
- XtAddCallback (w, XmNactivateCallback, ctls[i].cb, NULL);
- }
-
- /* put a separator on top of the control panel */
-
- n = 0;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
- botsep_w = XmCreateSeparator (filter_w, "BotSep", args, n);
- XtManageChild (botsep_w);
-
- /* make a horizontal rowcol to contain each column */
-
- n = 0;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, botsep_w); n++;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, topsep_w); n++;
- XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
- XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
- XtSetArg (args[n], XmNspacing, 0); n++;
- XtSetArg (args[n], XmNmarginWidth, 0); n++;
- hrc_w = XmCreateRowColumn (filter_w, "CategoryTableRC", args, n);
- XtManageChild (hrc_w);
-
- /* fill the horizontal rc with each FilterCat */
-
- for (i = 0; i < XtNumber(filters); i++)
- svf_create_filter (hrc_w, &filters[i]);
-
- /* set the real filter according to the state of the toggle buttons */
- svf_apply();
- }
-
- /* called to toggle whether the filter dialog is up.
- * whenever we are managed, reset the state of the toggle buttons back
- * to the way the real filter is.
- */
- void
- svf_manage_toggle ()
- {
- if (XtIsManaged(filter_w))
- svf_unmanage();
- else
- svf_manage();
- }
-
- /* called to manage the filer dialog.
- * whenever we are managed, reset the state of the toggle buttons back
- * to the way the real filter is.
- */
- void
- svf_manage()
- {
- svf_reset();
- XtManageChild(filter_w);
- }
-
- void
- svf_unmanage()
- {
- XtUnmanageChild(filter_w);
- }
-
- /* return 1 if p satisfies the stuff in the filter dialog, else 0.
- * N.B. because svf_apply() has to have already been called we do not need
- * to range check the type and class.
- */
- svf_filter_ok (op)
- Obj *op;
- {
- int t = op->type;
-
- if (t == FIXED)
- return (fclass_table[op->f_class]);
- else
- return (type_table[t]);
- }
-
- /* called to put up or remove the watch cursor. */
- void
- svf_cursor (c)
- Cursor c;
- {
- Window win;
-
- if (filter_w && (win = XtWindow(filter_w))) {
- Display *dsp = XtDisplay(filter_w);
- if (c)
- XDefineCursor (dsp, win, c);
- else
- XUndefineCursor (dsp, win);
- }
- }
-
- /* create one FilterCat filter category in the given RowColumn */
- static void
- svf_create_filter (mainrc, fcp)
- Widget mainrc;
- FilterCat *fcp;
- {
- Arg args[20];
- Widget l_w;
- Widget rc_w; /* rc for the label and controls */
- Widget fr_w, da_w;
- Widget w;
- int n;
- int i;
-
- /* make a rc within a frame for the tb rowcol */
-
- n = 0;
- fr_w = XmCreateFrame (mainrc, "Frame", args, n);
- XtManageChild (fr_w);
- n = 0;
- XtSetArg (args[n], XmNmarginWidth, 0); n++;
- XtSetArg (args[n], XmNisAligned, False); n++;
- rc_w = XmCreateRowColumn (fr_w, "CategoryRC", args, n);
- XtManageChild (rc_w);
-
- /* make a label for the category */
-
- n = 0;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- l_w = XmCreateLabel (rc_w, fcp->label, args, n);
- XtManageChild (l_w);
-
- /* make a pushbutton used to toggle all entries in this category */
- n = 0;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
- w = XmCreatePushButton (rc_w, "Toggle", args, n);
- XtAddCallback (w, XmNactivateCallback, svf_cat_toggle_cb,
- (XtPointer)fcp);
- XtManageChild (w);
-
- /* add each filter */
-
- for (i = 0; i < fcp->nftb; i++) {
- Widget f_w;
- Widget tb_w;
- FilterTB *ftbp = &fcp->ftb[i];
- XmString str;
-
- n = 0;
- f_w = XmCreateForm (rc_w, "FTBF", args, n);
- XtManageChild (f_w);
-
- /* create a frame around a drawing area in which to show the
- * object symbol
- */
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
- fr_w = XmCreateFrame (f_w, "SymbolF", args, n);
- XtManageChild (fr_w);
- n = 0;
- da_w = XmCreateDrawingArea (fr_w, "SymbolDA", args, n);
- XtAddCallback (da_w, XmNexposeCallback, svf_da_cb,
- (XtPointer)ftbp);
- XtManageChild (da_w);
-
- /* create the filter selection toggle button */
-
- str = XmStringCreateLtoR (ftbp->label,XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNleftWidget, fr_w); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- tb_w = XmCreateToggleButton (f_w, ftbp->name, args, n);
- XmStringFree(str);
- XtManageChild (tb_w);
- ftbp->tbw = tb_w;
- }
- }
-
- /* set the toggle button states according to the real filter states.
- */
- static void
- svf_reset()
- {
- int i, j;
-
- for (i = 0; i < XtNumber(filters); i++) {
- FilterCat *fcp = &filters[i];
- for (j = 0; j < fcp->nftb; j++) {
- FilterTB *ftbp = &fcp->ftb[j];
- XmToggleButtonSetState (ftbp->tbw, ftbp->state, True);
- }
- }
- }
-
- /* set the filter according to the present state of the toggle buttons.
- */
- static void
- svf_apply()
- {
- int i, j;
-
- for (i = 0; i < XtNumber(filters); i++) {
- FilterCat *fcp = &filters[i];
- for (j = 0; j < fcp->nftb; j++) {
- FilterTB *ftbp = &fcp->ftb[j];
- int t = ftbp->type;
- if (t < 0 || t >= XtNumber(type_table)) {
- printf ("svf_apply: type out of range: %d\n", t);
- exit (1);
- }
- ftbp->state = XmToggleButtonGetState (ftbp->tbw);
- if (ftbp->type == FIXED) {
- int c = ftbp->class;
- if (c < 0 || c >= XtNumber(fclass_table)) {
- printf ("svf_apply: FIXED class out of range: %d\n", c);
- exit (1);
- }
- fclass_table[c] = ftbp->state;
- } else
- type_table[t] = ftbp->state;
- }
- }
- }
-
- /* called when a symbol drawing area is exposed.
- * client is a pointer to the FilterTB.
- */
- /* ARGSUSED */
- static void
- svf_da_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
- FilterTB *ftbp = (FilterTB *) client;
-
- switch (c->reason) {
- case XmCR_EXPOSE: {
- /* turn off gravity so we get expose events for either shrink or
- * expand.
- */
- static before;
- XExposeEvent *e = &c->event->xexpose;
-
- if (!before) {
- XSetWindowAttributes swa;
- swa.bit_gravity = ForgetGravity;
- XChangeWindowAttributes (e->display, e->window,
- CWBitGravity, &swa);
- before = 1;
- }
- /* wait for the last in the series */
- if (e->count != 0)
- return;
- }
- break;
- default:
- return;
- }
-
- svf_draw_symbol(ftbp, w);
- }
-
- /* draw the symbol used for the object described by ftbp into the
- * DrawingArea widget daw.
- */
- static void
- svf_draw_symbol(ftbp, daw)
- FilterTB *ftbp;
- Widget daw;
- {
- static GC gc;
- Display *dsp = XtDisplay(daw);
- Window win = XtWindow(daw);
- Obj obj;
- Dimension w, h;
- int diam;
-
- obj.type = ftbp->type;
- if (ftbp->type == FIXED)
- obj.f_class = ftbp->class;
-
- get_something (daw, XmNwidth, (char *)&w);
- get_something (daw, XmNheight, (char *)&h);
- diam = (w > h ? h : w) - 2;
-
- if (!gc) {
- XGCValues gcv;
- unsigned gcm;
- Pixel p;
-
- gcm = GCForeground;
- get_something (daw, XmNforeground, (char *)&p);
- gcv.foreground = p;
- gc = XCreateGC (dsp, win, gcm, &gcv);
- }
-
- /* use diam-2 to allow for a little overflow on some symbols */
- sv_draw_obj (dsp, win, gc, &obj, (int)w/2, (int)h/2, diam-2, 0);
- sv_draw_obj (dsp, win, gc, NULL, 0, 0, 0, 0); /* flush */
- }
-
- /* called when Apply is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_apply_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- svf_apply();
- sv_all(mm_get_now(), 1);
- }
-
- /* called when Ok is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_ok_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- svf_apply();
- sv_all(mm_get_now(), 1);
- XtUnmanageChild (filter_w);
- }
-
- /* called when Close is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_close_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XtUnmanageChild (filter_w);
- }
-
- /* called when Toggle is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_toggle_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- int i, j;
-
- for (i = 0; i < XtNumber(filters); i++) {
- FilterCat *fcp = &filters[i];
- for (j = 0; j < fcp->nftb; j++) {
- FilterTB *ftbp = &fcp->ftb[j];
- XmToggleButtonSetState (ftbp->tbw,
- !XmToggleButtonGetState(ftbp->tbw), True);
- }
- }
- }
-
- /* called when All is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_all_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- int i, j;
-
- for (i = 0; i < XtNumber(filters); i++) {
- FilterCat *fcp = &filters[i];
- for (j = 0; j < fcp->nftb; j++) {
- FilterTB *ftbp = &fcp->ftb[j];
- XmToggleButtonSetState (ftbp->tbw, True, True);
- }
- }
- }
-
- /* called when Reset is pushed on the filter dialog */
- /* ARGSUSED */
- static void
- svf_reset_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- svf_reset();
- }
-
- /* called when the "Toggle" button is activated on a particular category.
- * client is the FilterCat pointer.
- */
- /* ARGSUSED */
- static void
- svf_cat_toggle_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- FilterCat *fcp = (FilterCat *) client;
- int i;
-
- for (i = 0; i < fcp->nftb; i++) {
- FilterTB *ftbp = &fcp->ftb[i];
- XmToggleButtonSetState (ftbp->tbw,
- !XmToggleButtonGetState(ftbp->tbw), True);
- }
- }
-