viewer.c: Much improved UI.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 18 Aug 2007 10:16:26 +0000 (12:16 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 18 Aug 2007 10:16:26 +0000 (12:16 +0200)
src/viewer.c

index 8773a00..7516db2 100644 (file)
@@ -184,7 +184,6 @@ static void zoom_out (double *fov)
 
 int main( int argc, char** argv )
 {
-  XSizeHints hint;
   unsigned long color_fg, color_bg;
   int done;
   static Atom                  proto_atom= None, delete_atom= None;
@@ -196,10 +195,11 @@ int main( int argc, char** argv )
   double pitch = 0.0;
 
   /* Detect mouse movement direction */
-  int pos_x_new = 0;
-  int pos_y_new = 0;
-  int pos_x_old;
-  int pos_y_old;
+  unsigned int btn_current_pressed = 0;
+  int btn_reference_pos_x = 0;
+  int btn_reference_pos_y = 0;
+  int btn_current_pos_x = 0;
+  int btn_current_pos_y = 0;
 
   ui_image_t *pano;
   ui_image_t *view;
@@ -243,10 +243,6 @@ int main( int argc, char** argv )
     exit (0);
   }
 
-  hint.width  = view->width;
-  hint.height = view->height;
-  hint.flags = PSize;
-
   window_g = XCreateSimpleWindow(disp_g,
       DefaultRootWindow(disp_g),
       0, 0, /* Position */
@@ -254,19 +250,29 @@ int main( int argc, char** argv )
       5,
       color_fg, color_bg);
 
-  XSetStandardProperties(disp_g,
-      window_g,
-      text,
-      text,
-      None,
-      argv,
-      argc,
-      &hint);
+  {
+    XSizeHints hint;
+
+    memset (&hint, '\0', sizeof (hint));
+    hint.width  = view->width;
+    hint.height = view->height;
+    hint.flags = PSize;
+
+    XSetStandardProperties(disp_g,
+       window_g,
+       text,
+       text,
+       None,
+       argv,
+       argc,
+       &hint);
+  }
+
   gc = XCreateGC(disp_g,window_g,0,0);
   XSetBackground(disp_g,gc,color_bg);
   XSetForeground(disp_g,gc,color_fg);
 
-  event_mask = ButtonPressMask | ButtonReleaseMask | Button1MotionMask
+  event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
     | KeyPressMask | KeyReleaseMask | StructureNotifyMask
     | EnterWindowMask | LeaveWindowMask| ExposureMask;
 
@@ -290,12 +296,47 @@ int main( int argc, char** argv )
     int isChanged = 0;
     XEvent event;
 
-    XMaskEvent (disp_g, event_mask, &event);
+    memset (&event, '\0', sizeof (event));
+
+    if (btn_current_pressed == 0)
+    {
+      /* No button is pressed -> block */
+      XMaskEvent (disp_g, event_mask, &event);
+    }
+    else
+    {
+      /* A button is pressed -> do not block */
+      XCheckMaskEvent (disp_g, event_mask, &event);
+    }
 
     switch (event.type)
     {
+      case 0: /* XCheckMaskEvent didn't return an event */
+       break;
+
       case Expose:
-       draw_window (view);
+       {
+         XExposeEvent *eev = (XExposeEvent *) &event;
+
+         while (eev->count != 0)
+         {
+           if (!XCheckTypedEvent (disp_g, Expose, &event))
+           {
+             eev = NULL;
+             break;
+           }
+           /* do nothing */
+         }
+
+         if (eev != NULL)
+           isChanged = 1;
+       }
+       break;
+
+      case EnterNotify:
+       break;
+
+      case LeaveNotify:
        break;
 
       case ConfigureNotify:
@@ -313,7 +354,15 @@ int main( int argc, char** argv )
       case KeyPress:
        {
          XKeyEvent *kev = (XKeyEvent *) &event;
-         KeySym ks = XLookupKeysym (kev, 0);
+         char buffer[64];
+         int buffer_len = sizeof (buffer);
+         KeySym ks;
+
+         buffer_len = XLookupString(kev, buffer, sizeof (buffer), &ks, NULL);
+
+         if (buffer_len >= sizeof (buffer))
+           buffer_len = sizeof (buffer) - 1;
+         buffer[buffer_len] = '\0';
 
          switch (ks)
          {
@@ -356,62 +405,48 @@ int main( int argc, char** argv )
                yaw += 360.0;
              isChanged = 1;
              break;
+
+           case XK_q:
+             done++;
+             break;
+
+           default:
+             printf ("Unhandeled KeySym 0x%02llx, buffer = %s\n", (uint64_t) ks, buffer);
          }
        }
        break;
 
+#if 0
       case KeyRelease:
        printf ("Ignoring KeyRelease event.\n");
        break;
+#endif
 
       case ButtonPress:
-      case ButtonRelease:
+      /* case ButtonRelease: */
        {
          XButtonEvent *bev = (XButtonEvent *) &event;
-         pos_x_old = pos_x_new = bev->x;
-         pos_y_old = pos_y_new = bev->y;
+
+         btn_current_pressed = bev->button;
+         btn_current_pos_x = btn_reference_pos_x = bev->x;
+         btn_current_pos_y = btn_reference_pos_y = bev->y;
        }
        break;
 
+      case ButtonRelease:
+       btn_current_pressed = 0;
+       break;
+
       case MotionNotify:
        {
          XMotionEvent *mev = (XMotionEvent *) &event;
 
-         pos_x_old = pos_x_new;
-         pos_y_old = pos_y_new;
-
          do
          {
-           pos_x_new = mev->x;
-           pos_y_new = mev->y;
+           btn_current_pos_x = mev->x;
+           btn_current_pos_y = mev->y;
          }
          while (XCheckTypedEvent (disp_g, MotionNotify, &event));
-
-         printf ("XMotionEvent received: [%u,%u] -> [%u,%u]\n",
-             pos_x_old, pos_y_old, pos_x_new, pos_y_new);
-
-         if (mev->state & Button1Mask)
-         {
-           double yaw_diff = (pos_x_new - pos_x_old) / 24.0;
-           if (yaw_diff > 90.0)
-             yaw_diff = 90.0;
-           else if (yaw_diff < -90.0)
-             yaw_diff = -90.0;
-
-           yaw += yaw_diff;
-           if (yaw > 180.0)
-             yaw -= 360.0;
-           else if (yaw <= -180.0)
-             yaw += 360.0;
-
-           pitch -= (pos_y_new - pos_y_old) / 24.0;
-           if (pitch > 90.0)
-             pitch = 90.0;
-           else if (pitch < -90.0)
-             pitch = -90.0;
-
-           isChanged = 1;
-         }
        }
        break;
 
@@ -420,6 +455,45 @@ int main( int argc, char** argv )
            event.type);
     } /* switch (event.type) */
 
