コード例 #1
0
    def align_left_or_top(self, rows, padding, column_or_row, aligned_axis,
                          below_or_right_axis, width_or_height):
        """ Align columns or rows to the left or top edge """
        constraints = []
        for i in range(0, len(rows) - 1):
            row1 = rows[i]
            row2 = rows[i + 1]
            if len(row1) > 0 and len(row2) > 0:
                shape1 = row1[0]
                shape2 = row2[0]

                # Width or height of shape1
                w_or_h = str(shape1.computed_width()
                             ) if width_or_height == "width" else str(
                                 shape1.computed_height())

                # Shape1 row is left or top aligned to shape2 row
                constraints.append(
                    cb.eq(shape1.variables[aligned_axis].id,
                          shape2.variables[aligned_axis].id))

                # shape2 row is below or to the right of shape1 row
                constraints.append(
                    cb.lte(
                        cb.add(shape1.variables[below_or_right_axis].id,
                               cb.add(w_or_h, padding)),
                        shape2.variables[below_or_right_axis].id))
        if len(constraints):
            return cb.and_expr(constraints)
        return True
コード例 #2
0
    def set_container_size_main_axis(self, container, padding, rows_or_columns,
                                     width_or_height):
        """ Constraint for the main axis size of the container """
        size = ""
        num_rows_or_columns = len(rows_or_columns)
        outside_padding = container.variables.outside_padding.id if container.at_root else "0"
        for i in range(0, num_rows_or_columns):
            row_or_column = rows_or_columns[i]
            if len(row_or_column):
                spacing = padding if i < num_rows_or_columns - 1 else 0
                m_height_or_width = None
                if width_or_height == "width":
                    m_height_or_width = size_constraint_helpers.get_max_width_constraint(
                        1, 0, row_or_column)
                else:
                    m_height_or_width = size_constraint_helpers.get_max_height_constraint(
                        1, 0, row_or_column)

                if len(size):
                    size = cb.add(size, cb.add(m_height_or_width,
                                               str(spacing)))
                else:
                    size = cb.add(m_height_or_width, str(spacing))

        container_size = cb.add(
            cb.mult("2", outside_padding), str(container.computed_width())
        ) if width_or_height == "width" else str(container.computed_height())
        return cb.eq(container_size, size)
コード例 #3
0
 def set_container_size_cross_axis(self, container, padding,
                                   rows_or_columns, width_or_height):
     """ Constraint for the cross axis size of the container """
     outside_padding = container.variables.outside_padding.id if container.at_root else "0"
     size = self.get_widest_row_constraint(
         1, 0, rows_or_columns, padding
     ) if width_or_height == "width" else self.get_tallest_column_constraint(
         1, 0, rows_or_columns, padding)
     container_size = cb.add(
         cb.mult("2", outside_padding), str(container.computed_width())
     ) if width_or_height == "width" else str(container.computed_height())
     return cb.eq(container_size, size)
コード例 #4
0
    def align_rows_or_columns(self, container, padding, rows, column_or_row,
                              aligned_axis, aligned_axis_size, layout_axis,
                              layout_axis_size):
        """ Align rows or columns elements with a column or row to the alignment of the parent container """
        constraints = []
        l_index = container.variables.alignment.domain.index("left")
        c_index = container.variables.alignment.domain.index("center")
        is_left = cb.eq(container.variables.alignment.id, str(l_index))
        is_center = cb.eq(container.variables.alignment.id, str(c_index))

        for row in rows:
            for i in range(len(row) - 1):
                shape1 = row[i]
                shape2 = row[i + 1]

                aligned_axis_size_value = str(shape1.computed_width(
                )) if aligned_axis_size == "width" else str(
                    shape1.computed_height())
                aligned_axis_size_value2 = str(shape2.computed_width(
                )) if aligned_axis_size == "width" else str(
                    shape2.computed_height())

                left_top_aligned = cb.eq(shape1.variables[aligned_axis].id,
                                         shape2.variables[aligned_axis].id)
                right_bottom_aligned = cb.eq(
                    cb.add(shape1.variables[aligned_axis].id,
                           aligned_axis_size_value),
                    cb.add(shape2.variables[aligned_axis].id,
                           aligned_axis_size_value2))
                center_aligned = cb.eq(
                    cb.add(shape1.variables[aligned_axis].id,
                           cb.div(aligned_axis_size_value, "2")),
                    cb.add(shape2.variables[aligned_axis].id,
                           cb.div(aligned_axis_size_value2, "2")))

                constraints.append(
                    cb.ite(
                        is_left, left_top_aligned,
                        cb.ite(is_center, center_aligned,
                               right_bottom_aligned)))

                # Shape 2 is exactly to the right of shape 1 or to the bottom if in a column
                layout_axis_size_value = str(shape1.computed_width(
                )) if layout_axis_size == "width" else str(
                    shape1.computed_height())
                constraints.append(
                    cb.eq(
                        cb.add(shape1.variables[layout_axis].id,
                               cb.add(layout_axis_size_value, padding)),
                        shape2.variables[layout_axis].id))

        if len(constraints):
            return cb.and_expr(constraints)
        return True
