Logo Search packages:      
Sourcecode: vertex version File versions

clrsel.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>

#include <GL/gl.h>
#include <GL/glu.h>

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gtkgl/gtkglarea.h>

#include "cdialog.h"
#include "csd.h"
#include "guiutils.h"
#include "msglist.h"
#include "v3dtex.h"
#include "v3dmp.h"

#include "editor.h"
#include "clrsel.h"
#include "clrselcb.h"

#include "vmacfg.h"
#include "vmacfglist.h"
#include "vma.h"
#include "vmautils.h"
#include "messages.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


#include "images/icon_ok_20x20.xpm"
#include "images/icon_select_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"


void ClrSelDrawView(vma_clrsel_struct *cs);
void ClrSelDrawColorDA(vma_clrsel_struct *cs);

int ClrSelCreate(vma_clrsel_struct *cs, gpointer editor);
int ClrSelViewEnableContext(vma_clrsel_struct *cs);
void ClrSelFetchFromEditor(vma_clrsel_struct *cs);
void ClrSelUpdateMenus(vma_clrsel_struct *cs);
void ClrSelMap(vma_clrsel_struct *cs);
void ClrSelUnmap(vma_clrsel_struct *cs);
void ClrSelReset(vma_clrsel_struct *cs, gbool need_unmap);
void ClrSelDestroy(vma_clrsel_struct *cs);


static int gl_attributes_list[] = {
        GDK_GL_RGBA,
        GDK_GL_DOUBLEBUFFER,
        GDK_GL_DEPTH_SIZE,      1,
        GDK_GL_NONE
};


#define TITLE     ": Color Selector"

#define BTN_WIDTH (100 + (2 * 3))
#define BTN_HEIGHT      (30 + (2 * 3))

/* Size of view glarea widget. */
#define VIEW_WIDTH      (160)
#define VIEW_HEIGHT     ((VIEW_WIDTH) * 0.75)

#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))


/*
 *    Redraws the view on the cs, also updates the quadrics type label.
 */
