Logo Search packages:      
Sourcecode: randim version File versions  Download package

win_aux.c

/* win_aux.c: auxiliary window-related functions for randim. */

/* 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.  Please see the file "COPYING"
   for details.  If you have not received it along with this program,
   please write to the Free Software Foundation, Inc., 675 Mass. Ave.,
   Cambridge, MA 02139, USA. */

#include "randim.h"

/*********************************************************************/
/* draw-related auxiliary functions */

/* plot_transreps() plot all transformations in small windows. */
void
plot_transreps() {
  int i;
  for (i=0;i<n_trans;i++) plot_transrep(i);
}

/* plot_transrep() plots a representation of the specified transformation
   in its rep. window, generated by a 9x9 pixel square at its center.
   STILL NEEDS TO BE UPDATED FOR 3-D. */
void
plot_transrep(int trans)
{

  float           rxscale, ryscale,
            fx,fy,
            x,y;
  int       ix,iy,
            iix, iiy,
            px,py;

  if (trans > TRANSREPN) return;    /* can only plot what have room for */

  /* set up conversion variables */
  rxscale = oxscale * ((float)rhsize2/hsize2);
  ryscale = oyscale * ((float)rvsize2/vsize2);

  /* Clear window and plot cross. */
  XClearWindow(display,trepWin[trans]);
  if (cmode & 1) {
    XDrawLine(display,trepWin[trans],cgc[trans],rhsize2-15,rvsize2,rhsize2+15,
            rvsize2);
    XDrawLine(display,trepWin[trans],cgc[trans],rhsize2,rvsize2-15,rhsize2,
            rvsize2+15);
    }
  else {
    XDrawLine(display,trepWin[trans],gc,rhsize2-15,rvsize2,rhsize2+15,
            rvsize2);
    XDrawLine(display,trepWin[trans],gc,rhsize2,rvsize2-15,rhsize2,
            rvsize2+15);
    }

  /* iterate through a 9x9 square and attempt to plot the transforms */
  for (ix=-4;ix<5;ix++) {
    fx = (float)ix/rxscale;
    for (iix=0; iix < 4; iix++) {   /* do 16 subpoints within each */
      for (iy=-4;iy<5;iy++) {
      fy = (float)iy/ryscale;
      for (iiy = 0;iiy < 4; iiy++) {
        x = a[trans][0] * fx + a[trans][1] * fy + a[trans][2];
        y = a[trans][3] * fx + a[trans][4] * fy + a[trans][5];
        px = x * rxscale, py = y * ryscale;
        if (rinrange(px,py)) {
          px += (rhsize2 - 1), py += (rvsize2 - 1);
          if (cmode & 1)
            XDrawPoint(display,trepWin[trans],cgc[trans],px,py);
          else
            XDrawPoint(display,trepWin[trans],gc,px,py);
          }
        fy += ((float)abs(iy)/ryscale)/4.0;
        }
      fx += ((float)abs(ix)/rxscale)/4.0;
      }
      }
    }

}

/* edit_rep_aux() interacts with user in specification of a transformation
   by point selection; operates similarly to zoom_point_aux (see below):
   Depending on state, we accept coordinates for T(0,1), T(1,0), and the
    translation part. */
void
edit_rep_aux(Widget w, XtPointer cdata, XEvent *rep, Boolean cont_disp)
{
  static char     stage = 0;
  static float    p[3], q[3];
  int             tzx, tzy;

  /*Get location, plot an "x" there, and convert it*/
  tzx = rep->xbutton.x, tzy = rep->xbutton.y;
  XDrawLine(display,trepWin[tmodn],cgc[tmodn],tzx-3,tzy-3,tzx+3,tzy+3);
  XDrawLine(display,trepWin[tmodn],cgc[tmodn],tzx-3,tzy+3,tzx+3,tzy-3);
  p[stage] = ((float) (tzx - rhsize2) / (float) rhsize2);
  q[stage] = ((float) (tzy - rvsize2) / (float) rvsize2);

  switch (++stage) {
  case 1:
    message("Select T(1,0)");
    break;
  case 2:
    message("Select (e,f)");
    break;
  case 3:
    message(" ");

    /*don't need to be called anymore*/
    XtRemoveEventHandler(trepWidg[tmodn],ButtonPressMask,False,
                   (XtEventHandler) edit_rep_aux,0);
    stage = 0;

    /*Compute new a[tmodn].  Currently, this means a=p0,b=p1,c=q0,d=q1,
      e=p2,f=q2.*/
    a[tmodn][0] = p[0];
    a[tmodn][1] = p[1];
    a[tmodn][3] = q[0];
    a[tmodn][4] = q[1];
    a[tmodn][2] = p[2];
    a[tmodn][5] = q[2];

    panel_on();
    add_trans();
    break;
    }
}