コード例 #5
0
    def encode_previous_solution_from_model(self, model, solution_id):
        # The next solution cannot be the exact same outputs as the previous assignment
        # It may be possible for multiple solutions to have the same outputs (exact x,y coordinates for all shapes)
        # So to restrict this, we encode the X,Y positions in the clauses to prevent these solutions
        all_values = []
        variables = solution.parse_variables_from_model(model)

        decl_constraints = ""  # Because from_string requires declaring vars again even if already defined :(
        for v_i in range(0, len(self.output_variables)):
            variable = self.output_variables[v_i]
            model_var = variables[variable.id]
            variable_value = model[model_var]
            variable_value = variable_value.as_string()
            variable_value = int(variable_value)
            all_values.append(smt.eq(variable.id, str(variable_value)))
            decl_constraints += smt.declare(variable.id, variable.type)

        constraints = smt.assert_expr(
            smt.not_expr(smt.and_expr(all_values)),
            "prevent_prev_solution_" + solution_id + "_from_appearing_again")
        constraints = decl_constraints + constraints
        self.override_solver.load_constraints(constraints)
コード例 #6
0
    def encode_assigned_variable(self, variable):
        """ Used by the search loops to create constraints to encode
		 an equality constraint for a variable value to the value it has been assigned by the search """
        constraints = smt.declare(variable.id, variable.type)
        if variable.name == "grid_layout":
            assigned_value = variable.domain[variable.assigned]

            marg_var = self.shapes[variable.shape_id].variables.margin
            constraints += smt.declare(marg_var.id, marg_var.type)
            marg = smt.eq(marg_var.id, str(assigned_value[0]))

            cols_var = self.shapes[variable.shape_id].variables.columns
            constraints += smt.declare(cols_var.id, cols_var.type)
            cols = smt.eq(cols_var.id, str(assigned_value[1]))

            gutter_width_var = self.shapes[
                variable.shape_id].variables.gutter_width
            constraints += smt.declare(gutter_width_var.id,
                                       gutter_width_var.type)
            gutter_width = smt.eq(gutter_width_var.id, str(assigned_value[2]))

            col_width_var = self.shapes[
                variable.shape_id].variables.column_width
            constraints += smt.declare(col_width_var.id, col_width_var.type)
            col_width = smt.eq(col_width_var.id, str(assigned_value[3]))
            and_expr = smt.and_expr([marg, cols, gutter_width, col_width])
            constraints += smt.assert_expr(
                and_expr, "variable_" + variable.id + "_assigned_to_" +
                str(variable.assigned))
            self.override_solver.load_constraints(constraints)

        elif variable.name == "size_combo":
            assigned_value = variable.domain[variable.assigned]
            width_var = self.shapes[variable.shape_id].variables.width
            constraints += smt.declare(width_var.id, width_var.type)
            width = smt.eq(width_var.id, str(assigned_value[0]))

            height_var = self.shapes[variable.shape_id].variables.height
            constraints += smt.declare(height_var.id, height_var.type)
            height = smt.eq(height_var.id, str(assigned_value[1]))

            size_factor = self.shapes[variable.shape_id].variables.size_factor
            constraints += smt.declare(size_factor.id, size_factor.type)
            size_fact = smt.eq(size_factor.id, str(assigned_value[2]))

            and_expr = smt.and_expr([width, height, size_fact])

            constraints += smt.assert_expr(
                and_expr, "variable_" + variable.id + "_assigned_to_" +
                str(variable.assigned))
            self.override_solver.load_constraints(constraints)

        elif variable.index_domain:
            constraints += smt.assert_expr(
                smt.eq(variable.id, str(variable.assigned)), "variable_" +
                variable.id + "_assigned_to_" + str(variable.assigned))
            self.override_solver.load_constraints(constraints)
        else:
            dom_value = variable.domain[variable.assigned]
            if variable.type == "String":
                dom_value = "\"" + dom_value + "\""

            constraints += smt.assert_expr(
                smt.eq(variable.id, str(dom_value)), "variable_" +
                variable.id + "_assigned_to_" + str(variable.assigned))
            self.override_solver.load_constraints(constraints)