+    /*
+     * Check for pressed buttons and change view accordingly
+     */
+    if (btn_current_pressed == Button1)
+    {
+      double yaw_diff = (btn_current_pos_x - btn_reference_pos_x) / 24.0;
+      if (yaw_diff > 90.0)
+       yaw_diff = 90.0;
+      else if (yaw_diff < -90.0)
+       yaw_diff = -90.0;
+
+      yaw += yaw_diff;
+      if (yaw > 180.0)
+       yaw -= 360.0;
+      else if (yaw <= -180.0)
+       yaw += 360.0;
+
+      pitch -= (btn_current_pos_y - btn_reference_pos_y) / 24.0;
+      if (pitch > 90.0)
+       pitch = 90.0;
+      else if (pitch < -90.0)
+       pitch = -90.0;
+
+      isChanged = 1;
+    }
+    else if (btn_current_pressed == Button3)
+    {
+      double zoom_diff = (btn_current_pos_y - btn_reference_pos_y) / 64.0;
+      double zoom_ratio = pow (ZOOM_SPEED, zoom_diff);
+
+      fov *= zoom_ratio;
+      if (fov < 10.5)
+       fov = 10.5;
+      else if (fov > 165.0)
+       fov = 165.0;
+
+      isChanged = 1;
+    }
+
     if (isChanged != 0)
     {
       pl_extract_view (view, pano, pitch, yaw, fov);