tile.cpp revision e463a5a70da38ff6014e7da6f70fcb7546186ebb
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/*
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * A simple dialog for creating grid type arrangements of selected objects
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Authors:
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Bob Jamison ( based off trace dialog)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * John Cliff
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Other dudes from The Inkscape Organization
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Abhishek Sharma
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Copyright (C) 2004 Bob Jamison
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Copyright (C) 2004 John Cliff
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof * Released under GNU GPL, read the file 'COPYING' for more information
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof */
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof//#define DEBUG_GRID_ARRANGE 1
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
81db7808fbee540434bcc6c7198579b95a6a2d88Jabiertxof#ifdef HAVE_CONFIG_H
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof# include <config.h>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#endif
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <gtk/gtk.h> //for GTK_RESPONSE* types
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <glibmm/i18n.h>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <gtkmm/stock.h>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <2geom/transforms.h>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "verbs.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "preferences.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "inkscape.h"
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#include "desktop-handles.h"
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#include "selection.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "document.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "sp-item.h"
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#include "widgets/icon.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "tile.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "desktop.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof/*
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Sort items by their x co-ordinates, taking account of y (keeps rows intact)
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof *
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof * <0 *elem1 goes before *elem2
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof * 0 *elem1 == *elem2
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * >0 *elem1 goes after *elem2
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof */
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxofint
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxofsp_compare_x_position(SPItem *first, SPItem *second)
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof{
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof using Geom::X;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof using Geom::Y;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::OptRect a = first->documentVisualBounds();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof Geom::OptRect b = second->documentVisualBounds();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if ( !a || !b ) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof // FIXME?
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof return 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof double const a_height = a->dimensions()[Y];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof double const b_height = b->dimensions()[Y];
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof bool a_in_b_vert = false;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof a_in_b_vert = true;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof a_in_b_vert = true;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof } else if (b->min()[Y] == a->min()[Y]) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof a_in_b_vert = true;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof } else {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof a_in_b_vert = false;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (!a_in_b_vert) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return -1;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof if (a_in_b_vert && a->min()[X] > b->min()[X]) {
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof return 1;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof if (a_in_b_vert && a->min()[X] < b->min()[X]) {
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof return -1;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof return 0;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof}
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/*
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof * Sort items by their y co-ordinates.
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof */
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxofint
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofsp_compare_y_position(SPItem *first, SPItem *second)
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::OptRect a = first->documentVisualBounds();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::OptRect b = second->documentVisualBounds();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if ( !a || !b ) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // FIXME?
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (a->min()[Geom::Y] > b->min()[Geom::Y]) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return 1;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (a->min()[Geom::Y] < b->min()[Geom::Y]) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof return -1;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof return 0;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof}
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxofnamespace Inkscape {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxofnamespace UI {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxofnamespace Dialog {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof//#########################################################################
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof//## E V E N T S
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof//#########################################################################
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/*
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof * This arranges the selection in a grid pattern.
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof *
de641d2613f4eea940ba6eb6c52ea9bcda516ba2Jabiertxof */
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxofvoid TileDialog::Grid_Arrange ()
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof{
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof int cnt,row_cnt,col_cnt,a,row,col;
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof double total_col_width,total_row_height;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof col_width = 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof row_height = 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof total_col_width=0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof total_row_height=0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // check for correct numbers in the row- and col-spinners
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof on_col_spinbutton_changed();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof on_row_spinbutton_changed();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof // set padding to manual values
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof paddingx = XPadding.getValue("px");
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof paddingy = YPadding.getValue("px");
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::vector<double> row_heights;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof std::vector<double> col_widths;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof std::vector<double> row_ys;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof std::vector<double> col_xs;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof int NoOfCols = NoOfColsSpinner.get_value_as_int();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof int NoOfRows = NoOfRowsSpinner.get_value_as_int();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof width = 0;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof for (a=0;a<NoOfCols; a++){
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof col_widths.push_back(width);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof height = 0;
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof for (a=0;a<NoOfRows; a++){
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof row_heights.push_back(height);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof grid_left = 99999;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof grid_top = 99999;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof SPDesktop *desktop = getDesktop();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof sp_desktop_document(desktop)->ensureUpToDate();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Inkscape::Selection *selection = sp_desktop_selection (desktop);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof const GSList *items = selection ? selection->itemList() : 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cnt=0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof for (; items != NULL; items = items->next) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof SPItem *item = SP_ITEM(items->data);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::OptRect b = item->documentVisualBounds();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof if (!b) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof continue;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof width = b->dimensions()[Geom::X];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof height = b->dimensions()[Geom::Y];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cx = b->midpoint()[Geom::X];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cy = b->midpoint()[Geom::Y];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (b->min()[Geom::X] < grid_left) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof grid_left = b->min()[Geom::X];
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (b->min()[Geom::Y] < grid_top) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof grid_top = b->min()[Geom::Y];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof if (width > col_width) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof col_width = width;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (height > row_height) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof row_height = height;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof }
a0623d30f399827fa8c9cf5edad86bbc8e72c063Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // require the sorting done before we can calculate row heights etc.
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof g_return_if_fail(selection);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof const GSList *items2 = selection->itemList();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof GSList *rev = g_slist_copy((GSList *) items2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof GSList *sorted = NULL;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // Calculate individual Row and Column sizes if necessary
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cnt=0;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof const GSList *sizes = sorted;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof for (; sizes != NULL; sizes = sizes->next) {
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof SPItem *item = SP_ITEM(sizes->data);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::OptRect b = item->documentVisualBounds();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (b) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof width = b->dimensions()[Geom::X];
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof height = b->dimensions()[Geom::Y];
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (width > col_widths[(cnt % NoOfCols)]) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof col_widths[(cnt % NoOfCols)] = width;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (height > row_heights[(cnt / NoOfCols)]) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof row_heights[(cnt / NoOfCols)] = height;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cnt++;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof /// Make sure the top and left of the grid dont move by compensating for align values.
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (RowHeightButton.get_active()){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign));
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (ColumnWidthButton.get_active()){
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof #ifdef DEBUG_GRID_ARRANGE
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof #endif
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // Calculate total widths and heights, allowing for columns and rows non uniformly sized.
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (ColumnWidthButton.get_active()){
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof total_col_width = col_width * NoOfCols;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof col_widths.clear();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof for (a=0;a<NoOfCols; a++){
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof col_widths.push_back(col_width);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
a0623d30f399827fa8c9cf5edad86bbc8e72c063Jabiertxof } else {
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof for (a = 0; a < (int)col_widths.size(); a++)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof total_col_width += col_widths[a] ;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (RowHeightButton.get_active()){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof total_row_height = row_height * NoOfRows;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof row_heights.clear();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (a=0;a<NoOfRows; a++){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof row_heights.push_back(row_height);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (a = 0; a < (int)row_heights.size(); a++)
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof total_row_height += row_heights[a] ;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::OptRect sel_bbox = selection->visualBounds();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof // Fit to bbox, calculate padding between rows accordingly.
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#ifdef DEBUG_GRID_ARRANGE
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofg_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));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#endif
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/*
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Horizontal align - Left = 0
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Centre = 1
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Right = 2
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Vertical align - Top = 0
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Middle = 1
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Bottom = 2
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof X position is calculated by taking the grids left co-ord, adding the distance to the column,
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof then adding 1/2 the spacing multiplied by the align variable above,
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it.
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof*/
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized.
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof for (a=0;a<NoOfCols; a++){
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (a<1) col_xs.push_back(0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (a=0;a<NoOfRows; a++){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (a<1) row_ys.push_back(0);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof cnt=0;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof GSList *current_row = NULL;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof current_row = g_slist_append (current_row, sorted->data);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof sorted = sorted->next;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof for (; current_row != NULL; current_row = current_row->next) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof SPItem *item=SP_ITEM(current_row->data);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof Inkscape::XML::Node *repr = item->getRepr();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::OptRect b = item->documentVisualBounds();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Point min;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (b) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof width = b->dimensions()[Geom::X];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof height = b->dimensions()[Geom::Y];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof min = b->min();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof width = height = 0;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof min = Geom::Point(0, 0);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof row = cnt / NoOfCols;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof col = cnt % NoOfCols;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof // signs are inverted between x and y due to y inversion
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Affine const affine = Geom::Affine(Geom::Translate(move));
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof item->set_i2d_affine(item->i2dt_affine() * affine);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof item->doWriteTransform(repr, item->transform, NULL);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof SP_OBJECT (current_row->data)->updateRepr();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof cnt +=1;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof g_slist_free (current_row);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_GRIDTILE,
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof _("Arrange in a grid"));
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof}
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof//#########################################################################
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof//## E V E N T S
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof//#########################################################################
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosińskivoid TileDialog::_apply()
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Grid_Arrange();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof}
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof/**
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof * changed value in # of columns spinbox.
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof */
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxofvoid TileDialog::on_row_spinbutton_changed()
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // quit if run by the attr_changed listener
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (updating) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof // in turn, prevent listener from responding
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof updating = true;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof SPDesktop *desktop = getDesktop();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Inkscape::Selection *selection = desktop ? desktop->selection : 0;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof g_return_if_fail( selection );
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof GSList const *items = selection->itemList();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof int selcount = g_slist_length((GSList *)items);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof double PerCol = ceil(selcount / NoOfColsSpinner.get_value());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof NoOfRowsSpinner.set_value(PerCol);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Inkscape::Preferences *prefs = Inkscape::Preferences::get();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof updating=false;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof}
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof/**
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof * changed value in # of rows spinbox.
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof */
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxofvoid TileDialog::on_col_spinbutton_changed()
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // quit if run by the attr_changed listener
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (updating) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof // in turn, prevent listener from responding
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof updating = true;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof SPDesktop *desktop = getDesktop();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Inkscape::Selection *selection = desktop ? desktop->selection : 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof g_return_if_fail(selection);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof GSList const *items = selection->itemList();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof int selcount = g_slist_length((GSList *)items);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof double PerRow = ceil(selcount / NoOfRowsSpinner.get_value());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof NoOfColsSpinner.set_value(PerRow);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Inkscape::Preferences *prefs = Inkscape::Preferences::get();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof updating=false;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof/**
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof * changed value in x padding spinbox.
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof */
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofvoid TileDialog::on_xpad_spinbutton_changed()
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof{
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof Inkscape::Preferences *prefs = Inkscape::Preferences::get();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof prefs->setDouble("/dialogs/gridtiler/XPad", XPadding.getValue("px"));
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof/**
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof * changed value in y padding spinbox.
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof */
void TileDialog::on_ypad_spinbutton_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble("/dialogs/gridtiler/YPad", YPadding.getValue("px"));
}
/**
* checked/unchecked autosize Rows button.
*/
void TileDialog::on_RowSize_checkbutton_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (RowHeightButton.get_active()) {
prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20);
} else {
prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20);
}
RowHeightBox.set_sensitive ( !RowHeightButton.get_active());
}
/**
* checked/unchecked autosize Rows button.
*/
void TileDialog::on_ColSize_checkbutton_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (ColumnWidthButton.get_active()) {
prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20);
} else {
prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20);
}
ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active());
}
/**
* changed value in columns spinbox.
*/
void TileDialog::on_rowSize_spinbutton_changed()
{
// quit if run by the attr_changed listener
if (updating) {
return;
}
// in turn, prevent listener from responding
updating = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value());
updating=false;
}
/**
* changed value in rows spinbox.
*/
void TileDialog::on_colSize_spinbutton_changed()
{
// quit if run by the attr_changed listener
if (updating) {
return;
}
// in turn, prevent listener from responding
updating = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value());
updating=false;
}
/**
* changed Radio button in Spacing group.
*/
void TileDialog::Spacing_button_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (SpaceManualRadioButton.get_active()) {
prefs->setDouble("/dialogs/gridtiler/SpacingType", 20);
} else {
prefs->setDouble("/dialogs/gridtiler/SpacingType", -20);
}
XPadding.set_sensitive ( SpaceManualRadioButton.get_active());
YPadding.set_sensitive ( SpaceManualRadioButton.get_active());
}
/**
* changed Radio button in Vertical Align group.
*/
void TileDialog::VertAlign_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (VertTopRadioButton.get_active()) {
VertAlign = 0;
prefs->setInt("/dialogs/gridtiler/VertAlign", 0);
} else if (VertCentreRadioButton.get_active()){
VertAlign = 1;
prefs->setInt("/dialogs/gridtiler/VertAlign", 1);
} else if (VertBotRadioButton.get_active()){
VertAlign = 2;
prefs->setInt("/dialogs/gridtiler/VertAlign", 2);
}
}
/**
* changed Radio button in Vertical Align group.
*/
void TileDialog::HorizAlign_changed()
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (HorizLeftRadioButton.get_active()) {
HorizAlign = 0;
prefs->setInt("/dialogs/gridtiler/HorizAlign", 0);
} else if (HorizCentreRadioButton.get_active()){
HorizAlign = 1;
prefs->setInt("/dialogs/gridtiler/HorizAlign", 1);
} else if (HorizRightRadioButton.get_active()){
HorizAlign = 2;
prefs->setInt("/dialogs/gridtiler/HorizAlign", 2);
}
}
/**
* Desktop selection changed
*/
void TileDialog::updateSelection()
{
// quit if run by the attr_changed listener
if (updating) {
return;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// in turn, prevent listener from responding
updating = true;
SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = desktop ? desktop->selection : 0;
GSList const *items = selection ? selection->itemList() : 0;
if (items) {
int selcount = g_slist_length((GSList *)items);
if (NoOfColsSpinner.get_value() > 1 && NoOfRowsSpinner.get_value() > 1){
// Update the number of rows assuming number of columns wanted remains same.
double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value());
NoOfRowsSpinner.set_value(NoOfRows);
// if the selection has less than the number set for one row, reduce it appropriately
if (selcount < NoOfColsSpinner.get_value()) {
double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value());
NoOfColsSpinner.set_value(NoOfCols);
prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols);
}
} else {
double PerRow = ceil(sqrt(selcount));
double PerCol = ceil(sqrt(selcount));
NoOfRowsSpinner.set_value(PerRow);
NoOfColsSpinner.set_value(PerCol);
prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol));
}
}
updating = false;
}
/*##########################
## Experimental
##########################*/
static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg)
{
TileDialog *tledlg = (TileDialog *) dlg;
tledlg->updateSelection();
}
//#########################################################################
//## C O N S T R U C T O R / D E S T R U C T O R
//#########################################################################
/**
* Constructor
*/
TileDialog::TileDialog()
: UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE),
XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns"),
YPadding(_("Y:"), _("Vertical spacing between rows."), XPadding, "", "object-rows")
{
// bool used by spin button callbacks to stop loops where they change each other.
updating = false;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!)
GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
{
// Selection Change signal
g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this);
}
Gtk::Box *contents = _getContents();
#define MARGIN 2
//##Set up the panel
SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = desktop ? desktop->selection : 0;
g_return_if_fail( selection );
int selcount = 1;
if (!selection->isEmpty()) {
GSList const *items = selection->itemList();
selcount = g_slist_length((GSList *)items);
}
/*#### Number of Rows ####*/
double PerRow = ceil(sqrt(selcount));
double PerCol = ceil(sqrt(selcount));
#ifdef DEBUG_GRID_ARRANGE
g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount);
#endif
NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:"));
NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner);
NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN);
NoOfRowsSpinner.set_digits(0);
NoOfRowsSpinner.set_increments(1, 0);
NoOfRowsSpinner.set_range(1.0, 10000.0);
NoOfRowsSpinner.set_value(PerCol);
NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed));
tips.set_tip(NoOfRowsSpinner, _("Number of rows"));
NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN);
gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj());
RowHeightButton.set_label(_("Equal _height"));
RowHeightButton.set_use_underline(true);
double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15);
if (AutoRow>0)
AutoRowSize=true;
else
AutoRowSize=false;
RowHeightButton.set_active(AutoRowSize);
NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN);
tips.set_tip(RowHeightButton, _("If not set, each row has the height of the tallest object in it"));
RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed));
{
/*#### Radio buttons to control vertical alignment ####*/
VertAlignLabel.set_label(_("Align:"));
VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN);
VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
VertAlignGroup = VertTopRadioButton.get_group();
VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0);
VertCentreRadioButton.set_group(VertAlignGroup);
VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0);
VertBotRadioButton.set_group(VertAlignGroup);
VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0);
VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1);
if (VertAlign == 0) {
VertTopRadioButton.set_active(TRUE);
}
else if (VertAlign == 1) {
VertCentreRadioButton.set_active(TRUE);
}
else if (VertAlign == 2){
VertBotRadioButton.set_active(TRUE);
}
VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN);
NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN);
}
SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN);
/*#### Label for X ####*/
padXByYLabel.set_label(" ");
XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN);
XByYLabel.set_markup(" &#215; ");
XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN);
SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN);
gtk_size_group_add_widget(_col2, (GtkWidget *) XByYLabelVBox.gobj());
/*#### Number of columns ####*/
NoOfColsLabel.set_text_with_mnemonic(_("_Columns:"));
NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner);
NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN);
NoOfColsSpinner.set_digits(0);
NoOfColsSpinner.set_increments(1, 0);
NoOfColsSpinner.set_range(1.0, 10000.0);
NoOfColsSpinner.set_value(PerRow);
NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed));
tips.set_tip(NoOfColsSpinner, _("Number of columns"));
NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN);
gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj());
ColumnWidthButton.set_label(_("Equal _width"));
ColumnWidthButton.set_use_underline(true);
double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15);
if (AutoCol>0)
AutoColSize=true;
else
AutoColSize=false;
ColumnWidthButton.set_active(AutoColSize);
NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN);
tips.set_tip(ColumnWidthButton, _("If not set, each column has the width of the widest object in it"));
ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed));
{
/*#### Radio buttons to control horizontal alignment ####*/
HorizAlignLabel.set_label(_("Align:"));
HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN);
HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
HorizAlignGroup = HorizLeftRadioButton.get_group();
HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0);
HorizCentreRadioButton.set_group(HorizAlignGroup);
HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0);
HorizRightRadioButton.set_group(HorizAlignGroup);
HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0);
HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1);
if (HorizAlign == 0) {
HorizLeftRadioButton.set_active(TRUE);
}
else if (HorizAlign == 1) {
HorizCentreRadioButton.set_active(TRUE);
}
else if (HorizAlign == 2) {
HorizRightRadioButton.set_active(TRUE);
}
HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN);
NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN);
}
SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN);
TileBox.pack_start(SpinsHBox, false, false, MARGIN);
{
/*#### Radio buttons to control spacing manually or to fit selection bbox ####*/
SpaceByBBoxRadioButton.set_label(_("_Fit into selection box"));
SpaceByBBoxRadioButton.set_use_underline (true);
SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
SpacingGroup = SpaceByBBoxRadioButton.get_group();
SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN);
SpaceManualRadioButton.set_label(_("_Set spacing:"));
SpaceManualRadioButton.set_use_underline (true);
SpaceManualRadioButton.set_group(SpacingGroup);
SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN);
TileBox.pack_start(SpacingVBox, false, false, MARGIN);
}
{
/*#### Padding ####*/
YPadding.setDigits(5);
YPadding.setIncrements(0.2, 0);
YPadding.setRange(-10000, 10000);
double yPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15);
YPadding.setValue(yPad, "px");
YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed));
XPadding.setDigits(5);
XPadding.setIncrements(0.2, 0);
XPadding.setRange(-10000, 10000);
double xPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15);
XPadding.setValue(xPad, "px");
XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed));
}
TileBox.pack_start(XPadding, false, false, MARGIN);
TileBox.pack_start(YPadding, false, false, MARGIN);
contents->pack_start(TileBox);
double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15);
if (SpacingType>0) {
ManualSpacing=true;
} else {
ManualSpacing=false;
}
SpaceManualRadioButton.set_active(ManualSpacing);
SpaceByBBoxRadioButton.set_active(!ManualSpacing);
XPadding.set_sensitive (ManualSpacing);
YPadding.set_sensitive (ManualSpacing);
//## The OK button
TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY);
TileOkButton->set_use_underline(true);
tips.set_tip((*TileOkButton), _("Arrange selected objects"));
show_all_children();
}
} //namespace Dialog
} //namespace UI
} //namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :