# HG changeset patch
# User Kai Habel
# Date 1279471427 -7200
# Node ID 88dfc9c07de8fa745ba97346bf1d199ea2e94fab
# Parent 3140cb7a05a1dc71d21f210e40bcc1fe7ef556e1
[mq]: mouse_rotation
diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/ChangeLog
--- a/src/ChangeLog Sat Jul 17 19:53:01 2010 -0700
+++ b/src/ChangeLog Sun Jul 18 18:43:47 2010 +0200
@@ -1,3 +1,9 @@
+2010-07-18 Kai Habel
+ * DLD-FUNCTIONS/fltk_backend.cc: Add mode for mouse rotation.
+ (view2status): new function
+ * src/graphics.cc: Remove limitations for zooming and translation.
+ (axes::properties::rotate_view): new function
+
2010-07-17 Rik
* DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/ccolamd.cc,
diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/DLD-FUNCTIONS/fltk_backend.cc
--- a/src/DLD-FUNCTIONS/fltk_backend.cc Sat Jul 17 19:53:01 2010 -0700
+++ b/src/DLD-FUNCTIONS/fltk_backend.cc Sun Jul 18 18:43:47 2010 +0200
@@ -69,6 +69,8 @@
const char* help_text = "\
Keyboard Shortcuts\n\
a - autoscale\n\
+p - pan/zoom\n\
+r - rotate\n\
g - toggle grid\n\
\n\
Mouse\n\
@@ -219,8 +221,7 @@
public:
plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp)
: Fl_Window (xx, yy, ww, hh, "octave"), window_label (), shift (0),
- fp (xfp), canvas (0), autoscale (0), togglegrid (0), help (0),
- status (0)
+ fp (xfp), canvas (0), autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0), status (0)
{
callback (window_close, static_cast (this));
@@ -245,8 +246,24 @@
"G");
togglegrid->callback (button_callback, static_cast (this));
+ panzoom = new
+ Fl_Button (2 * status_h,
+ hh - status_h,
+ status_h,
+ status_h,
+ "P");
+ panzoom->callback (button_callback, static_cast (this));
+
+ rotate = new
+ Fl_Button (3 * status_h,
+ hh - status_h,
+ status_h,
+ status_h,
+ "R");
+ rotate->callback (button_callback, static_cast (this));
+
help = new
- Fl_Button (2*status_h,
+ Fl_Button (4 * status_h,
hh - status_h,
status_h,
status_h,
@@ -254,7 +271,7 @@
help->callback (button_callback, static_cast (this));
status = new
- Fl_Output (3*status_h,
+ Fl_Output (5 * status_h,
hh - status_h,
ww > 2*status_h ? ww - status_h : 0,
status_h, "");
@@ -279,11 +296,13 @@
status->show ();
autoscale->show ();
togglegrid->show ();
+ panzoom->show ();
+ rotate->show ();
set_name ();
resizable (canvas);
size_range (4*status_h, 2*status_h);
-
+ gui_mode = 1;
}
~plot_window (void)
@@ -328,6 +347,10 @@
// Mod keys status
int shift;
+ // Interactive Mode
+ // 1...pan/zoom, 2...rotate/zoom
+ int gui_mode;
+
// Figure properties.
figure::properties& fp;
@@ -355,6 +378,12 @@
if (widg == togglegrid)
toggle_grid ();
+
+ if (widg == panzoom)
+ gui_mode = 1;
+
+ if (widg == rotate)
+ gui_mode = 2;
if (widg == help)
fl_message ("%s", help_text);
@@ -363,6 +392,8 @@
OpenGL_fltk* canvas;
Fl_Button* autoscale;
Fl_Button* togglegrid;
+ Fl_Button* panzoom;
+ Fl_Button* rotate;
Fl_Button* help;
Fl_Output* status;
@@ -382,7 +413,7 @@
feval ("grid", args);
mark_modified ();
}
-
+
void pixel2pos
(graphics_handle ax, int px, int py, double& xx, double& yy) const
{
@@ -441,7 +472,8 @@
{
double x0, y0, x1, y1;
std::stringstream cbuf;
-
+ cbuf.precision(4);
+ cbuf.width(6);
pixel2pos (ax, px0, py0, x0, y0);
cbuf << "[" << x0 << ", " << y0 << "]";
if (px1 >= 0)
@@ -454,6 +486,24 @@
status->redraw ();
}
+ void view2status (graphics_object ax)
+ {
+ if (ax && ax.isa ("axes"))
+ {
+ axes::properties& ap =
+ dynamic_cast (ax.get_properties ());
+ std::stringstream cbuf;
+ cbuf.precision(4);
+ cbuf.width(6);
+ Matrix v (1,2,0);
+ v = ap.get("view").matrix_value();
+ cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]";
+
+ status->value (cbuf.str ().c_str ());
+ status->redraw ();
+ }
+ }
+
void set_currentpoint (int px, int py)
{
Matrix pos (1,2,0);
@@ -624,7 +674,6 @@
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 ());
@@ -635,22 +684,37 @@
{
if (ax0 && ax0.isa ("axes"))
{
+ if (gui_mode == 1)
+ pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ());
+ else
+ view2status (ax0);
axes::properties& ap =
dynamic_cast (ax0.get_properties ());
double x0, y0, x1, y1;
+ Matrix pos = fp.get_position ().matrix_value ();
pixel2pos (ax0, px0, py0, x0, y0);
pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1);
+
+ if (gui_mode == 1)
+ ap.translate_view (x0 - x1, y0 - y1);
+ else if (gui_mode == 2)
+ {
+ double daz, del;
+ daz = (Fl::event_x () - px0) / pos(2) * 360;
+ del = (Fl::event_y () - py0) / pos(3) * 360;
+ ap.rotate_view (del, daz);
+ }
+
px0 = Fl::event_x ();
py0 = Fl::event_y ();
-
- ap.translate_view (x0 - x1, y0 - y1);
mark_modified ();
}
return 1;
}
else if (Fl::event_button () == 3)
{
+ pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ());
Matrix zoom_box (1,4,0);
zoom_box (0) = px0;
zoom_box (1) = py0;
diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/graphics.cc
--- a/src/graphics.cc Sat Jul 17 19:53:01 2010 -0700
+++ b/src/graphics.cc Sun Jul 18 18:43:47 2010 +0200
@@ -4231,12 +4231,6 @@
ylims (0) = y + factor * (ylims (0) - y);
ylims (1) = y + factor * (ylims (1) - y);
- // Make sure we stay within the range og the plot
- xlims (0) = force_in_range (xlims (0), minx, maxx);
- xlims (1) = force_in_range (xlims (1), minx, maxx);
- ylims (0) = force_in_range (ylims (0), miny, maxy);
- ylims (1) = force_in_range (ylims (1), miny, maxy);
-
zoom (xlims, ylims, push_to_zoom_stack);
}
@@ -4280,25 +4274,27 @@
double min_pos_y = octave_Inf;
get_children_limits (miny, maxy, min_pos_y, kids, 'y');
- // Make sure we don't exceed the borders
- if (delta_x > 0)
- delta_x = std::min (xlims (1) + delta_x, maxx) - xlims (1);
- else
- delta_x = std::max (xlims (0) + delta_x, minx) - xlims (0);
- xlims (0) = xlims (0) + delta_x;
- xlims (1) = xlims (1) + delta_x;
-
- if (delta_y > 0)
- delta_y = std::min (ylims (1) + delta_y, maxy) - ylims (1);
- else
- delta_y = std::max (ylims (0) + delta_y, miny) - ylims (0);
- ylims (0) = ylims (0) + delta_y;
- ylims (1) = ylims (1) + delta_y;
+ xlims (0) += delta_x;
+ xlims (1) += delta_x;
+ ylims (0) += delta_y;
+ ylims (1) += delta_y;
zoom (xlims, ylims, false);
}
void
+axes::properties::rotate_view (double delta_el, double delta_az)
+{
+ Matrix v = get_view ().matrix_value ();
+
+ v (1) += delta_el;
+ v (0) -= delta_az;
+
+ set_view(v);
+ update_transform();
+}
+
+void
axes::properties::unzoom (void)
{
if (zoom_stack.size () >= 4)
diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/graphics.h.in
--- a/src/graphics.h.in Sat Jul 17 19:53:01 2010 -0700
+++ b/src/graphics.h.in Sun Jul 18 18:43:47 2010 +0200
@@ -2912,6 +2912,7 @@
bool push_to_zoom_stack = true);
void zoom (const Matrix& xl, const Matrix& yl, bool push_to_zoom_stack = true);
void translate_view (double delta_x, double delta_y);
+ void rotate_view (double delta_az, double delta_el);
void unzoom (void);
void clear_zoom_stack (void);