summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: de19d0a)
raw | patch | inline | side by side (parent: de19d0a)
author | cilix42 <cilix42@users.sourceforge.net> | |
Tue, 8 Jan 2008 22:39:39 +0000 (22:39 +0000) | ||
committer | cilix42 <cilix42@users.sourceforge.net> | |
Tue, 8 Jan 2008 22:39:39 +0000 (22:39 +0000) |
diff --git a/src/axis-manip.h b/src/axis-manip.h
index 8fb8fdc8e972ce5f4a556d2106eff77816a02c6a..e5cc963ba2614d95f406dad307a24c34c9dfb706 100644 (file)
--- a/src/axis-manip.h
+++ b/src/axis-manip.h
#ifndef SEEN_AXIS_MANIP_H
#define SEEN_AXIS_MANIP_H
-#include <glib.h> // g_assert()
#include <gtk/gtk.h>
#include "libnr/nr-point.h"
namespace Proj {
enum VPState {
- VP_FINITE = 0,
- VP_INFINITE
+ FINITE = 0,
+ INFINITE
};
// The X-/Y-/Z-axis corresponds to the first/second/third digit
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 83952d5ef6583999080f3a19fb2273592a7a0144..78e80be45825f6719b3201d8fc2b399563239197 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -455,37 +455,51 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
case GDK_bracketright:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, -180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_bracketleft:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, 180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_parenright:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, -180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_parenleft:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, 180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_braceright:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, -180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_braceleft:
persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, 180/snaps, MOD__ALT);
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ _("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_O:
- Box3D::create_canvas_point(persp3d_get_VP(inkscape_active_document()->current_persp3d, Proj::W).affine(),
- 6, 0xff00ff00);
+ if (MOD__CTRL && MOD__SHIFT) {
+ Box3D::create_canvas_point(persp3d_get_VP(inkscape_active_document()->current_persp3d, Proj::W).affine(),
+ 6, 0xff00ff00);
+ }
ret = true;
break;
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index 27701c80deff7fd642a531997ba4f10881238b5e..c2bbb5b46984328873dcf7f4990fdf3b628fd7f5 100644 (file)
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
// On the other hand, vp_drag_sel_modified() would update all boxes;
// here we can confine ourselves to the boxes of this particular perspective.
persp3d_update_box_reprs (persp);
- persp3d_update_z_orders (persp);
+ //persp3d_update_z_orders (persp);
SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT);
if (set_undo) {
sp_document_done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX,
void
persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state) {
- if (persp3d_VP_is_finite(persp, axis) != (state == Proj::VP_FINITE)) {
+ if (persp3d_VP_is_finite(persp, axis) != (state == Proj::FINITE)) {
persp3d_toggle_VP(persp, axis);
}
}
@@ -348,7 +348,7 @@ persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_press
persp->tmat.set_infinite_direction (axis, a);
persp3d_update_box_reprs (persp);
- persp3d_update_z_orders (persp);
+ //persp3d_update_z_orders (persp);
SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT);
}
//g_print ("Requesting repr update for %d boxes in the perspective.\n", persp->boxes.size());
for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
SP_OBJECT(*i)->updateRepr(SP_OBJECT_WRITE_EXT);
+ box3d_set_z_orders(*i);
}
}
diff --git a/src/persp3d.h b/src/persp3d.h
index c74af2e29cdbcd8b50a72875f7d94ff082f81fe1..ce4587f62f4f8eef556e1036b4f5401d7b8e32ec 100644 (file)
--- a/src/persp3d.h
+++ b/src/persp3d.h
#include <map>
#include "sp-item.h"
#include "transf_mat_3x4.h"
+#include "document.h"
+#include "inkscape.h"
-class SPDocument;
class SPBox3D;
class Box3DContext;
GType persp3d_get_type (void);
// FIXME: Make more of these inline!
-inline Proj::Pt2 persp3d_get_VP (Persp3D *persp, Proj::Axis axis) { return persp->tmat.column(axis); }
+inline Persp3D * persp3d_get_from_repr (Inkscape::XML::Node *repr) {
+ return SP_PERSP3D(SP_ACTIVE_DOCUMENT->getObjectByRepr(repr));
+}
+inline Proj::Pt2 persp3d_get_VP (Persp3D *persp, Proj::Axis axis) {
+ return persp->tmat.column(axis);
+}
NR::Point persp3d_get_PL_dir_from_pt (Persp3D *persp, NR::Point const &pt, Proj::Axis axis); // convenience wrapper around the following two
NR::Point persp3d_get_finite_dir (Persp3D *persp, NR::Point const &pt, Proj::Axis axis);
NR::Point persp3d_get_infinite_dir (Persp3D *persp, Proj::Axis axis);
index 3c35d0cfecc767aff62edda8e5ee61dabac172bc..37f122ca7d82718493d4c74faa6f2463b9f35e65 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
" </toolbar>"
" <toolbar name='3DBoxToolbar'>"
- " <toolitem action='3DBoxPosAngleXAction' />"
- " <toolitem action='3DBoxVPXAction' />"
+ " <toolitem action='3DBoxAngleXAction' />"
+ " <toolitem action='3DBoxVPXStateAction' />"
" <separator />"
- " <toolitem action='3DBoxPosAngleYAction' />"
- " <toolitem action='3DBoxVPYAction' />"
- " <separator />"
- " <toolitem action='3DBoxPosAngleZAction' />"
- " <toolitem action='3DBoxVPZAction' />"
+ " <toolitem action='3DBoxAngleYAction' />"
+ " <toolitem action='3DBoxVPYStateAction' />"
" <separator />"
+ " <toolitem action='3DBoxAngleZAction' />"
+ " <toolitem action='3DBoxVPZStateAction' />"
" </toolbar>"
" <toolbar name='SpiralToolbar'>"
@@ -2343,228 +2342,224 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
//## 3D Box ##
//########################
-static void box3d_toggle_vp_changed (GtkToggleAction *act, GObject *dataKludge, Proj::Axis axis)
-{
- SPDesktop *desktop = (SPDesktop *) g_object_get_data (dataKludge, "desktop");
- SPDocument *document = sp_desktop_document (desktop);
- // FIXME: Make sure document->current_persp3d is set correctly!
- Persp3D *persp = document->current_persp3d;
+// normalize angle so that it lies in the interval [0,360]
+static double box3d_normalize_angle (double a) {
+ double angle = a + ((int) (a/360.0))*360;
+ if (angle < 0) {
+ angle += 360.0;
+ }
+ return angle;
+}
- g_return_if_fail (persp);
+static void
+box3d_set_button_and_adjustment(Persp3D *persp, Proj::Axis axis,
+ GtkAdjustment *adj, GtkAction *act, GtkToggleAction *tact) {
+ // TODO: Take all selected perspectives into account but don't touch the state button if not all of them
+ // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states
+ // are reset).
+ bool is_infinite = !persp3d_VP_is_finite(persp, axis);
+
+ if (is_infinite) {
+ gtk_toggle_action_set_active(tact, TRUE);
+ gtk_action_set_sensitive(act, TRUE);
+
+ double angle = persp3d_get_infinite_angle(persp, axis);
+ if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
+ gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
+ }
+ } else {
+ gtk_toggle_action_set_active(tact, FALSE);
+ gtk_action_set_sensitive(act, FALSE);
+ }
+}
- // quit if run by the attr_changed listener
- if (g_object_get_data(dataKludge, "freeze")) {
+static void
+box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) {
+ if (!persp_repr) {
+ g_print ("No perspective given to box3d_resync_toolbar().\n");
return;
}
- // in turn, prevent listener from responding
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
-
- persp3d_set_VP_state(persp, axis, (gtk_toggle_action_get_active(act) ? Proj::VP_INFINITE : Proj::VP_FINITE));
+ GtkWidget *tbl = GTK_WIDGET(data);
+ GtkAdjustment *adj = 0;
+ GtkAction *act = 0;
+ GtkToggleAction *tact = 0;
+ Persp3D *persp = persp3d_get_from_repr(persp_repr);
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action;
- // FIXME: Can we merge this functionality with the one in box3d_persp_tb_event_attr_changed()?
- gchar *str;
- switch (axis) {
- case Proj::X:
- str = g_strdup ("box3d_angle_x_action");
- break;
- case Proj::Y:
- str = g_strdup ("box3d_angle_y_action");
- break;
- case Proj::Z:
- str = g_strdup ("box3d_angle_z_action");
- break;
- default:
- return;
- }
- GtkAction* angle_action = GTK_ACTION (g_object_get_data (dataKludge, str));
- if (angle_action) {
- gtk_action_set_sensitive (angle_action, !persp3d_VP_is_finite(persp, axis));
+ box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact);
}
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_y"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action;
- sp_document_maybe_done(sp_desktop_document(desktop), "toggle_vp", SP_VERB_CONTEXT_3DBOX,
- _("3D Box: Toggle VP"));
- //sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,_("3D Box: Toggle VP"));
+ box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact);
+ }
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_z"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action;
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE));
+ box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact);
+ }
}
-static void box3d_toggle_vp_x_changed(GtkToggleAction *act, GObject *dataKludge)
+static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
+ gchar const */*old_value*/, gchar const */*new_value*/,
+ bool /*is_interactive*/, gpointer data)
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::X);
+ GtkWidget *tbl = GTK_WIDGET(data);
+
+ // quit if run by the attr_changed listener
+ // note: it used to work without the differently called freeze_ attributes (here and in
+ // box3d_angle_value_changed()) but I now it doesn't so I'm leaving them in for now
+ if (g_object_get_data(G_OBJECT(tbl), "freeze_angle")) {
+ return;
+ }
+
+ // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling
+ // sp_document_maybe_done() when the document is undo insensitive)
+ g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(TRUE));
+
+ // TODO: Only update the appropriate part of the toolbar
+// if (!strcmp(name, "inkscape:vp_z")) {
+ box3d_resync_toolbar(repr, G_OBJECT(tbl));
+// }
+
+ Persp3D *persp = persp3d_get_from_repr(repr);
+ persp3d_update_box_reprs(persp);
+
+ g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(FALSE));
}
-static void box3d_toggle_vp_y_changed(GtkToggleAction *act, GObject *dataKludge)
+static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::Y);
-}
+ NULL, /* child_added */
+ NULL, /* child_removed */
+ box3d_persp_tb_event_attr_changed,
+ NULL, /* content_changed */
+ NULL /* order_changed */
+};
-static void box3d_toggle_vp_z_changed(GtkToggleAction *act, GObject *dataKludge)
+/**
+ * \param selection Should not be NULL.
+ */
+// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
+// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
+static void
+box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::Z);
+ // Here the following should be done: If all selected boxes have finite VPs in a certain direction,
+ // disable the angle entry fields for this direction (otherwise entering a value in them should only
+ // update the perspectives with infinite VPs and leave the other ones untouched).
+
+ Inkscape::XML::Node *persp_repr = NULL;
+ purge_repr_listener(tbl, tbl);
+
+ SPItem *item = selection->singleItem();
+ if (item && SP_IS_BOX3D(item)) {
+ // FIXME: Also deal with multiple selected boxes
+ SPBox3D *box = SP_BOX3D(item);
+ Persp3D *persp = box3d_get_perspective(box);
+ persp_repr = SP_OBJECT_REPR(persp);
+ if (persp_repr) {
+ g_object_set_data(tbl, "repr", persp_repr);
+ Inkscape::GC::anchor(persp_repr);
+ sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl);
+ sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl);
+ }
+
+ inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr);
+ prefs_set_string_attribute("tools.shapes.3dbox", "persp", persp_repr->attribute("id"));
+
+ box3d_resync_toolbar(persp_repr, tbl);
+ }
}
-static void box3d_vp_angle_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis )
+static void
+box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis)
{
- SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop");
- Persp3D *persp = sp_desktop_document (desktop)->current_persp3d;
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
+ SPDocument *document = sp_desktop_document(desktop);
// quit if run by the attr_changed listener
- if (g_object_get_data(dataKludge, "freeze")) {
+ // note: it used to work without the differently called freeze_ attributes (here and in
+ // box3d_persp_tb_event_attr_changed()) but I now it doesn't so I'm leaving them in for now
+ if (g_object_get_data( dataKludge, "freeze_attr" )) {
return;
}
// in turn, prevent listener from responding
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
+ g_object_set_data(dataKludge, "freeze_angle", GINT_TO_POINTER(TRUE));
- if (persp) {
- double angle = adj->value;
- // FIXME: Shouldn't we set the angle via the SVG attributes of the perspective instead of directly?
- if (persp3d_VP_is_finite(persp, axis)) {
- return;
- }
- persp->tmat.set_infinite_direction (axis, angle);
- persp3d_update_box_reprs (persp);
-
- sp_document_maybe_done(sp_desktop_document(desktop), "perspectiveangle", SP_VERB_CONTEXT_3DBOX,
- _("3D Box: Change perspective"));
+ //Persp3D *persp = document->current_persp3d;
+ std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
+ if (sel_persps.empty()) {
+ // this can happen when the document is created; we silently ignore it
+ return;
}
+ Persp3D *persp = *(sel_persps.begin());
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE));
+ persp->tmat.set_infinite_direction (axis, adj->value);
+ SP_OBJECT(persp)->updateRepr();
+
+ // TODO: use the correct axis here, too
+ sp_document_maybe_done(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)"));
+
+ g_object_set_data( dataKludge, "freeze_angle", GINT_TO_POINTER(FALSE) );
}
-static void box3d_vpx_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+
+static void
+box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::X);
+ box3d_angle_value_changed(adj, dataKludge, Proj::X);
}
-static void box3d_vpy_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+static void
+box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::Y);
+ box3d_angle_value_changed(adj, dataKludge, Proj::Y);
}
-static void box3d_vpz_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+static void
+box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::Z);
+ box3d_angle_value_changed(adj, dataKludge, Proj::Z);
}
-// normalize angle so that it lies in the interval [0,360]
-static double box3d_normalize_angle (double a) {
- double angle = a + ((int) (a/360.0))*360;
- if (angle < 0) {
- angle += 360.0;
- }
- return angle;
-}
-static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
- gchar const *old_value, gchar const *new_value,
- bool is_interactive, gpointer data)
+static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction *box3d_angle, Proj::Axis axis )
{
- GtkWidget *tbl = GTK_WIDGET(data);
-
- // FIXME: if we check for "freeze" as in other tools, no action is performed at all ...
- // quit if run by the _changed callbacks
- if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
- //return;
- }
-
- // in turn, prevent callbacks from responding
- //g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
-
- GtkAdjustment *adj = 0;
- double angle;
- SPDesktop *desktop = (SPDesktop *) g_object_get_data(G_OBJECT(tbl), "desktop");
- // FIXME: Get the persp from the box (should be the same, but ...)
- Persp3D *persp = sp_desktop_document (desktop)->current_persp3d;
- if (!strcmp(name, "inkscape:vp_x")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_x_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_x_action"));
- if (!persp3d_VP_is_finite(persp, Proj::X)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_x"));
- angle = persp3d_get_infinite_angle(persp, Proj::X);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
- }
-
- if (!strcmp(name, "inkscape:vp_y")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_y_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_y_action"));
- if (!persp3d_VP_is_finite(persp, Proj::Y)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_y"));
- angle = persp3d_get_infinite_angle(persp, Proj::Y);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
+ // TODO: Take all selected perspectives into account
+ std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
+ if (sel_persps.empty()) {
+ // this can happen when the document is created; we silently ignore it
+ return;
}
+ Persp3D *persp = *(sel_persps.begin());
- if (!strcmp(name, "inkscape:vp_z")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_z_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_z_action"));
- if (!persp3d_VP_is_finite(persp, Proj::Z)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_z"));
- angle = persp3d_get_infinite_angle(persp, Proj::Z);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
- }
-
- //g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
+ bool set_infinite = gtk_toggle_action_get_active(act);
+ persp3d_set_VP_state (persp, axis, set_infinite ? Proj::INFINITE : Proj::FINITE);
}
-static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
+static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
{
- NULL, /* child_added */
- NULL, /* child_removed */
- box3d_persp_tb_event_attr_changed,
- NULL, /* content_changed */
- NULL /* order_changed */
-};
+ box3d_vp_state_changed(act, box3d_angle, Proj::X);
+}
-/**
- * \param selection Should not be NULL.
- */
-// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
-// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
-static void
-box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
+static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
{
- Inkscape::XML::Node *repr = NULL;
- purge_repr_listener(tbl, tbl);
+ box3d_vp_state_changed(act, box3d_angle, Proj::Y);
+}
- SPItem *item = selection->singleItem();
- if (item && SP_IS_BOX3D(item)) {
- //repr = SP_OBJECT_REPR(item);
- repr = SP_OBJECT_REPR(SP_BOX3D(item)->persp_ref->getObject());
- if (repr) {
- g_object_set_data(tbl, "repr", repr);
- Inkscape::GC::anchor(repr);
- sp_repr_add_listener(repr, &box3d_persp_tb_repr_events, tbl);
- sp_repr_synthesize_events(repr, &box3d_persp_tb_repr_events, tbl);
- }
- }
+static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
+{
+ box3d_vp_state_changed(act, box3d_angle, Proj::Z);
}
static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
@@ -2572,101 +2567,127 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
EgeAdjustmentAction* eact = 0;
SPDocument *document = sp_desktop_document (desktop);
Persp3D *persp = document->current_persp3d;
- bool toggled = false;
-
- /* angle of VP in X direction */
- eact = create_adjustment_action("3DBoxPosAngleXAction",
- _("Angle X"), _("Angle X:"), _("Angle of infinite vanishing point in X direction"),
- "tools.shapes.3dbox", "dir_vp_x", persp3d_get_infinite_angle(persp, Proj::X),
- GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpx_angle_changed,
- 0.1, 1);
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_x_action", eact);
+
+ EgeAdjustmentAction* box3d_angle_x = 0;
+ EgeAdjustmentAction* box3d_angle_y = 0;
+ EgeAdjustmentAction* box3d_angle_z = 0;
+
+ /* Angle X */
+ {
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleXAction",
+ _("Angle in X direction"), _("Angle X:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in X direction"),
+ "tools.shapes.3dbox", "box3d_angle_x", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_x_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_x_action", eact );
+ box3d_angle_x = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::X)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ }
+
+
+ /* VP X state */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in X direction"),
+ _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_x",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_x_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
}
- /* toggle VP in X direction */
+ /* Angle Y */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPXAction",
- _("Toggle VP in X direction"),
- _("Toggle VP in X direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_x",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
- g_object_set_data(holder, "toggle_vp_x_action", act);
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::X));
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_x_changed), holder);
- }
-
- /* angle of VP in Y direction */
- eact = create_adjustment_action("3DBoxPosAngleYAction",
- _("Angle Y"), _("Angle Y:"), _("Angle of infinite vanishing point in Y direction"),
- "tools.shapes.3dbox", "dir_vp_y", persp3d_get_infinite_angle(persp, Proj::Y),
- GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpy_angle_changed,
- 0.1, 1);
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_y_action", eact);
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleYAction",
+ _("Angle in Y direction"), _("Angle Y:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in Y direction"),
+ "tools.shapes.3dbox", "box3d_angle_y", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_y_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_y_action", eact );
+ box3d_angle_y = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::Y)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ }
+
+ /* VP Y state */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in Y direction"),
+ _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_y",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_y_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
}
- /* toggle VP in Y direction */
+ /* Angle Z */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPYAction",
- _("Toggle VP in Y direction"),
- _("Toggle VP in Y direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_y",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::Y));
- g_object_set_data(holder, "toggle_vp_y_action", act);
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_y_changed), holder);
- }
-
- /* angle of VP in Z direction */
- eact = create_adjustment_action("3DBoxPosAngleZAction",
- _("Angle Z"), _("Angle Z:"), _("Angle of infinite vanishing point in Z direction"),
- "tools.shapes.3dbox", "dir_vp_z", persp3d_get_infinite_angle(persp, Proj::Z),
- GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpz_angle_changed,
- 0.1, 1);
-
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_z_action", eact);
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleZAction",
+ _("Angle in Z direction"), _("Angle Z:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in Z direction"),
+ "tools.shapes.3dbox", "box3d_angle_z", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_z_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_z_action", eact );
+ box3d_angle_z = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::Z)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
}
- /* toggle VP in Z direction */
+ /* VP Z state */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPZAction",
- _("Toggle VP in Z direction"),
- _("Toggle VP in Z direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_z",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
-
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::Z));
- g_object_set_data(holder, "toggle_vp_z_action", act);
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_z_changed), holder);
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in Z direction"),
+ _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_z",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_z_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
}
sigc::connection *connection = new sigc::connection(