void ClrSelDrawView(vma_clrsel_struct *cs)
{
      GLfloat     r = 0.5,
            g = 0.5,
            b = 0.5,
            a = 1.0,
            ambient = 0.0,
            diffuse = 1.0,
            specular = 0.0,
            shininess = 0.0,
            emission = 0.0,
            light_brightness = 1.0;
      gdouble view_aspect;
      gdouble cam_x, cam_y, cam_z;
      gint ww, wh;
      GtkAdjustment *adj;
      GtkWidget *w, *label;
      GLUquadricObj *qobj;


      if(cs == NULL)
          return;

      if(!cs->realized)
          return;

      /* Update quadrics type label. */
      label = cs->qobj_type_label;
      if(label != NULL)
      {
          const gchar *cstrptr = "Unknown";

          switch(cs->qobj_type)
          {
            case 0:
            cstrptr = "Sphere";
            break;
            case 1:
            cstrptr = "Cylender";
                break;
              case 2:
                cstrptr = "Cone";
                break;
              case 3:
                cstrptr = "Rectangle";
                break;
          }

          gtk_label_set_text(GTK_LABEL(label), cstrptr);
      }


      /* Get color. */
      w = cs->red_scale;
      if(w != NULL)
      {
          adj = gtk_range_get_adjustment(GTK_RANGE(w));
          if(adj != NULL)
            r = (GLfloat)CLIP(adj->value, 0.0, 1.0);
      }
        w = cs->green_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                g = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->blue_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                b = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->alpha_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                a = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }

      /* Get lighting surface. */
        w = cs->ambient_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                ambient = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->diffuse_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                diffuse = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->specular_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                specular = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->shininess_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                shininess = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }
        w = cs->emission_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                emission = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }

      /* Light brightness. */
        w = cs->light_scale;
        if(w != NULL)
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                light_brightness = (GLfloat)CLIP(adj->value, 0.0, 1.0);
        }


      /* Set view into GL context. */
      if(ClrSelViewEnableContext(cs))
          return;

      /* Get pointer to view glarea widget. */
      w = cs->view;
      if(w == NULL)
          return;

      /* Get size of view glarea widget. */
      ww = w->allocation.width;
      wh = w->allocation.height;

      if((ww < 1) || (wh < 1))
          return;

      view_aspect = (gdouble)ww / (gdouble)wh;

        /* Set up camera viewport. */
        glViewport(0, 0, ww, wh);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(
            (GLfloat)40,            /* Field of view in degrees. */
          (GLfloat)view_aspect,       /* Aspect. */
          0.1,                /* Clip near. */
          1000.0              /* Clip far. */
      );
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

      /* Clear frame buffer (clear color only, no depth clear). */
      glClearColor(0.0, 0.0, 0.0, 0.0);
      glClearDepth(1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        /* Update states. */
      glDisable(GL_COLOR_MATERIAL);
      glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
        glDisable(GL_DEPTH_TEST);
      glDepthFunc(GL_ALWAYS);
        glDisable(GL_LIGHTING);
        glDisable(GL_LIGHT0);
      glDisable(GL_ALPHA_TEST);
        glShadeModel(GL_FLAT);
      if(a < 1.0)
      {
          glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      }
      else
      {
          glDisable(GL_BLEND);
      }

      /* Set up camera, note that we'll be drawing in standard
       * x, y, z space.
       */
      cam_x = 0.0; cam_y = -17.0; cam_z = 0.0;
      gluLookAt(
            (GLdouble)cam_x,
            (GLdouble)cam_z,
            (GLdouble)-cam_y,
            (GLdouble)(cam_x + 0.0),
            (GLdouble)(cam_z + 0.0),
            (GLdouble)-(cam_y + 1.0),
            (GLdouble)0.0,
            (GLdouble)1.0, 
            (GLdouble)-0.0 
        );

      /* Create background texture as needed. */
      if(cs->bg_texture == NULL)
      {
          GLubyte data[4] = {0x40, 0xb0, 0xb0, 0x40};

          cs->bg_texture = V3DTextureLoadFromData2D(
            data, "background",
            2, 2,
            8,          /* Actual bits per pixel of data. */
            V3D_TEX_FORMAT_LUMINANCE,
            NULL, NULL
          );
      }

      /* Have background texture? */
      if(cs->bg_texture != NULL)
      {
          glEnable(GL_TEXTURE_2D);
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
          glColor4f(
            light_brightness, light_brightness,
            light_brightness, 1.0
          );
          V3DTextureSelect(cs->bg_texture);

          glBegin(GL_QUADS);
          {
            glNormal3d(0.0, 0.0, 1.0);
            glTexCoord2d(0.0, 10.0);
            glVertex3d(-40, 40, -20);
                glTexCoord2d(0.0, 0.0);
                glVertex3d(-40, -40, -20);
                glTexCoord2d(10.0, 0.0);
                glVertex3d(40, -40, -20); 
                glTexCoord2d(10.0, 10.0);
                glVertex3d(40, 40, -20);
          }
          glEnd();
      }



      /* Create a new quadric object as needed. */
      if(cs->qobj == NULL)
      {
          cs->qobj = qobj = gluNewQuadric();
          if(qobj != NULL)
          {
            gluQuadricCallback(qobj, GLU_ERROR, ClrSelQuadricErrorCB);
          }
      }

      /* Get pointer to quadric object. */
      qobj = cs->qobj;
      if(qobj != NULL)
      {
          GLfloat v[4], light_distance = 100.0;

            glEnable(GL_DEPTH_TEST);
            glDepthFunc(GL_LEQUAL);

          /* Set up quadric parameters. */
            gluQuadricOrientation(qobj, GLU_OUTSIDE);
          gluQuadricDrawStyle(qobj, GLU_FILL);
            gluQuadricNormals(qobj, GLU_SMOOTH);
            gluQuadricTexture(qobj, GL_FALSE);

          /* Begin setting up lighting. */
          /* Enable lighting. */
          glEnable(GL_LIGHTING);
          glEnable(GL_LIGHT0);


          /* Move light. */
            v[0] = (GLfloat)(sin(cs->light_origin) * light_distance);
            v[1] = (GLfloat)(sin(0.25 * PI) * light_distance);
            v[2] = (GLfloat)-(cos(cs->light_origin) * light_distance); 
            v[3] = 1.0;
            glLightfv(GL_LIGHT0, GL_POSITION, &(v[0]));

          /* Set no light ambient as light_brightness. */
          v[0] = 0.0;
          v[1] = 0.0;
          v[2] = 0.0;
          v[3] = 1.0;
          glLightfv(GL_LIGHT0, GL_AMBIENT, &(v[0]));

            /* Set light diffuse as light_brightness. */
            v[0] = light_brightness;
            v[1] = light_brightness;
            v[2] = light_brightness;
            v[3] = 1.0;
            glLightfv(GL_LIGHT0, GL_DIFFUSE, &(v[0]));

            /* Set no light specular. */
            v[0] = 1.0;
            v[1] = 1.0;
            v[2] = 1.0;
            v[3] = 1.0;
            glLightfv(GL_LIGHT0, GL_SPECULAR,  &(v[0]));

          /* Other light values. */
            v[0] = 1.0;
          glLightfv(GL_LIGHT0, GL_CONSTANT_ATTENUATION, &(v[0]));

          v[0] = 0.0;
          glLightfv(GL_LIGHT0, GL_LINEAR_ATTENUATION, &(v[0]));

          v[0] = 0.0;
          glLightfv(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, &(v[0]));

/*
          glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
      GL_SEPARATE_SPECULAR_COLOR);
 */

          /* Begin setting up material colors. */
          v[0] = r * ambient;
          v[1] = g * ambient;
            v[2] = b * ambient;
            v[3] = a * ambient;
          glMaterialfv(GL_FRONT, GL_AMBIENT, &(v[0]));

            v[0] = r * diffuse;
            v[1] = g * diffuse;
            v[2] = b * diffuse;
            v[3] = a * diffuse;
            glMaterialfv(GL_FRONT, GL_DIFFUSE, &(v[0]));

            v[0] = specular;
            v[1] = specular;
            v[2] = specular;
            v[3] = 1.0;
            glMaterialfv(GL_FRONT, GL_SPECULAR, &(v[0]));

            v[0] = shininess * 128.0;     /* Value is coeff * 128.0. */
            glMaterialfv(GL_FRONT, GL_SHININESS, &(v[0]));

            v[0] = r * emission;
            v[1] = g * emission;
            v[2] = b * emission;
            v[3] = 0.0;             /* No alpha. */
            glMaterialfv(GL_FRONT, GL_EMISSION, &(v[0]));

          /* Set shade model. */
          glShadeModel(GL_SMOOTH);

          glDisable(GL_TEXTURE_2D);

          glPushMatrix();
          {
            switch(cs->qobj_type)
            {
              case 0:
                    glTranslatef(0.0, 0.0, 0.0);
                gluSphere(
                  qobj,
                  5.0,        /* Radius. */
                  16, 16            /* Divisions. */
                );
                break;

              case 1:
                glRotatef(-90, 1.0, 0.0, 0.0);
                    glTranslatef(0.0, 0.0, -4.0);
                gluCylinder(
                  qobj,
                  5.0,        /* Base radius. */
                  5.0,        /* Top radius. */
                  8.0,        /* Height. */
                  16,         /* Divisions. */
                  8           /* Vertical divisions. */
                );
                break;

                  case 2:
                    glRotatef(-90, 1.0, 0.0, 0.0);
                    glTranslatef(0.0, 0.0, -4.0);
                    gluCylinder(
                        qobj,
                        5.0,            /* Base radius. */
                        0.0,            /* Top radius. */
                        8.0,           /* Height. */
                        16,             /* Divisions. */
                        8               /* Vertical divisions. */
                    );
                    break;

                  case 3:
                glRotatef(25, 1.0, 0.0, 0.0);   /* Pitch. */
                glRotatef(25, 0.0, 1.0, 0.0);   /* Heading. */
                    glTranslatef(0.0, 1.0, 0.0);
                /* Begin drawing rectangle. */
                glBegin(GL_QUADS);
                {
                  /* Top. */
                  glNormal3d(-0.3, 0.6, -0.3);
                  glVertex3d(-4.0, 3.0, -3.0);
                        glNormal3d(-0.3, 0.6, 0.3);
                        glVertex3d(-4.0, 3.0, 3.0);
                        glNormal3d(0.3, 0.6, 0.3);
                        glVertex3d(4.0, 3.0, 3.0);
                        glNormal3d(0.3, 0.6, -0.3);
                        glVertex3d(4.0, 3.0, -3.0);

                        /* Front. */
                        glNormal3d(-0.3, 0.3, 0.6);
                        glVertex3d(-4.0, 3.0, 3.0);
                        glNormal3d(-0.3, -0.3, 0.6); 
                        glVertex3d(-4.0, -3.0, 3.0);
                        glNormal3d(0.3, -0.3, 0.6);
                        glVertex3d(4.0, -3.0, 3.0);
                        glNormal3d(0.3, 0.3, 0.6); 
                        glVertex3d(4.0, 3.0, 3.0);

                        /* Left. */
                        glNormal3d(-0.6, 0.3, -0.3);
                        glVertex3d(-4.0, 3.0, -3.0);
                        glNormal3d(-0.6, -0.3, -0.3);
                        glVertex3d(-4.0, -3.0, -3.0);
                        glNormal3d(-0.6, -0.3, 0.3);
                        glVertex3d(-4.0, -3.0, 3.0);
                        glNormal3d(-0.6, 0.3, 0.3);
                        glVertex3d(-4.0, 3.0, 3.0);
                }
                glEnd();

                    break;
            }
          }
          glPopMatrix();
      }





        /* Make glarea rendered buffer active. */
        gtk_gl_area_swapbuffers(GTK_GL_AREA(w));

        /* Check for GL errors. */
        if(1)
        {
            GLenum error_code = glGetError();
            if(error_code != GL_NO_ERROR)
                VMAReportGLError(NULL, (int)error_code);
        }

      return;
}


