tile.cpp revision 7e9727d1b09a7a652946b8f99aaf6e230df305c2
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * A simple dialog for creating grid type arrangements of selected objects
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Bob Jamison ( based off trace dialog)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen * Other dudes from The Inkscape Organization
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Abhishek Sharma
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Copyright (C) 2004 Bob Jamison
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Copyright (C) 2004 John Cliff
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Released under GNU GPL, read the file 'COPYING' for more information
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free//#define DEBUG_GRID_ARRANGE 1
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen#include <gtk/gtk.h> //for GTK_RESPONSE* types
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Sort items by their x co-ordinates, taking account of y (keeps rows intact)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * <0 *elem1 goes before *elem2
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * 0 *elem1 == *elem2
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen * >0 *elem1 goes after *elem2
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freeint sp_compare_x_position(SPItem *first, SPItem *second)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::OptRect a = first->documentVisualBounds();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::OptRect b = second->documentVisualBounds();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if ( !a || !b ) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen } else if (b->min()[Y] == a->min()[Y]) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (a_in_b_vert && a->min()[X] > b->min()[X]) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if (a_in_b_vert && a->min()[X] < b->min()[X]) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free * Sort items by their y co-ordinates.
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelensp_compare_y_position(SPItem *first, SPItem *second)
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen Geom::OptRect a = first->documentVisualBounds();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::OptRect b = second->documentVisualBounds();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free if ( !a || !b ) {
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen if (a->min()[Geom::Y] > b->min()[Geom::Y]) {
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free _notebook.append_page(*_gridArrangeTab, C_("Arrange dialog", "Rectangular grid"));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free _notebook.append_page(*_polarArrangeTab, C_("Arrange dialog", "Polar Coordinates"));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free _arrangeButton = this->addResponseButton(C_("Arrange dialog","_Arrange"), GTK_RESPONSE_APPLY);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free _arrangeButton->set_tooltip_text(_("Arrange selected objects"));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freePolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free centerX("", "X coordinate of the center", centerY),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free radiusX("", "X coordinate of the radius", radiusY),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free angleY("", "Starting angle", UNIT_TYPE_RADIAL),
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorPointLabel.set_alignment(Gtk::ALIGN_START);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorBoundingBoxRadio.set_label("Object's bounding box:");
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorRadioGroup = anchorBoundingBoxRadio.get_group();
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorBoundingBoxRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free pack_start(anchorBoundingBoxRadio, false, false);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorObjectPivotRadio.set_label("Object's rotational center");
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorObjectPivotRadio.set_group(anchorRadioGroup);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free anchorObjectPivotRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free pack_start(anchorObjectPivotRadio, false, false);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free arrangeOnLabel.set_alignment(Gtk::ALIGN_START);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free arrangeOnCircleRadio.set_label("Last selected circle/ellipse/arc");
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen arrangeRadioGroup = arrangeOnCircleRadio.get_group();
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen arrangeOnCircleRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed));
94bd7adc978850d91de1a92a8b5c05d01162a74cJohan B. C. Engelen pack_start(arrangeOnCircleRadio, false, false);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free arrangeOnParametersRadio.set_label("Parameterized:");
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free arrangeOnParametersRadio.set_group(arrangeRadioGroup);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free arrangeOnParametersRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free pack_start(arrangeOnParametersRadio, false, false);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free //FIXME: Objects in grid do not line up properly!
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free parametersTable.attach(centerLabel, 0, 1, 0, 1);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free parametersTable.attach(radiusLabel, 0, 1, 1, 2);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free parametersTable.attach(angleLabel, 0, 1, 2, 3);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free rotateObjectsCheckBox.set_label("Rotate objects");
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free pack_start(rotateObjectsCheckBox, false, false);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free std::cout << "PolarArrangeTab::arrange()" << std::endl;
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Inkscape::Selection *selection = sp_desktop_selection(parent->getDesktop());
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::Point move = Geom::Point(100 * i, -100 * i);
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free Geom::Affine const affine = Geom::Affine(Geom::Translate(move));
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-freevoid PolarArrangeTab::on_arrange_radio_changed()
895229950881e4c5be06fc7999ed0ef9aea62e92tavmjong-free bool arrangeParametric = !arrangeOnCircleRadio.get_active();
col_width = 0;
row_height = 0;
width = 0;
for (a=0;a<NoOfCols; a++){
height = 0;
for (a=0;a<NoOfRows; a++){
cnt=0;
cnt=0;
cnt++;
#ifdef DEBUG_GRID_ARRANGE
for (a=0;a<NoOfCols; a++){
for (a=0;a<NoOfRows; a++){
#ifdef DEBUG_GRID_ARRANGE
g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y));
Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it.
// Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized.
for (a=0;a<NoOfCols; a++){
for (a=0;a<NoOfRows; a++){
cnt=0;
if (updating) {
updating = true;
updating=false;
if (updating) {
updating = true;
updating=false;
if (updating) {
updating = true;
updating=false;
if (updating) {
updating = true;
updating=false;
if (updating) {
updating = true;
if (items) {
updating = false;
static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg)
XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns"),
updating = false;
g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this);
#ifdef DEBUG_GRID_ARRANGE
NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_col_spinbutton_changed));
if (AutoRow>0)
AutoRowSize=true;
AutoRowSize=false;
RowHeightButton.set_tooltip_text(_("If not set, each row has the height of the tallest object in it"));
RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_RowSize_checkbutton_changed));
NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_row_spinbutton_changed));
if (AutoCol>0)
AutoColSize=true;
AutoColSize=false;
ColumnWidthButton.set_tooltip_text(_("If not set, each column has the width of the widest object in it"));
ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ColSize_checkbutton_changed));
AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed));
SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed));
SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed));
YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ypad_spinbutton_changed));
XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_xpad_spinbutton_changed));
if (SpacingType>0) {
ManualSpacing=true;
ManualSpacing=false;