EXP_ARRAY *qcad_layer_selection_get_object_array (QCADLayer *layer, EXP_ARRAY *ar) { GList *llItr = NULL ; for (llItr = layer->lstSelObjs ; llItr != NULL ; llItr = llItr->next) { if (NULL == ar) ar = exp_array_new (sizeof (QCADDesignObject *), 1) ; exp_array_insert_vals (ar, &(llItr->data), 1, 1, -1) ; } return ar ; }
void push_transformation () { TRANSFORMATION xform = {-1} ; xform.subs_top_x = subs_top_x ; xform.subs_top_y = subs_top_y ; xform.cxClientArea = cxClientArea ; xform.cyClientArea = cyClientArea ; xform.scale = scale ; if (NULL == transformation_stack) transformation_stack = exp_array_new (sizeof (TRANSFORMATION), 1) ; exp_array_insert_vals (transformation_stack, &xform, 1, 1, -1) ; }
static QCADLabel *get_label_from_array (EXP_ARRAY *ar, int idx, double dCurrentGrad, GdkColor *clr) { GRADUATION grad = {NULL, 0.0} ; GRADUATION *ar_grad = NULL ; if (idx == ar->icUsed) { grad.lbl = qcad_label_new ("%.2lf", dCurrentGrad) ; grad.dVal = dCurrentGrad ; exp_array_insert_vals (ar, &grad, 1, 1, -1) ; ar_grad = &grad ; } else if ((ar_grad = &exp_array_index_1d (ar, GRADUATION, idx))->dVal != dCurrentGrad) { qcad_label_set_text (QCAD_LABEL (ar_grad->lbl), "%.2lf", dCurrentGrad) ; ar_grad->dVal = dCurrentGrad ; } memcpy (&(QCAD_DESIGN_OBJECT (ar_grad->lbl)->clr), clr, sizeof (GdkColor)) ; return ar_grad->lbl ; }
static void precompute (QCADElectrode *electrode) { int Nix, Nix1 ; WorldPoint ptSrcLine, ptDstLine ; double factor1, factor2, dstx_minus_srcx, dsty_minus_srcy ; double pt1x_minus_pt0x, pt1y_minus_pt0y, pt3x_minus_pt2x, pt3y_minus_pt2y ; double reciprocal_of_x_divisions, reciprocal_of_y_divisions ; QCADRectangleElectrode *rc_electrode = QCAD_RECTANGLE_ELECTRODE (electrode) ; QCADDesignObject *obj = QCAD_DESIGN_OBJECT (electrode) ; double kose = cos (rc_electrode->angle), msin = -sin (rc_electrode->angle), sine = sin (rc_electrode->angle), half_cx = rc_electrode->cxWorld / 2.0, half_cy = rc_electrode->cyWorld / 2.0, xMin, yMin, xMax, yMax ; WorldPoint pt[4] = {{0,0},{0,0},{0,0},{0,0}}, ptCenter = {0,0} ; // Call parent precompute function QCAD_ELECTRODE_CLASS (g_type_class_peek (g_type_parent (QCAD_TYPE_RECTANGLE_ELECTRODE)))->precompute (electrode) ; ptCenter.xWorld = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ; ptCenter.yWorld = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ; // Create corner points pt[0].xWorld = ptCenter.xWorld - half_cx ; pt[0].yWorld = ptCenter.yWorld - half_cy ; pt[1].xWorld = ptCenter.xWorld + half_cx ; pt[1].yWorld = ptCenter.yWorld - half_cy ; pt[2].xWorld = ptCenter.xWorld + half_cx ; pt[2].yWorld = ptCenter.yWorld + half_cy ; pt[3].xWorld = ptCenter.xWorld - half_cx ; pt[3].yWorld = ptCenter.yWorld + half_cy ; if (0 != rc_electrode->angle) { // rotate corner points rc_electrode->precompute_params.pt[0].xWorld = kose * pt[0].xWorld + sine * pt[0].yWorld ; rc_electrode->precompute_params.pt[0].yWorld = msin * pt[0].xWorld + kose * pt[0].yWorld ; rc_electrode->precompute_params.pt[1].xWorld = kose * pt[1].xWorld + sine * pt[1].yWorld ; rc_electrode->precompute_params.pt[1].yWorld = msin * pt[1].xWorld + kose * pt[1].yWorld ; rc_electrode->precompute_params.pt[2].xWorld = kose * pt[2].xWorld + sine * pt[2].yWorld ; rc_electrode->precompute_params.pt[2].yWorld = msin * pt[2].xWorld + kose * pt[2].yWorld ; rc_electrode->precompute_params.pt[3].xWorld = kose * pt[3].xWorld + sine * pt[3].yWorld ; rc_electrode->precompute_params.pt[3].yWorld = msin * pt[3].xWorld + kose * pt[3].yWorld ; // Find binding box xMin = MIN (rc_electrode->precompute_params.pt[0].xWorld, MIN (rc_electrode->precompute_params.pt[1].xWorld, MIN (rc_electrode->precompute_params.pt[2].xWorld, rc_electrode->precompute_params.pt[3].xWorld))) ; xMax = MAX (rc_electrode->precompute_params.pt[0].xWorld, MAX (rc_electrode->precompute_params.pt[1].xWorld, MAX (rc_electrode->precompute_params.pt[2].xWorld, rc_electrode->precompute_params.pt[3].xWorld))) ; yMin = MIN (rc_electrode->precompute_params.pt[0].yWorld, MIN (rc_electrode->precompute_params.pt[1].yWorld, MIN (rc_electrode->precompute_params.pt[2].yWorld, rc_electrode->precompute_params.pt[3].yWorld))) ; yMax = MAX (rc_electrode->precompute_params.pt[0].yWorld, MAX (rc_electrode->precompute_params.pt[1].yWorld, MAX (rc_electrode->precompute_params.pt[2].yWorld, rc_electrode->precompute_params.pt[3].yWorld))) ; obj->bounding_box.xWorld = xMin ; obj->bounding_box.yWorld = yMin ; obj->bounding_box.cxWorld = xMax - xMin ; obj->bounding_box.cyWorld = yMax - yMin ; obj->x = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ; obj->y = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ; // move points back rc_electrode->precompute_params.pt[0].xWorld += ptCenter.xWorld - obj->x ; rc_electrode->precompute_params.pt[0].yWorld += ptCenter.yWorld - obj->y ; rc_electrode->precompute_params.pt[1].xWorld += ptCenter.xWorld - obj->x ; rc_electrode->precompute_params.pt[1].yWorld += ptCenter.yWorld - obj->y ; rc_electrode->precompute_params.pt[2].xWorld += ptCenter.xWorld - obj->x ; rc_electrode->precompute_params.pt[2].yWorld += ptCenter.yWorld - obj->y ; rc_electrode->precompute_params.pt[3].xWorld += ptCenter.xWorld - obj->x ; rc_electrode->precompute_params.pt[3].yWorld += ptCenter.yWorld - obj->y ; obj->bounding_box.xWorld += ptCenter.xWorld - obj->x ; obj->bounding_box.yWorld += ptCenter.yWorld - obj->y ; obj->x = ptCenter.xWorld ; obj->y = ptCenter.yWorld ; } else { rc_electrode->precompute_params.pt[0] = pt[0] ; rc_electrode->precompute_params.pt[1] = pt[1] ; rc_electrode->precompute_params.pt[2] = pt[2] ; rc_electrode->precompute_params.pt[3] = pt[3] ; obj->bounding_box.xWorld = pt[0].xWorld ; obj->bounding_box.yWorld = pt[0].yWorld ; obj->bounding_box.cxWorld = rc_electrode->cxWorld ; obj->bounding_box.cyWorld = rc_electrode->cyWorld ; obj->x = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ; obj->y = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ; } if (NULL != rc_electrode->precompute_params.pts) exp_array_free (rc_electrode->precompute_params.pts) ; rc_electrode->precompute_params.pts = exp_array_new (sizeof (WorldPoint), 2) ; for (Nix = 0 ; Nix < rc_electrode->n_y_divisions ; Nix++) exp_array_insert_vals (rc_electrode->precompute_params.pts, NULL, rc_electrode->n_x_divisions, 2, -1, TRUE, 0, TRUE) ; // This is a faaar better place to multiply by 1e9 than get_potential rc_electrode->precompute_params.rho_factor = 1e9 * QCAD_ELECTRODE (rc_electrode)->precompute_params.capacitance / (rc_electrode->n_x_divisions * rc_electrode->n_y_divisions) ; pt1x_minus_pt0x = rc_electrode->precompute_params.pt[1].xWorld - rc_electrode->precompute_params.pt[0].xWorld ; pt1y_minus_pt0y = rc_electrode->precompute_params.pt[1].yWorld - rc_electrode->precompute_params.pt[0].yWorld ; pt3x_minus_pt2x = rc_electrode->precompute_params.pt[3].xWorld - rc_electrode->precompute_params.pt[2].xWorld ; pt3y_minus_pt2y = rc_electrode->precompute_params.pt[3].yWorld - rc_electrode->precompute_params.pt[2].yWorld ; reciprocal_of_x_divisions = 1.0 / rc_electrode->n_x_divisions ; reciprocal_of_y_divisions = 1.0 / rc_electrode->n_y_divisions ; for (Nix = 0 ; Nix < rc_electrode->n_x_divisions ; Nix++) { factor1 = reciprocal_of_x_divisions * (Nix + 0.5) ; factor2 = reciprocal_of_x_divisions * ((rc_electrode->n_x_divisions - Nix) - 0.5) ; ptSrcLine.xWorld = rc_electrode->precompute_params.pt[0].xWorld + pt1x_minus_pt0x * factor1 ; ptSrcLine.yWorld = rc_electrode->precompute_params.pt[0].yWorld + pt1y_minus_pt0y * factor1 ; ptDstLine.xWorld = rc_electrode->precompute_params.pt[2].xWorld + pt3x_minus_pt2x * factor2 ; ptDstLine.yWorld = rc_electrode->precompute_params.pt[2].yWorld + pt3y_minus_pt2y * factor2 ; dstx_minus_srcx = ptDstLine.xWorld - ptSrcLine.xWorld ; dsty_minus_srcy = ptDstLine.yWorld - ptSrcLine.yWorld ; for (Nix1 = 0 ; Nix1 < rc_electrode->n_y_divisions ; Nix1++) { exp_array_index_2d (rc_electrode->precompute_params.pts, WorldPoint, Nix1, Nix).xWorld = ptSrcLine.xWorld + dstx_minus_srcx * reciprocal_of_y_divisions * (Nix1 + 0.5) ; exp_array_index_2d (rc_electrode->precompute_params.pts, WorldPoint, Nix1, Nix).yWorld = ptSrcLine.yWorld + dsty_minus_srcy * reciprocal_of_y_divisions * (Nix1 + 0.5) ; } } }
// start helpers static void swap_buses (GtkTreeModel *tm, GtkTreeSelection *sel, bus_layout_D *dialog, GtkTreePath *tpSrc, GtkTreePath *tpDst) { int Nix ; GtkTreeIter itr ; SWAP_BUSES_STRUCT src, dst ; SWAP_BUSES_STRUCT *min = NULL, *max = NULL ; EXP_ARRAY *ar_bSelSrc = NULL, *ar_bSelDst = NULL ; gboolean bDstExpanded = TRUE ; src.tp = gtk_tree_path_copy (tpSrc) ; gtk_tree_model_get_iter (tm, &(src.itr), tpSrc) ; src.icChildren = gtk_tree_model_iter_n_children (tm, &(src.itr)) ; dst.tp = gtk_tree_path_copy (tpDst) ; gtk_tree_model_get_iter (tm, &(dst.itr), tpDst) ; dst.icChildren = gtk_tree_model_iter_n_children (tm, &(dst.itr)) ; if (dst.icChildren < src.icChildren) { min = &dst ; max = &src ; } else { min = &src ; max = &dst ; } bDstExpanded = gtk_tree_view_row_expanded (gtk_tree_selection_get_tree_view (sel), dst.tp) ; g_signal_handlers_block_matched (G_OBJECT (sel), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer)tree_view_selection_changed, NULL) ; for (Nix = 0 ; Nix < max->icChildren - min->icChildren ; Nix++) gtk_tree_store_append (GTK_TREE_STORE (tm), &itr, &(min->itr)) ; gtk_tree_path_down (src.tp) ; gtk_tree_path_down (dst.tp) ; ar_bSelSrc = exp_array_new (sizeof (gboolean), 1) ; ar_bSelDst = exp_array_new (sizeof (gboolean), 1) ; exp_array_insert_vals (ar_bSelSrc, NULL, max->icChildren, 1, 0) ; exp_array_insert_vals (ar_bSelDst, NULL, max->icChildren, 1, 0) ; for (Nix = 0 ; Nix < max->icChildren ; Nix++) { exp_array_index_1d (ar_bSelSrc, gboolean, Nix) = gtk_tree_selection_path_is_selected (sel, src.tp) ; exp_array_index_1d (ar_bSelDst, gboolean, Nix) = gtk_tree_selection_path_is_selected (sel, dst.tp) ; gtk_tree_path_next (src.tp) ; gtk_tree_path_next (dst.tp) ; } gtk_tree_path_up (src.tp) ; gtk_tree_path_up (dst.tp) ; gtk_tree_path_down (src.tp) ; gtk_tree_path_down (dst.tp) ; for (Nix = 0 ; Nix < max->icChildren ; Nix++) { if (exp_array_index_1d (ar_bSelDst, gboolean, Nix)) gtk_tree_view_expand_to_path (gtk_tree_selection_get_tree_view (sel), src.tp) ; if (exp_array_index_1d (ar_bSelSrc, gboolean, Nix)) gtk_tree_view_expand_to_path (gtk_tree_selection_get_tree_view (sel), dst.tp) ; gtk_tree_path_next (src.tp) ; gtk_tree_path_next (dst.tp) ; } gtk_tree_path_up (src.tp) ; gtk_tree_path_up (dst.tp) ; gtk_tree_path_down (src.tp) ; gtk_tree_path_down (dst.tp) ; for (Nix = 0 ; Nix < max->icChildren ; Nix++) { swap_model_paths_contents (tm, src.tp, dst.tp) ; gtk_tree_path_next (src.tp) ; gtk_tree_path_next (dst.tp) ; } gtk_tree_path_up (src.tp) ; gtk_tree_path_up (dst.tp) ; gtk_tree_path_down (src.tp) ; gtk_tree_path_down (dst.tp) ; for (Nix = 0 ; Nix < max->icChildren ; Nix++) { GTK_TREE_SELECTION_SET_PATH_SELECTED (sel, src.tp, exp_array_index_1d (ar_bSelDst, gboolean, Nix)) ; GTK_TREE_SELECTION_SET_PATH_SELECTED (sel, dst.tp, exp_array_index_1d (ar_bSelSrc, gboolean, Nix)) ; gtk_tree_path_next (src.tp) ; gtk_tree_path_next (dst.tp) ; } gtk_tree_path_up (src.tp) ; gtk_tree_path_up (dst.tp) ; swap_model_paths_contents (tm, src.tp, dst.tp) ; gtk_tree_path_down (src.tp) ; gtk_tree_path_down (dst.tp) ; for (Nix = 0 ; Nix < min->icChildren ; Nix++) gtk_tree_path_next (max->tp) ; if (gtk_tree_model_get_iter (tm, &itr, max->tp)) while (gtk_tree_store_remove (GTK_TREE_STORE (tm), &itr)) ; if (!bDstExpanded) { for (Nix = 0 ; Nix < ar_bSelDst->icUsed ; Nix++) if (exp_array_index_1d (ar_bSelDst, gboolean, Nix)) break ; if (Nix == ar_bSelDst->icUsed) { gtk_tree_path_up (src.tp) ; gtk_tree_view_collapse_row (gtk_tree_selection_get_tree_view (sel), src.tp) ; } } exp_array_free (ar_bSelSrc) ; exp_array_free (ar_bSelDst) ; gtk_tree_path_free (src.tp) ; gtk_tree_path_free (dst.tp) ; g_signal_handlers_unblock_matched (G_OBJECT (sel), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer)tree_view_selection_changed, NULL) ; tree_view_selection_changed (sel, dialog) ; }
static void DialogToBusLayout (bus_layout_D *dialog, BUS_LAYOUT *bus_layout) { GtkTreeModel *tm = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tview)) ; int Nix ; int icTopLevel = gtk_tree_model_iter_n_children (tm, NULL), icCells = -1 ; GtkTreePath *tp = NULL, *tpCells = NULL ; GtkTreeIter itr ; int Nix1, idxCell = -1 ; int row_type ; EXP_ARRAY *cell_list = NULL ; BUS *bus ; // destroy all buses before adding the new ones for (Nix = bus_layout->buses->icUsed - 1 ; Nix > -1 ; Nix--) { exp_array_free (exp_array_index_1d (bus_layout->buses, BUS, Nix).cell_indices) ; g_free (exp_array_index_1d (bus_layout->buses, BUS, Nix).pszName) ; } exp_array_remove_vals (bus_layout->buses, 1, 0, bus_layout->buses->icUsed) ; // Since we've destroyed all buses, no cells are members of any bus any longer for (Nix = 0 ; Nix < bus_layout->inputs->icUsed ; Nix++) exp_array_index_1d (bus_layout->inputs, BUS_LAYOUT_CELL, Nix).bIsInBus = FALSE ; for (Nix = 0 ; Nix < bus_layout->outputs->icUsed ; Nix++) exp_array_index_1d (bus_layout->outputs, BUS_LAYOUT_CELL, Nix).bIsInBus = FALSE ; if (icTopLevel > 0) { tp = gtk_tree_path_new_first () ; for (Nix = 0 ; Nix < icTopLevel ; Nix++, gtk_tree_path_next (tp)) { gtk_tree_model_get_iter (tm, &itr, tp) ; gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_TYPE, &row_type, -1) ; if (ROW_TYPE_BUS & row_type) { exp_array_insert_vals (bus_layout->buses, NULL, 1, 1, -1) ; bus = &(exp_array_index_1d (bus_layout->buses, BUS, bus_layout->buses->icUsed - 1)) ; gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_NAME, &(bus->pszName), -1) ; if (ROW_TYPE_INPUT & row_type) { bus->bus_function = QCAD_CELL_INPUT ; cell_list = bus_layout->inputs ; } else { bus->bus_function = QCAD_CELL_OUTPUT ; cell_list = bus_layout->outputs ; } bus->cell_indices = exp_array_new (sizeof (int), 1) ; if ((icCells = gtk_tree_model_iter_n_children (tm, &itr)) > 0) { gtk_tree_path_down (tpCells = gtk_tree_path_copy (tp)) ; for (Nix1 = 0 ; Nix1 < icCells ; Nix1++, gtk_tree_path_next (tpCells)) { gtk_tree_model_get_iter (tm, &itr, tpCells) ; gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_INDEX, &idxCell, -1) ; exp_array_insert_vals (bus->cell_indices, &idxCell, 1, 1, -1) ; // Flag this cell in the master cell list as a member of some bus exp_array_index_1d (cell_list, BUS_LAYOUT_CELL, idxCell).bIsInBus = TRUE ; } gtk_tree_path_free (tpCells) ; } } } gtk_tree_path_free (tp) ; } }