/*
 *    Updates the color drawing area on the cs based on the current
 *    scale values on the cs.
 */
void ClrSelDrawColorDA(vma_clrsel_struct *cs)
{
      GtkAdjustment *adj;
      GtkWidget *w, *da;
      GdkColormap *colormap;
      GdkColor gdk_color;


      if(cs == NULL)
          return;

      if(!cs->initialized)
          return;

      da = cs->color_da;
      if(da == NULL)
          return;

      if(da->window == NULL)
          return;

      colormap = gdk_window_get_colormap(da->window);
      if(colormap == NULL)
          return;

      /* Get values from scales. */
      w = cs->red_scale;
      if(w != NULL)
      {
          adj = gtk_range_get_adjustment(GTK_RANGE(w));
          if(adj != NULL)
            gdk_color.red = (guint16)(adj->value * (guint16)(-1));
      }
        w = cs->green_scale;
        if(w != NULL) 
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                gdk_color.green = (guint16)(adj->value * (guint16)(-1));
        }
        w = cs->blue_scale;
        if(w != NULL) 
        {
            adj = gtk_range_get_adjustment(GTK_RANGE(w));
            if(adj != NULL)
                gdk_color.blue = (guint16)(adj->value * (guint16)(-1));
        }

      gdk_colormap_alloc_color(colormap, &gdk_color, TRUE, TRUE);
      gdk_window_set_background(da->window, &gdk_color);
      gdk_window_clear(da->window);
      gdk_colormap_free_colors(colormap, &gdk_color, 1);
}

