changeset 10517:9cdd6c8c05a4

[mq]: fltk_cb
author Shai Ayal <shaiay@users.sourceforge.net>
date Tue, 13 Apr 2010 20:26:08 +0300
parents f0266ee4aabe
children fcafe0e9bd58
files scripts/ChangeLog scripts/plot/__fltk_ginput__.m src/ChangeLog src/DLD-FUNCTIONS/fltk_backend.cc src/graphics.h.in
diffstat 5 files changed, 247 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Apr 13 14:59:01 2010 +0200
+++ b/scripts/ChangeLog	Tue Apr 13 20:26:08 2010 +0300
@@ -1,3 +1,8 @@
+2010-04-13  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* plot/__fltk_ginput__.m: New functions, implement ginput for
+	fltk backend.
+
 2010-04-13  Jaroslav Hajek  <highegg@gmail.com>
 
 	* sparse/spalloc.m: Remove.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/__fltk_ginput__.m	Tue Apr 13 20:26:08 2010 +0300
@@ -0,0 +1,92 @@
+## Copyright (C) 2010 Shai Ayal
+##
+## This file is part of Octave.
+##
+## Octave 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 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __fltk_ginput__ (@var{f}, @var{n})
+## Undocumented internal function.
+## @end deftypefn
+
+## This is ginput.m implementation for fltk.
+
+function [x, y, button] = __fltk_ginput__ (f, n = -1)
+
+  if (isempty (get (f, "currentaxes")))
+    error ("ginput: must have at least one axes");
+  endif
+
+  x = [];
+  y = [];
+  button = [];
+  ginput_aggregator (0, 0, 0);
+
+  unwind_protect
+
+    orig_windowbuttondownfcn = get (f, "windowbuttondownfcn");
+    set (f, "windowbuttondownfcn", @ginput_windowbuttondownfcn);
+
+    orig_ginput_keypressfcn = get (f, "keypressfcn");
+    set (f, "keypressfcn", @ginput_keypressfcn);
+    
+    while (true)
+      __fltk_redraw__ ();
+      
+      ## release CPU
+      sleep (0.01);
+
+      [x, y, n0] = ginput_aggregator (-1, 0, 0);
+      if (n0 == n | n0 < 0)
+        break;
+      endif
+    endwhile
+    
+    ## FIXME -- got to get the buttons somehow
+    button = ones (size (x));
+  unwind_protect_cleanup
+    set (f, "windowbuttondownfcn", orig_windowbuttondownfcn);
+    set (f, "keypressfcn", orig_ginput_keypressfcn);
+  end_unwind_protect
+
+endfunction
+
+function [x, y, n] = ginput_aggregator (mode , xn, yn)
+  persistent x y n
+
+  if (mode == 0),
+    x = [];
+    y = [];
+    n = 0;
+  elseif (mode == 1)
+    x = [x, xn];
+    y = [y, yn];
+    n += 1;
+  elseif (mode == 2)
+    n = -1
+  endif
+endfunction
+
+function ginput_windowbuttondownfcn (src, data)
+  point = get (get (src,"currentaxes"), "currentpoint");
+  ginput_aggregator (1, point(1,1), point(2,1));
+endfunction
+
+function ginput_keypressfcn (src, evt)
+  if (evt.Key == 10)
+    ginput_aggregator (2, 0, 0)
+  endif
+endfunction
+
--- a/src/ChangeLog	Tue Apr 13 14:59:01 2010 +0200
+++ b/src/ChangeLog	Tue Apr 13 20:26:08 2010 +0300
@@ -1,3 +1,14 @@
+2010-04-13  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* DLD-FUNCTIONS/fltk_backend.cc (plot_window::set_currentpoint,
+	(plot_window::set_axes_currentpoint, plot_window::key2shift,
+	(plot_window::key2ascii, plot_window::modifier2cell): new helper
+	functions for keypress and mousebutton callbacks.
+	(plot_window::handle): implement keypress and mousebutton callbacks.
+
+	* graphics.h.in (callback_property::is_defined): New conveniance function.
+	rename figure.current_point to figure.currentpoint.
+
 2010-04-13  Jaroslav Hajek  <highegg@gmail.com>
 
 	* DLD-FUNCTIONS/sparse.cc (Fspalloc): New DEFUN.
--- a/src/DLD-FUNCTIONS/fltk_backend.cc	Tue Apr 13 14:59:01 2010 +0200
+++ b/src/DLD-FUNCTIONS/fltk_backend.cc	Tue Apr 13 20:26:08 2010 +0300
@@ -218,7 +218,7 @@
 {
 public:
   plot_window (int _x, int _y, int _w, int _h, figure::properties& _fp)
-    : Fl_Window (_x, _y, _w, _h, "octave"), fp (_fp)
+    : Fl_Window (_x, _y, _w, _h, "octave"), fp (_fp), shift (0)
   {
     callback (window_close, static_cast<void*> (this));
 
@@ -323,6 +323,9 @@
   // life
   std::string window_label;
 
+  // Mod keys status
+  int shift;
+
   // Figure properties.
   figure::properties& fp;
 
@@ -449,6 +452,73 @@
     status->redraw ();
   }
 
+  void set_currentpoint (int px, int py)
+  {
+    Matrix pos (1,2,0);
+    pos(0) = px;
+    pos(1) = h () - status_h - py;
+    fp.set_currentpoint (pos);
+  }
+
+  void set_axes_currentpoint (graphics_object ax, int px, int py)
+  {
+    axes::properties& ap = 
+      dynamic_cast<axes::properties&> (ax.get_properties ());
+    
+    double x, y;
+    pixel2pos (ax, px, py, x, y);
+
+    Matrix pos (2,3,0);
+    pos(0,0) = x;
+    pos(1,0) = y;
+    pos(0,1) = x;
+    pos(1,1) = y;
+
+    ap.set_currentpoint (pos);
+  }
+
+  int key2shift (int key)
+  {
+    if (key == FL_Shift_L || key == FL_Shift_R)
+      return FL_SHIFT;
+
+    if (key == FL_Control_L || key == FL_Control_R)
+      return FL_CTRL;
+
+    if (key == FL_Alt_L || key == FL_Alt_R)
+      return FL_ALT;
+
+    if (key == FL_Meta_L || key == FL_Meta_R)
+      return FL_META;
+
+    return 0;
+  }
+
+  int key2ascii (int key)
+  {
+    if (key < 256) return key;
+    if (key == FL_Tab) return '\t';
+    if (key == FL_Enter) return 0x0a;
+    if (key == FL_BackSpace) return 0x08;
+    if (key == FL_Escape) return 0x1b;
+
+    return 0;
+  }
+
+  Cell modifier2cell ()
+  {
+    string_vector mod;
+    
+    if (shift & FL_SHIFT)
+      mod.append (std::string ("shift"));
+    if (shift & FL_CTRL)
+      mod.append (std::string ("control"));
+    if (shift & FL_ALT || shift & FL_META)
+      mod.append (std::string ("alt"));
+
+    return Cell (mod);
+  }
+
   void resize (int _x,int _y,int _w,int _h)
   {
     Fl_Window::resize (_x, _y, _w, _h);
@@ -475,7 +545,6 @@
     static int px0,py0;
     static graphics_object ax0;
 
-
     int retval = Fl_Window::handle (event);
 
     // We only handle events which are in the canvas area.
@@ -485,18 +554,49 @@
     switch (event)
       {
       case FL_KEYDOWN:
-        switch(Fl::event_key ())
-          {
-          case 'a':
-          case 'A':
-            axis_auto ();
+        {
+          int key = Fl::event_key ();
+
+          shift |= key2shift (key);
+          int key_a = key2ascii (key);
+          if (key_a && fp.get_keypressfcn ().is_defined ()) 
+            {
+              Octave_map evt;
+              evt.assign ("Character", octave_value (key_a));
+              evt.assign ("Key", octave_value (std::tolower (key_a)));
+              evt.assign ("Modifier", octave_value (modifier2cell ()));
+              fp.execute_keypressfcn (evt);
+            }
+          switch (key)
+            {
+            case 'a':
+            case 'A':
+              axis_auto ();
             break;
 
-          case 'g':
-          case 'G':
-            toggle_grid ();
+            case 'g':
+            case 'G':
+              toggle_grid ();
             break;
-          }
+            }
+        }
+        break;
+
+      case FL_KEYUP:
+        {
+          int key = Fl::event_key ();
+
+          shift &= (~key2shift (key));
+          int key_a = key2ascii (key);
+          if (key_a && fp.get_keyreleasefcn ().is_defined ())
+            {
+              Octave_map evt;
+              evt.assign ("Character", octave_value (key_a));
+              evt.assign ("Key", octave_value (std::tolower (key_a)));
+              evt.assign ("Modifier", octave_value (modifier2cell ()));
+              fp.execute_keyreleasefcn (evt);
+            }
+        }
         break;
 
       case FL_MOVE:
@@ -505,17 +605,27 @@
         break;
 
       case FL_PUSH:
+        px0 = Fl::event_x ();
+        py0 = Fl::event_y ();
+        ax0 = gh_manager::get_object (pixel2axes_or_ca (px0, py0));
+
+        set_currentpoint (Fl::event_x (), Fl::event_y ());
+        set_axes_currentpoint (ax0, px0, py0);
+        fp.execute_windowbuttondownfcn ();
+        
+
         if (Fl::event_button () == 1 || Fl::event_button () == 3)
-          {
-            px0 = Fl::event_x ();
-            py0 = Fl::event_y ();
-            ax0 = gh_manager::get_object (pixel2axes_or_ca (px0, py0));
-            return 1;
-          }
+          return 1;
         break;
 
       case FL_DRAG:
         pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ());
+        if (fp.get_windowbuttonmotionfcn ().is_defined ())
+          {
+            set_currentpoint (Fl::event_x (), Fl::event_y ());
+            fp.execute_windowbuttonmotionfcn ();
+          }
+        
         if (Fl::event_button () == 1)
           {
             if (ax0 && ax0.isa ("axes"))
@@ -573,6 +683,12 @@
       return 1;
 
       case FL_RELEASE:
+        if (fp.get_windowbuttonupfcn ().is_defined ())
+          {
+            set_currentpoint (Fl::event_x (), Fl::event_y ());
+            fp.execute_windowbuttonupfcn ();
+          }
+       
         if (Fl::event_button () == 1)
           {
             if ( Fl::event_clicks () == 1)
--- a/src/graphics.h.in	Tue Apr 13 14:59:01 2010 +0200
+++ b/src/graphics.h.in	Tue Apr 13 20:26:08 2010 +0300
@@ -1382,6 +1382,11 @@
 
   OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
 
+  bool is_defined (void) const
+    { 
+      return (callback.is_defined () && ! callback.is_empty ());
+    }
+
   callback_property& operator = (const octave_value& val)
     {
       set (val);
@@ -2572,7 +2577,7 @@
       array_property alphamap , Matrix (64, 1, 1)
       string_property currentcharacter r , ""
       handle_property currentobject r , graphics_handle ()
-      array_property current_point r , Matrix (2, 1, 0)
+      array_property currentpoint r , Matrix (2, 1, 0)
       bool_property dockcontrols , "off"
       bool_property doublebuffer , "on"
       string_property filename r , ""