/* zoom_point_aux() gets called when the mouse button is pressed and sets
   the zoompoint accordingly*/
void
zoom_point_aux(Widget w, XtPointer cdata, XEvent *rep, Boolean cont_disp)
{
  int tzx, tzy;

  /*don't need to be called anymore*/
  XtRemoveEventHandler(cwidg,ButtonPressMask,False,
                   (XtEventHandler) zoom_point_aux,0);

  /*get location info from buttonpress event*/
  tzx = rep->xbutton.x, tzy = rep->xbutton.y;

  /*do calculation stuff*/
  zoom_calc(tzx,tzy,zmag,zmag);
  panel_on();
  plottedpoints = 0;
  message("");
  XClearWindow(display,canvas);
}

/* zoom_rect_aux() gets called whenever mouse moves with button down; draws
   a rectangle to indicate where zoom will take place, and when button
   released, fixes location and computes zoom info*/
void
zoom_rect_aux(Widget w, XtPointer cdata, XEvent *rep, Boolean cont_disp)
{
  static int      x1,x2,y1,y2,       /*coordinates of user-entered rectangle*/
            pxo,pxn,pyo,pyn; /*used to draw selection rectangle*/
  static char     first = 1,   /*need to undraw previous rect?*/
            done = 0;    /*flag to show when selected*/

  switch (rep->type) {
  case ButtonPress:
    x1 = rep->xbutton.x, y1 = rep->xbutton.y;
    break;
  case ButtonRelease:
    x2 = rep->xbutton.x, y2 = rep->xbutton.y;
    done = 1;
    break;
  case MotionNotify:    /*only ButtonMotion events come here*/
    pxn = rep->xmotion.x, pyn = rep->xmotion.y;
    if (!first)   /*undraw oldrect*/
      XDrawRectangle(display,canvas,gc,x1,y1,pxo-x1,pyo-y1);
    else
      first = 0;
    /*should check that user moved mouse bottom right*/
    XDrawRectangle(display,canvas,gc,x1,y1,pxn-x1,pyn-y1);
    pxo = pxn, pyo = pyn;
    break;
  default:  /*just in case unwanted event trickles in*/
    break;
    }

  if (done) {
    int           crx,cry,dx,dy;    /*size and center of rectangle*/
    float   xmag,ymag;

    XtRemoveEventHandler(cwidg,ButtonPressMask|ButtonReleaseMask|
                   ButtonMotionMask,False,
                   (XtEventHandler) zoom_rect_aux,0);

    /*Now we've got the info - just need to do the easy part - compute*/
    dx = x2 - x1, dy = y2 - y1;
    crx = x1 + dx / 2.0, cry = y1 + dy / 2.0;
    xmag = (float) hsize / dx, ymag = (float) vsize / dy;
    zoom_calc(crx,cry,xmag,ymag);

    /*reset the stuff we messed up earlier*/
    XSetFunction(display,gc,GXcopy); /*reset for plotting*/
    panel_on();
    message("");
    XClearWindow(display,canvas);
    done = 0, first = 1;
    }

}

/* zoom_calc() calculates new scaling factors given a point and a magnitude
   for zooming.  Scale calculated simply by multiplying old scales by
    magnification.  Offset is calculated by reverse-transforming the point
    given and computing the necessary offset so that it will be sent to 0,0
    (screen center) when mapped with the new scale.*/
void
zoom_calc(int tzx, int tzy, float xmag, float ymag)
{
  /*Adjust cumulative magnification.*/
  zxmag *= xmag;
  zymag *= ymag;

  /*Calculate offsets and scales.*/
  xoffset = -((tzx - hsize2 - xoffset) * xmag);
  yoffset = -((tzy - vsize2 - yoffset) * ymag);
  xscale *= xmag;
  yscale *= ymag;

  zoomf = 1;

}


/*********************************************************************/
/* general auxiliary functions */

/*This function outputs stuff in label area.*/
void
message(char *s)
{
  arg[0].name = XtNlabel, arg[0].value = (XtArgVal) s;
  XtSetValues(mmlabel[0],arg,1);    /*use 1st label for messages*/
}

/*This function outputs a kind of progress bar.*/
void
dotmsg(char reset)
{
  static char dotstring[MAXDOTS+1];

  if (reset) strcpy(dotstring,"");
  else strcat(dotstring,".");

  message(dotstring);
}

/*disable main panel during other operations*/
void
panel_off()
{
  if (drawflag) {
    XtRemoveWorkProc(DrawID); /*Stop drawing*/
    drawflag = 0;
  }
  arg[0].name = XtNsensitive, arg[0].value = (XtArgVal) False;
  XtSetValues(mpanel,arg,1);  /*Turn off sensitivity of main window*/
  transreps_off(); /*deactivate button sensitivity of transrep windows*/
}