/*
 *    Initializes a new color selection dialog.
 */
int ClrSelCreate(vma_clrsel_struct *cs, gpointer editor)
{
      const gchar *msglist[] = VMA_MSGLIST_CLRSEL_TOOLTIPS;
      const gchar *tip_name;
      const gchar *label;
      gint label_width;
      GtkAdjustment *adj;
      GtkWidget *w, *parent, *parent2, *parent3, *parent4, *parent5;
      GtkWidget *editor_toplevel, *btn, *scale, *entry, *main_vbox;
      GdkWindow *window;
      GtkAccelGroup *accelgrp;


      if(cs == NULL)
            return(-1);

      /* Reset values. */
      cs->initialized = TRUE;
      cs->map_state = FALSE;
      cs->editor_ptr = editor;

      if(editor == NULL)
          editor_toplevel = NULL;
      else
          editor_toplevel = ((ma_editor_struct *)editor)->toplevel;

      /* Keyboard accelerator group. */
      cs->accelgrp = accelgrp = gtk_accel_group_new();

        /* Toplevel. */
        cs->toplevel = parent = w = gtk_window_new(GTK_WINDOW_DIALOG);
        gtk_widget_realize(w);
        window = w->window;
        if(window != NULL)
        {
            gdk_window_set_decorations(
                window,
                GDK_DECOR_TITLE | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE
            );
            gdk_window_set_functions(
                window,
                GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE
            );
        }
        gtk_signal_connect(
            GTK_OBJECT(w), "delete_event",
            GTK_SIGNAL_FUNC(ClrSelCloseCB),
            (gpointer)cs
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "destroy",
            GTK_SIGNAL_FUNC(ClrSelDestroyCB),
            (gpointer)cs
        );
        gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_accel_group_attach(accelgrp, GTK_OBJECT(w));
      gtk_window_set_title(GTK_WINDOW(w), PROG_NAME TITLE);
      if(editor_toplevel != NULL)
          gtk_window_set_transient_for(
            GTK_WINDOW(w),
            GTK_WINDOW(editor_toplevel)
          );

        /* Main vbox. */
      main_vbox = w = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent), w);
        gtk_widget_show(w);
      parent = w;

        /* Vbox to hold frames. */
        w = gtk_vbox_new(FALSE, 5);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(w), 5);
        gtk_widget_show(w);
        parent = w;

        /* Hbox to separate columns for view, color scales/drawing area,
       * and surface lighting scales.
       */
      w = gtk_hbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
        gtk_widget_show(w);
      parent2 = w;


#define DO_CREATE_COLOR_SCALE \
{ \
 w = gtk_hbox_new(FALSE, 0); \
 gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2); \
 gtk_widget_show(w); \
 parent5 = w; \
\
 w = gtk_label_new(label); \
 gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2); \
 gtk_widget_set_usize(w, label_width, -1); \
 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_RIGHT); \
 gtk_widget_show(w); \
\
 adj = (GtkAdjustment *)gtk_adjustment_new( \
  0.0,          /* Initial. */ \
  0.0,          /* Minimum. */ \
  1.0,          /* Maximum. */ \
  0.01,         /* Step inc. */ \
  0.05,         /* Page inc. */ \
  0.0           /* Page size. */ \
 ); \
 scale = w = gtk_hscale_new(adj); \
 gtk_widget_set_usize(w, 80, -1); \
 gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2); \
 gtk_scale_set_draw_value(GTK_SCALE(w), FALSE); \
 gtk_signal_connect( \
  GTK_OBJECT(adj), "value_changed", \
  GTK_SIGNAL_FUNC(ClrSelScaleCB), \
  (gpointer)cs \
 ); \
 gtk_widget_show(w); \
 GUISetWidgetTip( \
  w, MsgListMatchCaseMessage( \
   msglist, tip_name \
  ) \
 ); \
