2
* A simple dialog for creating grid type arrangements of selected objects
5
* Bob Jamison ( based off trace dialog)
7
* Other dudes from The Inkscape Organization
9
* Copyright (C) 2004 Bob Jamison
10
* Copyright (C) 2004 John Cliff
12
* Released under GNU GPL, read the file 'COPYING' for more information
14
//#define DEBUG_GRID_ARRANGE 1
21
#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
22
#include <gtk/gtksizegroup.h>
23
#include <glibmm/i18n.h>
24
#include <gtkmm/stock.h>
27
#include "preferences.h"
29
#include "desktop-handles.h"
30
#include "selection.h"
33
#include "widgets/icon.h"
34
#include "tiledialog.h"
39
* Sort items by their x co-ordinates, taking account of y (keeps rows intact)
41
* <0 *elem1 goes before *elem2
43
* >0 *elem1 goes after *elem2
46
sp_compare_x_position(SPItem *first, SPItem *second)
51
boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
52
boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
59
double const a_height = a->dimensions()[Y];
60
double const b_height = b->dimensions()[Y];
62
bool a_in_b_vert = false;
63
if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
65
} else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
67
} else if (b->min()[Y] == a->min()[Y]) {
76
if (a_in_b_vert && a->min()[X] > b->min()[X]) {
79
if (a_in_b_vert && a->min()[X] < b->min()[X]) {
86
* Sort items by their y co-ordinates.
89
sp_compare_y_position(SPItem *first, SPItem *second)
91
boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
92
boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
99
if (a->min()[Geom::Y] > b->min()[Geom::Y]) {
102
if (a->min()[Geom::Y] < b->min()[Geom::Y]) {
114
//#########################################################################
116
//#########################################################################
120
* This arranges the selection in a grid pattern.
124
void TileDialog::Grid_Arrange ()
127
int cnt,row_cnt,col_cnt,a,row,col;
128
double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy;
129
double total_col_width,total_row_height;
135
// check for correct numbers in the row- and col-spinners
136
on_col_spinbutton_changed();
137
on_row_spinbutton_changed();
139
// set padding to manual values
140
paddingx = XPadSpinner.get_value();
141
paddingy = YPadSpinner.get_value();
143
std::vector<double> row_heights;
144
std::vector<double> col_widths;
145
std::vector<double> row_ys;
146
std::vector<double> col_xs;
148
int NoOfCols = NoOfColsSpinner.get_value_as_int();
149
int NoOfRows = NoOfRowsSpinner.get_value_as_int();
152
for (a=0;a<NoOfCols; a++){
153
col_widths.push_back(width);
157
for (a=0;a<NoOfRows; a++){
158
row_heights.push_back(height);
163
SPDesktop *desktop = getDesktop();
164
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
166
Inkscape::Selection *selection = sp_desktop_selection (desktop);
167
const GSList *items = selection->itemList();
169
for (; items != NULL; items = items->next) {
170
SPItem *item = SP_ITEM(items->data);
171
boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
176
width = b->dimensions()[Geom::X];
177
height = b->dimensions()[Geom::Y];
179
cx = b->midpoint()[Geom::X];
180
cy = b->midpoint()[Geom::Y];
182
if (b->min()[Geom::X] < grid_left) {
183
grid_left = b->min()[Geom::X];
185
if (b->min()[Geom::Y] < grid_top) {
186
grid_top = b->min()[Geom::Y];
188
if (width > col_width) {
191
if (height > row_height) {
197
// require the sorting done before we can calculate row heights etc.
199
const GSList *items2 = selection->itemList();
200
GSList *rev = g_slist_copy((GSList *) items2);
201
GSList *sorted = NULL;
202
rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position);
203
sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position);
206
// Calculate individual Row and Column sizes if necessary
210
const GSList *sizes = sorted;
211
for (; sizes != NULL; sizes = sizes->next) {
212
SPItem *item = SP_ITEM(sizes->data);
213
boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
215
width = b->dimensions()[Geom::X];
216
height = b->dimensions()[Geom::Y];
217
if (width > col_widths[(cnt % NoOfCols)]) {
218
col_widths[(cnt % NoOfCols)] = width;
220
if (height > row_heights[(cnt / NoOfCols)]) {
221
row_heights[(cnt / NoOfCols)] = height;
229
/// Make sure the top and left of the grid dont move by compensating for align values.
230
if (RowHeightButton.get_active()){
231
grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign));
233
if (ColumnWidthButton.get_active()){
234
grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign));
237
#ifdef DEBUG_GRID_ARRANGE
238
g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left);
241
// Calculate total widths and heights, allowing for columns and rows non uniformly sized.
243
if (ColumnWidthButton.get_active()){
244
total_col_width = col_width * NoOfCols;
246
for (a=0;a<NoOfCols; a++){
247
col_widths.push_back(col_width);
250
for (a = 0; a < (int)col_widths.size(); a++)
252
total_col_width += col_widths[a] ;
256
if (RowHeightButton.get_active()){
257
total_row_height = row_height * NoOfRows;
259
for (a=0;a<NoOfRows; a++){
260
row_heights.push_back(row_height);
263
for (a = 0; a < (int)row_heights.size(); a++)
265
total_row_height += row_heights[a] ;
270
boost::optional<Geom::Rect> sel_bbox = selection->bounds();
271
// Fit to bbox, calculate padding between rows accordingly.
272
if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
273
#ifdef DEBUG_GRID_ARRANGE
274
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));
276
paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1);
277
paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1);
281
Horizontal align - Left = 0
285
Vertical align - Top = 0
289
X position is calculated by taking the grids left co-ord, adding the distance to the column,
290
then adding 1/2 the spacing multiplied by the align variable above,
291
Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it.
295
// Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized.
297
for (a=0;a<NoOfCols; a++){
298
if (a<1) col_xs.push_back(0);
299
else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]);
303
for (a=0;a<NoOfRows; a++){
304
if (a<1) row_ys.push_back(0);
305
else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]);
309
for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) {
311
GSList *current_row = NULL;
312
for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) {
313
current_row = g_slist_append (current_row, sorted->data);
314
sorted = sorted->next;
317
for (; current_row != NULL; current_row = current_row->next) {
318
SPItem *item=SP_ITEM(current_row->data);
319
Inkscape::XML::Node *repr = SP_OBJECT_REPR(item);
320
boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
323
width = b->dimensions()[Geom::X];
324
height = b->dimensions()[Geom::Y];
328
min = Geom::Point(0, 0);
331
row = cnt / NoOfCols;
332
col = cnt % NoOfCols;
334
new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
335
new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];
337
// signs are inverted between x and y due to y inversion
338
Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y);
339
Geom::Matrix const affine = Geom::Matrix(Geom::Translate(move));
340
sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
341
sp_item_write_transform(item, repr, item->transform, NULL);
342
SP_OBJECT (current_row->data)->updateRepr();
345
g_slist_free (current_row);
348
sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE,
349
_("Arrange in a grid"));
354
//#########################################################################
356
//#########################################################################
359
void TileDialog::_apply()
366
* changed value in # of columns spinbox.
368
void TileDialog::on_row_spinbutton_changed()
370
// quit if run by the attr_changed listener
375
// in turn, prevent listener from responding
377
SPDesktop *desktop = getDesktop();
379
Inkscape::Selection *selection = sp_desktop_selection (desktop);
381
GSList const *items = selection->itemList();
382
int selcount = g_slist_length((GSList *)items);
384
double PerCol = ceil(selcount / NoOfColsSpinner.get_value());
385
NoOfRowsSpinner.set_value(PerCol);
386
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
387
prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value());
392
* changed value in # of rows spinbox.
394
void TileDialog::on_col_spinbutton_changed()
396
// quit if run by the attr_changed listener
401
// in turn, prevent listener from responding
403
SPDesktop *desktop = getDesktop();
404
Inkscape::Selection *selection = sp_desktop_selection (desktop);
406
GSList const *items = selection->itemList();
407
int selcount = g_slist_length((GSList *)items);
409
double PerRow = ceil(selcount / NoOfRowsSpinner.get_value());
410
NoOfColsSpinner.set_value(PerRow);
411
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
412
prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow);
418
* changed value in x padding spinbox.
420
void TileDialog::on_xpad_spinbutton_changed()
422
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
423
prefs->setDouble("/dialogs/gridtiler/XPad", XPadSpinner.get_value());
428
* changed value in y padding spinbox.
430
void TileDialog::on_ypad_spinbutton_changed()
432
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
433
prefs->setDouble("/dialogs/gridtiler/YPad", YPadSpinner.get_value());
438
* checked/unchecked autosize Rows button.
440
void TileDialog::on_RowSize_checkbutton_changed()
442
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
443
if (RowHeightButton.get_active()) {
444
prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20);
446
prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20);
448
RowHeightBox.set_sensitive ( !RowHeightButton.get_active());
452
* checked/unchecked autosize Rows button.
454
void TileDialog::on_ColSize_checkbutton_changed()
456
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
457
if (ColumnWidthButton.get_active()) {
458
prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20);
460
prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20);
462
ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active());
466
* changed value in columns spinbox.
468
void TileDialog::on_rowSize_spinbutton_changed()
470
// quit if run by the attr_changed listener
475
// in turn, prevent listener from responding
477
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
478
prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value());
484
* changed value in rows spinbox.
486
void TileDialog::on_colSize_spinbutton_changed()
488
// quit if run by the attr_changed listener
493
// in turn, prevent listener from responding
495
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
496
prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value());
502
* changed Radio button in Spacing group.
504
void TileDialog::Spacing_button_changed()
506
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
507
if (SpaceManualRadioButton.get_active()) {
508
prefs->setDouble("/dialogs/gridtiler/SpacingType", 20);
510
prefs->setDouble("/dialogs/gridtiler/SpacingType", -20);
513
SizesHBox.set_sensitive ( SpaceManualRadioButton.get_active());
517
* changed Radio button in Vertical Align group.
519
void TileDialog::VertAlign_changed()
521
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
522
if (VertTopRadioButton.get_active()) {
524
prefs->setInt("/dialogs/gridtiler/VertAlign", 0);
525
} else if (VertCentreRadioButton.get_active()){
527
prefs->setInt("/dialogs/gridtiler/VertAlign", 1);
528
} else if (VertBotRadioButton.get_active()){
530
prefs->setInt("/dialogs/gridtiler/VertAlign", 2);
535
* changed Radio button in Vertical Align group.
537
void TileDialog::HorizAlign_changed()
539
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
540
if (HorizLeftRadioButton.get_active()) {
542
prefs->setInt("/dialogs/gridtiler/HorizAlign", 0);
543
} else if (HorizCentreRadioButton.get_active()){
545
prefs->setInt("/dialogs/gridtiler/HorizAlign", 1);
546
} else if (HorizRightRadioButton.get_active()){
548
prefs->setInt("/dialogs/gridtiler/HorizAlign", 2);
553
* Desktop selection changed
555
void TileDialog::updateSelection()
557
// quit if run by the attr_changed listener
562
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
563
double col_width = 0;
564
double row_height = 0;
565
// in turn, prevent listener from responding
567
SPDesktop *desktop = getDesktop();
568
Inkscape::Selection *selection = sp_desktop_selection (desktop);
569
const GSList *items = selection->itemList();
570
int selcount = g_slist_length((GSList *)items);
572
if (NoOfColsSpinner.get_value()>1 && NoOfRowsSpinner.get_value()>1){
573
// Update the number of rows assuming number of columns wanted remains same.
574
double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value());
575
NoOfRowsSpinner.set_value(NoOfRows);
577
// if the selection has less than the number set for one row, reduce it appropriately
578
if (selcount<NoOfColsSpinner.get_value()) {
579
double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value());
580
NoOfColsSpinner.set_value(NoOfCols);
581
prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols);
584
double PerRow = ceil(sqrt(selcount));
585
double PerCol = ceil(sqrt(selcount));
586
NoOfRowsSpinner.set_value(PerRow);
587
NoOfColsSpinner.set_value(PerCol);
588
prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol));
598
/*##########################
600
##########################*/
602
static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg)
604
TileDialog *tledlg = (TileDialog *) dlg;
605
tledlg->updateSelection();
609
//#########################################################################
610
//## C O N S T R U C T O R / D E S T R U C T O R
611
//#########################################################################
615
TileDialog::TileDialog()
616
: UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE)
618
// bool used by spin button callbacks to stop loops where they change each other.
620
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
622
// could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!)
623
GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
624
GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
625
GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
628
// Selection Change signal
629
g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this);
632
Gtk::Box *contents = _getContents();
638
SPDesktop *desktop = getDesktop();
640
Inkscape::Selection *selection = sp_desktop_selection (desktop);
642
if (!selection->isEmpty()) {
643
GSList const *items = selection->itemList();
644
selcount = g_slist_length((GSList *)items);
648
/*#### Number of Rows ####*/
650
double PerRow = ceil(sqrt(selcount));
651
double PerCol = ceil(sqrt(selcount));
653
#ifdef DEBUG_GRID_ARRANGE
654
g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount);
657
NoOfRowsLabel.set_label(_("Rows:"));
658
NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN);
660
NoOfRowsSpinner.set_digits(0);
661
NoOfRowsSpinner.set_increments(1, 5);
662
NoOfRowsSpinner.set_range(1.0, 100.0);
663
NoOfRowsSpinner.set_value(PerCol);
664
NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed));
665
tips.set_tip(NoOfRowsSpinner, _("Number of rows"));
666
NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN);
667
gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj());
669
RowHeightButton.set_label(_("Equal height"));
670
double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15);
675
RowHeightButton.set_active(AutoRowSize);
677
NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN);
679
tips.set_tip(RowHeightButton, _("If not set, each row has the height of the tallest object in it"));
680
RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed));
683
/*#### Radio buttons to control vertical alignment ####*/
685
VertAlignLabel.set_label(_("Align:"));
686
VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN);
688
VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
689
VertAlignGroup = VertTopRadioButton.get_group();
690
VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0);
692
VertCentreRadioButton.set_group(VertAlignGroup);
693
VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
694
VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0);
696
VertBotRadioButton.set_group(VertAlignGroup);
697
VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
698
VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0);
700
VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1);
701
if (VertAlign == 0) {
702
VertTopRadioButton.set_active(TRUE);
704
else if (VertAlign == 1) {
705
VertCentreRadioButton.set_active(TRUE);
707
else if (VertAlign == 2){
708
VertBotRadioButton.set_active(TRUE);
710
VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN);
711
NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN);
714
SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN);
717
/*#### Label for X ####*/
718
padXByYLabel.set_label(" ");
719
XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN);
720
XByYLabel.set_markup(" × ");
721
XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN);
722
SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN);
723
gtk_size_group_add_widget(_col2, (GtkWidget *) XByYLabelVBox.gobj());
725
/*#### Number of columns ####*/
727
NoOfColsLabel.set_label(_("Columns:"));
728
NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN);
730
NoOfColsSpinner.set_digits(0);
731
NoOfColsSpinner.set_increments(1, 5);
732
NoOfColsSpinner.set_range(1.0, 100.0);
733
NoOfColsSpinner.set_value(PerRow);
734
NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed));
735
tips.set_tip(NoOfColsSpinner, _("Number of columns"));
736
NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN);
737
gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj());
739
ColumnWidthButton.set_label(_("Equal width"));
740
double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15);
745
ColumnWidthButton.set_active(AutoColSize);
746
NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN);
748
tips.set_tip(ColumnWidthButton, _("If not set, each column has the width of the widest object in it"));
749
ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed));
753
/*#### Radio buttons to control horizontal alignment ####*/
755
HorizAlignLabel.set_label(_("Align:"));
756
HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN);
758
HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
760
HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
761
HorizAlignGroup = HorizLeftRadioButton.get_group();
762
HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0);
764
HorizCentreRadioButton.set_group(HorizAlignGroup);
765
HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
766
HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0);
768
HorizRightRadioButton.set_group(HorizAlignGroup);
769
HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
770
HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0);
772
HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
774
HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1);
775
if (HorizAlign == 0) {
776
HorizLeftRadioButton.set_active(TRUE);
778
else if (HorizAlign == 1) {
779
HorizCentreRadioButton.set_active(TRUE);
781
else if (HorizAlign == 2) {
782
HorizRightRadioButton.set_active(TRUE);
784
HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN);
785
NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN);
788
SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN);
790
TileBox.pack_start(SpinsHBox, false, false, MARGIN);
793
/*#### Radio buttons to control spacing manually or to fit selection bbox ####*/
794
SpaceByBBoxRadioButton.set_label(_("Fit into selection box"));
795
SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
796
SpacingGroup = SpaceByBBoxRadioButton.get_group();
798
SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN);
800
SpaceManualRadioButton.set_label(_("Set spacing:"));
801
SpaceManualRadioButton.set_group(SpacingGroup);
802
SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
803
SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN);
805
TileBox.pack_start(SpacingVBox, false, false, MARGIN);
809
/*#### Y Padding ####*/
811
GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_row");
812
YPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
814
YPadSpinner.set_digits(1);
815
YPadSpinner.set_increments(0.2, 2);
816
YPadSpinner.set_range(-10000, 10000);
817
double YPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15);
818
YPadSpinner.set_value(YPad);
819
YPadBox.pack_start(YPadSpinner, true, true, MARGIN);
820
tips.set_tip(YPadSpinner, _("Vertical spacing between rows (px units)"));
821
YPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed));
822
gtk_size_group_add_widget(_col1, (GtkWidget *) YPadBox.gobj());
824
SizesHBox.pack_start(YPadBox, false, false, MARGIN);
828
Gtk::HBox *spacer = new Gtk::HBox;
829
SizesHBox.pack_start(*spacer, false, false, 0);
830
gtk_size_group_add_widget(_col2, (GtkWidget *) spacer->gobj());
834
/*#### X padding ####*/
836
GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_column");
837
XPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
839
XPadSpinner.set_digits(1);
840
XPadSpinner.set_increments(0.2, 2);
841
XPadSpinner.set_range(-10000, 10000);
842
double XPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15);
843
XPadSpinner.set_value(XPad);
844
XPadBox.pack_start(XPadSpinner, true, true, MARGIN);
845
tips.set_tip(XPadSpinner, _("Horizontal spacing between columns (px units)"));
846
XPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed));
847
gtk_size_group_add_widget(_col3, (GtkWidget *) XPadBox.gobj());
849
SizesHBox.pack_start(XPadBox, false, false, MARGIN);
853
TileBox.pack_start(SizesHBox, false, false, MARGIN);
855
contents->pack_start(TileBox);
857
double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15);
863
SpaceManualRadioButton.set_active(ManualSpacing);
864
SpaceByBBoxRadioButton.set_active(!ManualSpacing);
865
SizesHBox.set_sensitive (ManualSpacing);
868
TileOkButton = addResponseButton(_("Arrange"), GTK_RESPONSE_APPLY);
869
tips.set_tip((*TileOkButton), _("Arrange selected objects"));
876
} //namespace Inkscape
881
c-file-style:"stroustrup"
882
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
887
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 ::