/*re-enable main panel*/
void
panel_on()
{
  arg[0].name = XtNsensitive, arg[0].value = (XtArgVal) True;
  XtSetValues(mpanel,arg,1);  /*Turn on main window*/
  resume_draw(); /* turn background drawing proc back on */
  transreps_on(); /*turn on button sensitivity of transrep windows*/
}

/* disable transformation rep responsiveness to button presses */
void
transreps_off()
{
  int i;

  for (i=0;i<TRANSREPN;i++)
    XtRemoveEventHandler(trepWidg[i],ButtonPressMask,False,
                   (XtEventHandler) trep_bpress,&repdat[i]);
}

/* re-enable transrep responsiveness */
void
transreps_on()
{
  int i;

  for (i=0;i<TRANSREPN;i++)
    XtAddEventHandler(trepWidg[i],ButtonPressMask,False,
                  (XtEventHandler) trep_bpress,&repdat[i]);
}

/* resize() called on drawing window resizes: sets screensize variables
   according to the new size and calls for a rescale.*/
void
resize(Widget w, XtPointer cdata, XEvent *rep, Boolean cont_disp)
{
  if (rep->type == ConfigureNotify) {
    panel_off();
    hsize = rep->xconfigure.width;
    vsize = rep->xconfigure.height;
    hsize2 = floor(hsize/2.0);
    vsize2 = floor(vsize/2.0);
    XFreePixmap(display,hcanvas);
    hcanvas = XCreatePixmap(display,canvas,hsize,vsize,depth);
    scale(SCALE_MAX);
    XClearWindow(display,canvas);
    panel_on();
  }

}

/* rep_resize() called on transrep window resizes: resets local screensize
   variables and redisplays their contents. */
void
rep_resize(Widget w, XtPointer cdata, XEvent *rep, Boolean cont_disp)
{
  int       i;

  if (rep->type == ConfigureNotify) {
    rhsize2 = (rep->xconfigure.width - 4) / 2;
    rvsize2 = floor(rep->xconfigure.height/8.0 - 4.0) / 2;  
  }
  plot_transreps();
}


/**********************************************************************/
/*Dialog i/o smoothing utilities*/

/*Reads an integer from a dialog value string*/
int
dialog_get_int(Widget w)
{
  char *s;
  int i;

  s = XawDialogGetValueString(w);
  sscanf(s,"%d",&i);
  return(i);
}

/*Transfers an integer to a dialog value string*/
void
dialog_set_int(Widget w, int i)
{
  char s[10];

  sprintf(s,"%d",i);
  arg[0].name = XtNvalue, arg[0].value = (XtArgVal) s;
  XtSetValues(w,arg,1);
}

/*Reads a float from a dialog value string*/
float
dialog_get_float(Widget w)
{
  char *s;
  float f;

  s = XawDialogGetValueString(w);
  sscanf(s,"%f",&f);
  return(f);
}

/*Transfers a float to a dialog value string*/
void
dialog_set_float(Widget w, float f)
{
  char s[10];

  sprintf(s,"%7f",f);
  arg[0].name = XtNvalue, arg[0].value = (XtArgVal) s;
  XtSetValues(w,arg,1);
}


/* convert decimal byte to hex; rtn must be at least a 3 char string */
void
itoh(int byteval, char *rtn) {
  static char     hex[16] =
              { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F' };

  if ((byteval < 0) || (byteval > 255)) {
    rtn[0] = '\0';
    printf("%d\n",byteval);
    }
  else {
    rtn[0] = hex[byteval / 16];
    rtn[1] = hex[byteval % 16];
    rtn[2] = '\0';
    }
}


/* calculate brightness of an XColor */
int
brightness(XColor color)
{
  return color.red + color.green + color.blue;
}


/*Function getnextline gets the next line of input from the file, discarding
  blank lines and comment lines (which begin with a number sign ("#").
  It returns 1 on success, 0 if eof reached. */
char
getnextline(FILE *fp,char *line)
{
    char        *tpos, c,
                done, eflag;

    /*get to next line of data*/
    for (done=0;!done;) {
        c = getc(fp);
      if (feof(fp)) return(0);
        if (c == '#')
            while (c != '\n') c=getc(fp); // go to end of line
        if (c != '\n')
            done = 1;
        }

    /*read in line*/
    while(isspace(c)) c=getc(fp);       // skip any indentation
    for (tpos=line;c!='\n';c=getc(fp))
        *tpos++ = c;
    
    *tpos = '\0';

    /* printf("%s\n",line); */

    return(1);

}

Generated by  Doxygen 1.6.0   Back to index