\
 entry = w = gtk_entry_new_with_max_length(8); \
 gtk_widget_set_usize(w, 40, -1); \
 gtk_entry_set_editable(GTK_ENTRY(w), TRUE); \
 gtk_entry_set_text(GTK_ENTRY(w), "0.0"); \
 gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2); \
 gtk_signal_connect( \
  GTK_OBJECT(GTK_EDITABLE(w)), "changed", \
  GTK_SIGNAL_FUNC(ClrSelEntryCB), \
  (gpointer)cs \
 ); \
 gtk_widget_show(w); \
}

        /* *********************************************************** */
      /* Preview frame. */
        w = gtk_frame_new("Preview");
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
        gtk_widget_show(w);
        parent3 = w;

      /* Preview vbox inside frame. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(w), 5);
      gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

      /* Frame for view glarea. */
        w = gtk_frame_new(NULL);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
        gtk_widget_show(w);
        parent4 = w;

        /* View glarea widget. */
        w = gtk_gl_area_new(gl_attributes_list);
        cs->view = w;
        if(w != NULL)
        {
            gtk_widget_add_events(
            w,
                GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
                GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
                GDK_POINTER_MOTION_HINT_MASK
            );
            gtk_signal_connect(
                GTK_OBJECT(w), "button_press_event",
                GTK_SIGNAL_FUNC(ClrSelViewEventCB),
                (gpointer)cs
            );
            gtk_signal_connect(
                GTK_OBJECT(w), "button_release_event",
                GTK_SIGNAL_FUNC(ClrSelViewEventCB),
                (gpointer)cs
            );
            gtk_signal_connect(
                GTK_OBJECT(w), "motion_notify_event",
                GTK_SIGNAL_FUNC(ClrSelViewEventCB),
                (gpointer)cs
            );
            gtk_signal_connect(
                GTK_OBJECT(w), "expose_event",
                GTK_SIGNAL_FUNC(ClrSelViewEventCB),
                (gpointer)cs
            );
            gtk_signal_connect(
                GTK_OBJECT(w), "configure_event",
                GTK_SIGNAL_FUNC(ClrSelViewEventCB),
                (gpointer)cs
            );
            gtk_container_add(GTK_CONTAINER(parent4), w);
          gtk_widget_set_usize(w, VIEW_WIDTH, VIEW_HEIGHT);
            gtk_widget_show(w);
            GUISetWidgetTip(
                w,
                MsgListMatchCaseMessage(
                    msglist, VMA_MSGNAME_CLRSEL_PREVIEW
                )
            );
        }


      /* Quadric object type. */
      cs->qobj_type = 0;            /* Sphere. */

      /* Hbox for quadric object type and buttons. */
      w = gtk_hbox_new(TRUE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
      gtk_widget_show(w);
      parent4 = w;

        w = gtk_hbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 5);
        gtk_widget_show(w);
        parent4 = w;

      /* Previous button. */
      cs->qobj_type_prev_btn = w = gtk_button_new();
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",        
            GTK_SIGNAL_FUNC(ClrSelPrevQObjCB), 
            (gpointer)cs
        );
        gtk_widget_show(w);
      parent5 = w;
      /* Arrow. */
      w = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT);
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_show(w);

      /* Frame for label. */
      w = gtk_frame_new(NULL);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
      gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_OUT);
      gtk_widget_show(w);
      parent5 = w;

      cs->qobj_type_label = w = gtk_label_new("");
      gtk_container_add(GTK_CONTAINER(parent5), w);
      gtk_widget_set_usize(w, 80, -1);
        gtk_widget_show(w);


        /* Next button. */   
        cs->qobj_type_next_btn = w = gtk_button_new();
        gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(ClrSelNextQObjCB),
            (gpointer)cs
        );
        gtk_widget_show(w);
        parent5 = w;
        /* Arrow. */
        w = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
        gtk_container_add(GTK_CONTAINER(parent5), w);
        gtk_widget_show(w);


      /* Vbox to group light intensity scale. */
      w = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
      parent4 = w;

      /* Create light intensity scale. */
      tip_name = VMA_MSGNAME_CLRSEL_LIGHT_BRIGHTNESS;
        label_width = -1;
        label = "Light:";
        DO_CREATE_COLOR_SCALE
        cs->light_scale = scale;
        cs->light_entry = entry;



      /* *********************************************************** */
        /* Pigment frame. */
        w = gtk_frame_new("Pigment");
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
        gtk_widget_show(w);
        parent3 = w;
 
        /* Pigment vbox inside frame. */   
        w = gtk_vbox_new(FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(w), 5);
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

      /* Select color button. */
        btn = w = gtk_button_new();
