Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

void Inkscape::UI::Dialog::TileDialog::Grid_Arrange (  )

Do the actual work

Make sure the top and left of the grid dont move by compensating for align values.

Definition at line 122 of file tile.cpp.

References Inkscape::Selection::bounds(), SPItem::getBounds(), Inkscape::Selection::itemList(), on_col_spinbutton_changed(), on_row_spinbutton_changed(), sp_document_ensure_up_to_date(), sp_item_i2d_affine(), sp_item_i2doc_affine(), and sp_item_write_transform().

Referenced by _apply().

{

    int cnt,row_cnt,col_cnt,a,row,col;
    double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy;
    double total_col_width,total_row_height;
    col_width = 0;
    row_height = 0;
    total_col_width=0;
    total_row_height=0;

    // check for correct numbers in the row- and col-spinners
    on_col_spinbutton_changed();
    on_row_spinbutton_changed();

    // set padding to manual values
    paddingx = XPadSpinner.get_value();
    paddingy = YPadSpinner.get_value();

    std::vector<double> row_heights;
    std::vector<double> col_widths;
    std::vector<double> row_ys;
    std::vector<double> col_xs;

    int NoOfCols = NoOfColsSpinner.get_value_as_int();
    int NoOfRows = NoOfRowsSpinner.get_value_as_int();

    width = 0;
    for (a=0;a<NoOfCols; a++){
        col_widths.push_back(width);
    }

    height = 0;
    for (a=0;a<NoOfRows; a++){
        row_heights.push_back(height);
    }
    grid_left = 99999;
    grid_top = 99999;

    SPDesktop *desktop = getDesktop();
    sp_document_ensure_up_to_date(sp_desktop_document(desktop));

    Inkscape::Selection *selection = sp_desktop_selection (desktop);
    const GSList *items = selection ? selection->itemList() : 0;
    cnt=0;
    for (; items != NULL; items = items->next) {
        SPItem *item = SP_ITEM(items->data);
        Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
        if (!b) {
            continue;
        }

        width = b->dimensions()[Geom::X];
        height = b->dimensions()[Geom::Y];

        cx = b->midpoint()[Geom::X];
        cy = b->midpoint()[Geom::Y];

        if (b->min()[Geom::X] < grid_left) {
            grid_left = b->min()[Geom::X];
        }
        if (b->min()[Geom::Y] < grid_top) {
            grid_top = b->min()[Geom::Y];
        }
        if (width > col_width) {
            col_width = width;
        }
        if (height > row_height) {
            row_height = height;
        }
    }


    // require the sorting done before we can calculate row heights etc.

    g_return_if_fail(selection);
    const GSList *items2 = selection->itemList();
    GSList *rev = g_slist_copy((GSList *) items2);
    GSList *sorted = NULL;
    rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position);
    sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position);


    // Calculate individual Row and Column sizes if necessary


        cnt=0;
        const GSList *sizes = sorted;
        for (; sizes != NULL; sizes = sizes->next) {
            SPItem *item = SP_ITEM(sizes->data);
            Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
            if (b) {
                width = b->dimensions()[Geom::X];
                height = b->dimensions()[Geom::Y];
                if (width > col_widths[(cnt % NoOfCols)]) {
                    col_widths[(cnt % NoOfCols)] = width;
                }
                if (height > row_heights[(cnt / NoOfCols)]) {
                    row_heights[(cnt / NoOfCols)] = height;
                }
            }

            cnt++;
        }


    /// Make sure the top and left of the grid dont move by compensating for align values.
    if (RowHeightButton.get_active()){
        grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign));
    }
    if (ColumnWidthButton.get_active()){
        grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign));
    }

    #ifdef DEBUG_GRID_ARRANGE
     g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left);
    #endif

    // Calculate total widths and heights, allowing for columns and rows non uniformly sized.

    if (ColumnWidthButton.get_active()){
        total_col_width = col_width * NoOfCols;
        col_widths.clear();
        for (a=0;a<NoOfCols; a++){
            col_widths.push_back(col_width);
        }
    } else {
        for (a = 0; a < (int)col_widths.size(); a++)
        {
          total_col_width += col_widths[a] ;
        }
    }

    if (RowHeightButton.get_active()){
        total_row_height = row_height * NoOfRows;
        row_heights.clear();
        for (a=0;a<NoOfRows; a++){
            row_heights.push_back(row_height);
        }
    } else {
        for (a = 0; a < (int)row_heights.size(); a++)
        {
          total_row_height += row_heights[a] ;
        }
    }


    Geom::OptRect sel_bbox = selection->bounds();
    // Fit to bbox, calculate padding between rows accordingly.
    if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
#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));
#endif
        paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1);
        paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1);
    }

/*
    Horizontal align  - Left    = 0
                        Centre  = 1
                        Right   = 2

    Vertical align    - Top     = 0
                        Middle  = 1
                        Bottom  = 2

    X position is calculated by taking the grids left co-ord, adding the distance to the column,
   then adding 1/2 the spacing multiplied by the align variable above,
   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++){
        if (a<1) col_xs.push_back(0);
        else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]);
    }


    for (a=0;a<NoOfRows; a++){
        if (a<1) row_ys.push_back(0);
        else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]);
    }

    cnt=0;
  for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) {

             GSList *current_row = NULL;
             for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) {
                 current_row = g_slist_append (current_row, sorted->data);
                 sorted = sorted->next;
             }

             for (; current_row != NULL; current_row = current_row->next) {
                 SPItem *item=SP_ITEM(current_row->data);
                 Inkscape::XML::Node *repr = SP_OBJECT_REPR(item);
                 Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
                 Geom::Point min;
                 if (b) {
                     width = b->dimensions()[Geom::X];
                     height = b->dimensions()[Geom::Y];
                     min = b->min();
                 } else {
                     width = height = 0;
                     min = Geom::Point(0, 0);
                 }

                 row = cnt / NoOfCols;
                 col = cnt % NoOfCols;

                 new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
                 new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];

                 // signs are inverted between x and y due to y inversion
                 Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y);
                 Geom::Matrix const affine = Geom::Matrix(Geom::Translate(move));
                 sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
                 sp_item_write_transform(item, repr, item->transform,  NULL);
                 SP_OBJECT (current_row->data)->updateRepr();
                 cnt +=1;
             }
             g_slist_free (current_row);
    }

    sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE,
                      _("Arrange in a grid"));

}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index