Edit

IABSD.fr/xenocara/app/xgc/choice.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2006-11-25 20:07:29
    Hash : 616b6f15
    Message : Importing from X.Org 7.2RC2

  • app/xgc/choice.c
  • /* $XFree86$ */
    /*
    ** xgc
    **
    ** choice.c
    **
    ** All the generic stuff for dealing with choice widgets.
    */
    
    #include <stdio.h>
    #include <X11/Intrinsic.h>
    #include <X11/StringDefs.h>
    #include <X11/Xaw/Form.h>
    #include <X11/Xaw/Label.h>
    #include <X11/Xaw/Toggle.h>
    
    #include "xgc.h"
    
    static void print_text_to_buffer(Widget, caddr_t, caddr_t);
    
    /* create_choice(w,info)
    ** ---------------------
    ** What a choice widget is:  A collection of toggle buttons placed inside
    ** a form widget.  Exactly one of these toggle buttons can be "on" at
    ** any given time;  the rest are "off".  "On" toggle buttons have
    ** the foreground and background colors reversed.
    ** Also, specifically because it comes in handy in xgc, choosing one
    ** of the buttons causes a string associated with it to be printed out
    ** (and interpreted).  Half of the string is global to the whole form
    ** and the other half is local to each button.
    **
    ** For example, pressing the "xor" button in the "function" form would
    ** cause xgc to interpret the string "function xor", thus changing the
    ** function in the GC to xor.
    **
    ** There's also a label widget to the left of that mess, with an
    ** incredibly descriptive title.
    **
    ** create_choice() makes one.
    **
    ** w is the form widget (already created) into which we will place the
    ** toggle buttons.  info contains lots of useful information, such
    ** as the names of the buttons and their strings (see xgc.h).
    */
    
    ChoiceDesc *
    create_choice(Widget w, XgcStuff *info)
    {
      ChoiceDesc *choice;		/* What we will return.  Contains
    				** Widget ID's of the label and toggles. */
      int i;			/* Counter */
      char *text;			/* Text to be interpreted when the
    				** toggle widget is selected. */
    
      /* ArgList for the label widget */
      static Arg labelargs[] = {	
        {XtNborderWidth,  (XtArgVal) 0}, 
        {XtNjustify,      (XtArgVal) XtJustifyRight},
        {XtNvertDistance, (XtArgVal) 4}
      };
    
      /* ArgList for the toggle widgets */
      static Arg toggleargs[] = {
        {XtNfromHoriz,     (XtArgVal) NULL},
        {XtNfromVert,      (XtArgVal) NULL},
        {XtNhorizDistance, (XtArgVal) 4},
        {XtNvertDistance,  (XtArgVal) 4},
        {XtNradioGroup,    (XtArgVal) NULL},
        {XtNcallback,      (XtArgVal) NULL}
      };
    
      /* Callback list for the toggle widgets */
      static XtCallbackRec callbacklist[] = {
        {(XtCallbackProc)  print_text_to_buffer, NULL},
        {NULL,                                   NULL}
      };
    
      /* Allocate space for the widgets and initialize choice */
      choice = (ChoiceDesc *) XtMalloc(sizeof(ChoiceDesc));
      choice->widgets = (WidgetList) XtMalloc(sizeof(Widget) * 
    					  info->choice.num_toggles);
      choice->size = info->choice.num_toggles;
      choice->label = XtCreateManagedWidget(info->choice.name,labelWidgetClass,w,
    					labelargs,XtNumber(labelargs));
    
      /* set up the toggle widgets */
      toggleargs[5].value = (XtArgVal) callbacklist;
      for (i = 0; i < info->choice.num_toggles; ++i) {
        if (i == 0) {
          /* the upper left toggle; put it next to the label
           and don't worry about radio groups */
          toggleargs[0].value = (XtArgVal) choice->label;
          toggleargs[1].value = (XtArgVal) NULL;
          toggleargs[2].value = (XtArgVal) 10;
          toggleargs[3].value = (XtArgVal) 4;
          toggleargs[4].value = (XtArgVal) NULL;
        }
        else {
          toggleargs[4].value = (XtArgVal) choice->widgets[0];
    				/* are we starting a new row? */
          if (info->choice.columns > 0 && 
    	  i > 1 && 
    	  (i % (info->choice.columns) == 0)) {
    	toggleargs[0].value = (XtArgVal) choice->label;
    	/* under the appropriate toggle */
    	toggleargs[1].value = (XtArgVal) choice->widgets[i - info->choice.columns];
    	toggleargs[2].value = (XtArgVal) 10;
    	toggleargs[3].value = (XtArgVal) 4;
          }
          else {			/* we're in the middle of a row */
    	/* to the right of the previous toggle */
    	toggleargs[0].value = (XtArgVal) choice->widgets[i - 1];
    	toggleargs[1].value = (XtArgVal) NULL;
    	toggleargs[2].value = (XtArgVal) -1; /* overlapping slightly */
    	toggleargs[3].value = (XtArgVal) 4;
          }
    
          if (info->choice.columns > 0 &&
    	  i >= info->choice.columns) {
    	/* correct vertical spacing */
    	toggleargs[1].value = (XtArgVal) choice->widgets[i - info->choice.columns];
    	toggleargs[3].value = (XtArgVal) -1;
          }
        }
    
        /* Put the correct stuff in the text field */
        text = (char *) XtMalloc((unsigned) (strlen(info->choice.text) +
    					 strlen((info->data)[i].text) + 3));
        strcpy(text, info->choice.text);
        strcat(text, " ");
        strcat(text, (info->data)[i].text);
        strcat(text, "\n");
        callbacklist[0].closure = (caddr_t) text;
        
        /* Create it finally */
        choice->widgets[i] = XtCreateManagedWidget((info->data[i]).name, 
    					       toggleWidgetClass,
    					       w,
    					       toggleargs,
    					       XtNumber(toggleargs));
      }
      
      /* The toggle widgets have all been created;
      ** now make the all the same width if that's
      ** what we want to do.                    */
    
      if (info->choice.columns > 0) {
        Dimension maxwidth = 0;	/* maximum width we've found */
        Dimension width;		/* width of the current widget */
        static Arg args[] = {	/* for getting and setting the width */
          {XtNwidth,    (XtArgVal) NULL}
        };
    
        args[0].value = (XtArgVal) &width;
    
        /* Find the maximum width of any toggle widget */
        for (i = 0; i < info->choice.num_toggles; ++i) {
          XtGetValues(choice->widgets[i],args,1);
          maxwidth = max(maxwidth,width);
        }
    
        /* Now set them all to that width */
        args[0].value = (XtArgVal) maxwidth;
        for (i = 0; i < info->choice.num_toggles; ++i)
          XtSetValues(choice->widgets[i],args,1);
      }
    
      /* return the list of toggles that were just created */
      return (choice);
    }
    
    
    
    /* select_button(choice,togglenum)
    ** -------------------------------
    ** "Selects" the togglenumth toggle widget in the choice layout
    ** represented by choice.  It simply turns the widget on, as if the
    ** user had selected it, without calling any callbacks.  It's used
    ** to give feedback when reading from a script.
    */
    
    void
    select_button(ChoiceDesc *choice, int togglenum)
    {
      static Arg toggleargs[] = {
        {XtNstate,   (XtArgVal) True}
      };
    
      XtSetValues(choice->widgets[togglenum],toggleargs,XtNumber(toggleargs));
    }
    
    /* line_up_labels(descs,numdescs)
    ** ------------------------------
    ** descs represents a bunch of choice layouts (numdescs is the size of
    ** descs).  This function sets each label in descs to the same width,
    ** thus making them line up nicely since they're all on the left margin.
    */
    
    void
    line_up_labels(ChoiceDesc *descs[], int numdescs)
    {
      int i;			/* counter */
      Dimension width;		/* current width */
      Dimension maxwidth = (Dimension) 0; /* max width found */
    
      static Arg widthargs[] = {
        {XtNwidth,     (XtArgVal) NULL }
      };
    
      widthargs[0].value = (XtArgVal) &width;
    
      /* Find the maximum width */
      for (i = 0; i < numdescs; ++i) {
        XtGetValues(descs[i]->label, widthargs, XtNumber(widthargs));
        maxwidth = max(maxwidth,width);
      }
    
      /* Set all labels to that width */
      widthargs[0].value = (XtArgVal) maxwidth;
      for (i = 0; i < numdescs; ++i) {
        XtSetValues(descs[i]->label, widthargs, XtNumber(widthargs));
      }
    }
    
    /* choose_defaults(descs,numdescs)
    ** -------------------------------
    ** descs represents a bunch of choice layouts (numdescs is the size of
    ** descs).  This function goes through all of descs and selects the
    ** appropriate toggle widget for each one.  This includes calling
    ** the callbacks associated with that widget.
    **
    ** This function ends up initializing both the screen and the GC, and
    ** ensures that they are consistent.
    */
    
    void
    choose_defaults(ChoiceDesc *descs[], int numdescs)
    {
      int i;			/* which choice layout */
      int j;			/* which toggle within it */
    
      for (i = 0; i < numdescs; ++i) {
        j = 0;
        if (i == 0)
          j = 3;
        select_button(descs[i],j);
        XtCallCallbacks(descs[i]->widgets[j], XtNcallback, (caddr_t) NULL);
      }
    }
    
    
    /* print_text_to_buffer(w,closure,call_data)
    ** -----------------------------------------
    ** This is also in the list of callbacks for the toggle buttons in a
    ** choice widget.  It sends the string contained in closure (which
    ** was set way back in create_choice()) over to interpret(), which
    ** decides what to do with it.
    */
    
    /*ARGSUSED*/
    static void
    print_text_to_buffer(
        Widget  w,
        caddr_t closure,           /* contains the string */
        caddr_t call_data)
    {
      interpret((char *) closure);          /* Gee, that was easy */
    }