/*      gtk_widget_set_usize(w, 25, 25); */
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(ClrSelSelectColorCB),
            (gpointer)cs          
        );
        gtk_widget_show(w);
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist, VMA_MSGNAME_CLRSEL_COLOR_BUTTON
            )
        );
        parent4 = w;

      /* Color drawing area. */
        cs->color_da = w = gtk_drawing_area_new();
        gtk_drawing_area_size(GTK_DRAWING_AREA(w), 80, 20);
        gtk_container_add(GTK_CONTAINER(parent4), w);
        gtk_widget_realize(w);
        gtk_widget_show(w);


      /* Vbox to group rgb scales. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

      label_width = 20;
        tip_name = VMA_MSGNAME_CLRSEL_RED;
      label = "R:";
      DO_CREATE_COLOR_SCALE
      cs->red_scale = scale;
      cs->red_entry = entry;

        tip_name = VMA_MSGNAME_CLRSEL_GREEN;
        label = "G:";
        DO_CREATE_COLOR_SCALE
        cs->green_scale = scale;
      cs->green_entry = entry;

        tip_name = VMA_MSGNAME_CLRSEL_BLUE;
        label = "B:";
        DO_CREATE_COLOR_SCALE
        cs->blue_scale = scale;
      cs->blue_entry = entry;

        /* Vbox to group alpha scale. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

        tip_name = VMA_MSGNAME_CLRSEL_ALPHA;
        label = "A:";
        DO_CREATE_COLOR_SCALE
        cs->alpha_scale = scale;
      cs->alpha_entry = entry;


        /* Vbox to group update preview check. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 2);
      gtk_widget_show(w);
        parent5 = w;

      cs->update_view_check = w = gtk_check_button_new_with_label(
            "Update Preview"
        );
        gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 2);
        gtk_signal_connect(
            GTK_OBJECT(w), "toggled",
            GTK_SIGNAL_FUNC(ClrSelUpdatePreviewCheckCB), (gpointer)cs
        );
        gtk_widget_show(w);


        /* *********************************************************** */
        /* Material frame. */
        w = gtk_frame_new("Material");
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
        gtk_widget_show(w);
        parent3 = w;

        /* Material vbox inside frame. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_container_border_width(GTK_CONTAINER(w), 5);
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

        /* Vbox to group ambient and diffuse scales. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

        label_width = 80;
        tip_name = VMA_MSGNAME_CLRSEL_AMBIENT;
      label = "Ambient:";
        DO_CREATE_COLOR_SCALE
        cs->ambient_scale = scale;
      cs->ambient_entry = entry;

        label = "Diffuse:";
        tip_name = VMA_MSGNAME_CLRSEL_DIFFUSE;
        DO_CREATE_COLOR_SCALE
        cs->diffuse_scale = scale;
      cs->diffuse_entry = entry;

        /* Vbox to group specular and shininess scales. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

        label = "Specular:";
        tip_name = VMA_MSGNAME_CLRSEL_SPECULAR;
        DO_CREATE_COLOR_SCALE
        cs->specular_scale = scale;
      cs->specular_entry = entry;

        label = "Shininess:";
        tip_name = VMA_MSGNAME_CLRSEL_SHININESS;
        DO_CREATE_COLOR_SCALE
        cs->shininess_scale = scale;
        cs->shininess_entry = entry;

        /* Vbox to group emission scale. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);
        parent4 = w;

        label = "Emission:";
        tip_name = VMA_MSGNAME_CLRSEL_EMISSION;
        DO_CREATE_COLOR_SCALE
        cs->emission_scale = scale;
        cs->emission_entry = entry;


#undef DO_CREATE_COLOR_SCALE

        /* Separator. */
        w = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(main_vbox), w, FALSE, FALSE, 0);
        gtk_widget_show(w);

        /* Buttons hbox. */
      w = gtk_hbox_new(TRUE, 0);
        gtk_box_pack_start(GTK_BOX(main_vbox), w, FALSE, FALSE, 5);
        gtk_widget_show(w);
      parent2 = w;

        /* Set button. */
        cs->set_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_ok_20x20_xpm, "Set", NULL
        );
        gtk_widget_set_usize(w, BTN_WIDTH, BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(ClrSelSetCB),
            (gpointer)cs
        );
        gtk_accel_group_add(
            accelgrp, GDK_space, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Return, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_3270_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_KP_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_ISO_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_widget_show(w);

        /* Apply button. */
        cs->apply_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_select_20x20_xpm, "Apply", NULL
        );
        gtk_widget_set_usize(w, BTN_WIDTH, BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(ClrSelApplyCB),
            (gpointer)cs
        );
        gtk_widget_show(w);   

        /* Cancel button. */
        cs->close_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_cancel_20x20_xpm, "Cancel", NULL
        );
        gtk_widget_set_usize(w, BTN_WIDTH, BTN_HEIGHT);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(ClrSelCloseBtnCB),
            (gpointer)cs   
        );
        gtk_accel_group_add(
            accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_widget_show(w);   




      ClrSelReset(cs, FALSE);
      ClrSelUpdateMenus(cs);

      return(0);
}

/*
 *      Makes the glarea view widget on the cs into gl context.
 *
 *      Returns 0 on success or -1 on error.
 */
int ClrSelViewEnableContext(vma_clrsel_struct *cs)
{
        GtkWidget *w;
        gint status;

        if(cs == NULL)
            return(-1);

        w = cs->view;
      if(w == NULL)
          return(-1);

        if(!cs->realized)
            return(-1);

      status = gtk_gl_area_make_current(GTK_GL_AREA(w));
      if(status)
          return(0);
      else
          return(-1);
}


/*
 *    Have the color selection fetch values from its editor's
 *    selected primitive (if any).
 *
 *    The color drawing area will be updated as well.
 */
void ClrSelFetchFromEditor(vma_clrsel_struct *cs)
{
        GtkWidget *w;   
        GtkAdjustment *adj;
        ma_editor_struct *editor;


        if(cs == NULL)
            return;

        if(!cs->initialized)  
            return;

        editor = (ma_editor_struct *)cs->editor_ptr;

        /* Is editor valid? */
        if((editor == NULL) ? 0 : editor->initialized)
        {
          /* Get selected primitive on editor and update cs widgets. */
          gint model_num;
          v3d_model_struct *model_ptr;

            model_num = EditorSelectedModelIndex(editor);
            model_ptr = V3DModelListGetPtr(
                editor->model, editor->total_models, model_num
            );
            if(model_ptr != NULL)
            {   
                gint pn;
                gpointer p;
  
                pn = ((editor->total_selected_primitives == 1) ?
                    editor->selected_primitive[0] : -1
                );
                p = V3DMPListGetPtr(
                    model_ptr->primitive, model_ptr->total_primitives, pn
                );
                if((p == NULL) ? 0 : ((*(int *)p) == V3DMP_TYPE_COLOR))
                {
                    gdouble value;
                    mp_color_struct *mp_color = (mp_color_struct *)p;

#define DO_SET_SCALE_VALUE    \
{ \
 if(w != NULL) \
 { \
  adj = gtk_range_get_adjustment(GTK_RANGE(w)); \
  if(adj != NULL) \
  { \
   adj->value = value; \
   gtk_adjustment_value_changed(adj); \
  } \
 } \
}
                    value = mp_color->r;
                    w = cs->red_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->g;
                    w = cs->green_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->b;
                    w = cs->blue_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->a;
                    w = cs->alpha_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->ambient;
                    w = cs->ambient_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->diffuse;
                    w = cs->diffuse_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->specular;
                    w = cs->specular_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->shininess;
                    w = cs->shininess_scale;
                    DO_SET_SCALE_VALUE

                    value = mp_color->emission;
                    w = cs->emission_scale;
                    DO_SET_SCALE_VALUE

#undef DO_SET_SCALE_VALUE
                }
            }
        }

      /* Update drawings. */
/*
      ClrSelDrawColorDA(cs);
      ClrSelDrawView(cs);
 */
      return;
}

/*
 *    Updates menus on the cs. This will also fetch the values from
 *    the editor's selected model primitive (if any).
 */
void ClrSelUpdateMenus(vma_clrsel_struct *cs)
{
      ma_editor_struct *editor;


        if(cs == NULL)
            return;

        if(!cs->initialized)
            return;

      editor = (ma_editor_struct *)cs->editor_ptr;




      return;
}

/*
 *    Maps the cs.
 */
void ClrSelMap(vma_clrsel_struct *cs)
{
        GtkWidget *w;

        if(cs == NULL)
            return;

        if(!cs->initialized)
            return;

      w = cs->set_btn;
      if(w != NULL)
      {
          gtk_widget_grab_focus(w);
          gtk_widget_grab_default(w);
      }

        if(!cs->map_state)
        {
            w = cs->toplevel;
            if(w != NULL)
                gtk_widget_show(w);

            cs->map_state = TRUE;
        }
}

/*
 *    Unmaps the cs.
 */
void ClrSelUnmap(vma_clrsel_struct *cs)
{
      GtkWidget *w;

      if(cs == NULL)
          return;

      if(!cs->initialized)
          return;

      if(cs->map_state)
      {
            w = cs->toplevel;
            if(w != NULL)
                gtk_widget_hide(w);

            cs->map_state = FALSE;
      }

      return;
}

/*
 *    Resets all values on the cs and unmaps it as requested.
 */
void ClrSelReset(vma_clrsel_struct *cs, gbool need_unmap)
{
      GtkWidget *w;
      GtkAdjustment *adj;


      if(cs == NULL)
          return;

      if(!cs->initialized)
          return;

      /* Preview qobj type. */
      cs->qobj_type = VMACFGItemListGetValueI(
            option, VMA_CFG_PARM_CLRSEL_PREVIEW_QOBJ_TYPE
        );
      if(cs->qobj_type < 0)
          cs->qobj_type = 0;

      /* Light orbit position. */
      cs->light_origin = VMACFGItemListGetValueD(
          option, VMA_CFG_PARM_CLRSEL_LIGHT_ORBIT_POSITION
      );
      while(cs->light_origin >= (2.0 * PI))
          cs->light_origin -= (2.0 * PI);
      while(cs->light_origin < (0.0 * PI))
          cs->light_origin += (2.0 * PI);

      /* Update preview check. */
      w = cs->update_view_check;
      if(w != NULL)
      {
          GTK_TOGGLE_BUTTON(w)->active = (VMACFGItemListGetValueI(
            option, VMA_CFG_PARM_CLRSEL_UPDATE_PREVIEW
          ) ? TRUE : FALSE);
      }

      /* Light brightness. */
      w = cs->light_scale;
      if(w != NULL)
      {
          adj = gtk_range_get_adjustment(GTK_RANGE(w));
          if(adj != NULL)
          {
            adj->value = CLIP(VMACFGItemListGetValueD(
                option, VMA_CFG_PARM_CLRSEL_LIGHT_BRIGHTNESS
            ), 0.0, 1.0);
            gtk_adjustment_value_changed(adj);
          }
      }

      /* If currently mapped, then redraw view. */
      if(cs->map_state)
          ClrSelDrawView(cs);

      if(need_unmap)
          ClrSelUnmap(cs);

      return;
}

/*
 *    Destroys the given color selection dialog but does not deallocate
 *    the structure itself.
 */
void ClrSelDestroy(vma_clrsel_struct *cs)
{
      GtkWidget **w;


      if(cs == NULL)
          return;

      if(cs->initialized)
      {
#define DO_DESTROY_WIDGET       \
{ \
 if((*w) != NULL) \
 { \
  GtkWidget *tmp_w = *w; \
  (*w) = NULL; \
  gtk_widget_destroy(tmp_w); \
 } \
}

          /* Enable view glarea into context and begin deallocating
           * GL resources.
           */
          ClrSelViewEnableContext(cs);

          /* GL quadric object. */
          if(cs->qobj != NULL)
          {
            gluDeleteQuadric(cs->qobj);
            cs->qobj = NULL;
          }

          /* Background texture. */
          if(cs->bg_texture != NULL)
            {
                V3DTextureDestroy(cs->bg_texture);
                cs->bg_texture = NULL;
            }

          /* Deallocate all substructures. */
          ClrSelReset(cs, cs->map_state);


          /* Begin destroying widgets. */
            w = &cs->qobj_type_label;
            DO_DESTROY_WIDGET

            w = &cs->qobj_type_prev_btn;
            DO_DESTROY_WIDGET

            w = &cs->qobj_type_next_btn;
            DO_DESTROY_WIDGET

            w = &cs->light_scale;   
            DO_DESTROY_WIDGET   
            w = &cs->light_entry;     
            DO_DESTROY_WIDGET

          w = &cs->view;
          DO_DESTROY_WIDGET

            w = &cs->color_da;
            DO_DESTROY_WIDGET

            w = &cs->red_scale;
            DO_DESTROY_WIDGET
          w = &cs->red_entry;
            DO_DESTROY_WIDGET

            w = &cs->green_scale;
            DO_DESTROY_WIDGET
            w = &cs->green_entry;
            DO_DESTROY_WIDGET

            w = &cs->blue_scale;
            DO_DESTROY_WIDGET
            w = &cs->blue_entry;
            DO_DESTROY_WIDGET

            w = &cs->alpha_scale;
            DO_DESTROY_WIDGET
            w = &cs->alpha_entry;
            DO_DESTROY_WIDGET

            w = &cs->ambient_scale;
            DO_DESTROY_WIDGET
            w = &cs->ambient_entry;
            DO_DESTROY_WIDGET

            w = &cs->diffuse_scale;
            DO_DESTROY_WIDGET
            w = &cs->diffuse_entry;
            DO_DESTROY_WIDGET

            w = &cs->specular_scale;
            DO_DESTROY_WIDGET
            w = &cs->specular_entry;
            DO_DESTROY_WIDGET

            w = &cs->shininess_scale;
            DO_DESTROY_WIDGET
            w = &cs->shininess_entry;
            DO_DESTROY_WIDGET

            w = &cs->emission_scale;
            DO_DESTROY_WIDGET
            w = &cs->emission_entry;
            DO_DESTROY_WIDGET


          w = &cs->update_view_check;
          DO_DESTROY_WIDGET

            w = &cs->set_btn;
            DO_DESTROY_WIDGET
            w = &cs->apply_btn;
            DO_DESTROY_WIDGET
            w = &cs->close_btn;
            DO_DESTROY_WIDGET

          w = &cs->toplevel;
          DO_DESTROY_WIDGET

          if(cs->accelgrp != NULL)
          {
            gtk_accel_group_unref(cs->accelgrp);
            cs->accelgrp = NULL;
          }

#undef DO_DESTROY_WIDGET
      }

      /* Clear color selector structure. */
      memset(cs, 0x00, sizeof(vma_clrsel_struct));
}

Generated by  Doxygen 1.6.0   Back to index