Example #1
0
    def place_cursor(self):

        rows = self.text.split("\n")
        prop = self.actor.GetTextProperty()

        cursor_top = self.top
        cursor_left = self.left

        max_width, total_height = text_dimensions(self.text, prop)
        _, before_h = text_dimensions("\n".join(rows[:self.row]), prop)

        if len(rows) > self.row + 1:
            _, after_h = text_dimensions("\n".join(rows[self.row + 1:]), prop)
            row_height = total_height - (after_h + before_h)
        else:
            row_height = total_height - before_h

        cursor_top += before_h

        row = rows[self.row]
        row_width, _ = text_dimensions(row, prop)
        before = row[:self.column]

        before_w, _ = text_dimensions(before, prop)
        cursor_left += before_w


        cursor_left += (max_width - row_width) / 2.0

        if self.cursor:
            self.cursor.detach()
            del self.cursor

        self.cursor = Button(self.interactor, left=cursor_left, top=cursor_top, width=2, height=row_height, corner_radius=0, bgcolor=(0,0,0))
        self.cursor.show()
Example #2
0
    def update(self):
        self.repr.SetNumberOfStates(len(self.states))
        dpi = self.interactor.GetRenderWindow().GetDPI()

        max_width = 0
        max_height = 0

        for index, state in enumerate(self.states):
            # Set up attributes with defaults if nothing is set
            label_text = state.label if state.label else self.label
            image = state.image if state.image else self.image

            if image:
                # Image supersedes label
                w, h, _ = image.GetDimensions()
                # Use a 3 px padding for now
                max_height = max(max_height, h)
                max_width = max(max_width, w)

            elif label_text:
                l_w, l_h = text_dimensions(
                    label_text, self.text_widget.actor.GetTextProperty(),
                    dpi)

                max_height = max(max_height, l_h)
                max_width = max(max_width, l_w)

        # Pad the text
        max_width += 2 * BUTTON_MARGIN
        max_height += 2 * BUTTON_MARGIN

        for index, state in enumerate(self.states):

            image = state.image if state.image else self.image
            bgcolor = state.bgcolor if state.bgcolor else self.bgcolor
            # Opacity not yet supported by this code
            # opacity = state.opacity if state.opacity else self.opacity

            # Something weird happens when images of drastically different sizes are passed in;
            # not hunting down that fix right now.
            if image is not None:
                width, height, _ = image.GetDimensions()
            else:
                width = self.width if self.width else int(max_width)
                height = self.height if self.height else int(max_height)

            # Optimization can be done here; can use the same image for
            # everything with same bgcolor + h/w
            bg_image = rounded_rect(width, height, self.radius, bgcolor)
            if image is not None:
                image = pad_image(image, max_width, max_height)
                bg_image = combine_images(bg_image, image)

            # Should deal with opacity here-ish
            self.repr.SetButtonTexture(index, bg_image)
Example #3
0
    def update(self):
        self.repr.SetNumberOfStates(len(self.states))
        dpi = self.interactor.GetRenderWindow().GetDPI()

        max_width = 0
        max_height = 0

        for index, state in enumerate(self.states):
            # Set up attributes with defaults if nothing is set
            label_text = state.label if state.label else self.label
            image = state.image if state.image else self.image

            if image:
                # Image supersedes label
                w, h, _ = image.GetDimensions()
                # Use a 3 px padding for now
                max_height = max(max_height, h)
                max_width = max(max_width, w)

            elif label_text:
                l_w, l_h = text_dimensions(
                    label_text, self.text_widget.actor.GetTextProperty(), dpi)

                max_height = max(max_height, l_h)
                max_width = max(max_width, l_w)

        # Pad the text
        max_width += 2 * BUTTON_MARGIN
        max_height += 2 * BUTTON_MARGIN

        for index, state in enumerate(self.states):

            image = state.image if state.image else self.image
            bgcolor = state.bgcolor if state.bgcolor else self.bgcolor
            # Opacity not yet supported by this code
            # opacity = state.opacity if state.opacity else self.opacity

            # Something weird happens when images of drastically different sizes are passed in;
            # not hunting down that fix right now.
            if image is not None:
                width, height, _ = image.GetDimensions()
            else:
                width = self.width if self.width else int(max_width)
                height = self.height if self.height else int(max_height)

            # Optimization can be done here; can use the same image for
            # everything with same bgcolor + h/w
            bg_image = rounded_rect(width, height, self.radius, bgcolor)
            if image is not None:
                image = pad_image(image, max_width, max_height)
                bg_image = combine_images(bg_image, image)

            # Should deal with opacity here-ish
            self.repr.SetButtonTexture(index, bg_image)
Example #4
0
    def place_cursor(self):

        rows = self.text.split("\n")
        prop = self.actor.GetTextProperty()

        cursor_top = self.top
        cursor_left = self.left

        max_width, total_height = text_dimensions(self.text, prop)
        _, before_h = text_dimensions("\n".join(rows[:self.row]), prop)

        if len(rows) > self.row + 1:
            _, after_h = text_dimensions("\n".join(rows[self.row + 1:]), prop)
            row_height = total_height - (after_h + before_h)
        else:
            row_height = total_height - before_h

        cursor_top += before_h

        row = rows[self.row]
        row_width, _ = text_dimensions(row, prop)
        before = row[:self.column]

        before_w, _ = text_dimensions(before, prop)
        cursor_left += before_w

        cursor_left += (max_width - row_width) / 2.0

        if self.cursor:
            self.cursor.detach()
            del self.cursor

        self.cursor = Button(self.interactor,
                             left=cursor_left,
                             top=cursor_top,
                             width=2,
                             height=row_height,
                             corner_radius=0,
                             bgcolor=(0, 0, 0))
        self.cursor.show()
Example #5
0
    def row_col_at_point(self, x, y):
        rows = self.text.split("\n")
        prop = self.actor.GetTextProperty()

        text_width, text_height = text_dimensions(self.text, prop)

        # Viewport coordinates of widget
        sw, sh = self.interactor.GetRenderWindow().GetSize()

        x0, y0 = self.left, sh - self.top

        # Adjust click coords to widget's bounds
        x = abs(x - x0)
        y = text_height - abs(y - y0)


        # Calculate the bounds of each row
        row_bounds = []
        max_width = 0
        # We're iterating in reverse because y goes from 0 at the bottom to 1 at the top
        row_at_point = None
        for row in rows[::-1]:
            if row == '':
                row = ' '

            w, h = text_dimensions(row, prop)
            row_bounds.append((w, h))

            if w > max_width:
                # Use for x offset calculations
                max_width = w

            if h < y and row_at_point is None:
                y = y - h
            else:
                row_at_point = rows.index(row)

        if row_at_point is None:
            row_at_point = len(rows) - 1

        # List was assembled backwards
        row_bounds.reverse()

        # Now let's find the column clicked...
        row = row_bounds[row_at_point]
        text = rows[row_at_point]

        # If max_width == row[0], then offset is 0 and all of the calcs below still work
        x -= (max_width - row[0]) / 2.0

        row_left = 0
        row_right = row[0]

        if x < row_left:
            # Clicked to the left of the row
            return row_at_point, 0

        if x > row_right:
            # Clicked to the right of the row
            return row_at_point, len(rows[row_at_point])

        if row == '':
            # Clicked on the blank row (inserted a space when calculating width earlier, for height considerations)
            return row_at_point, 1

        # OK, no easy answer; have to calc the width of each letter in the row till we find the column
        # Start at left or right depending on which side the click is closer to
        if x - row_left > row_right - x:
            # Start from right
            for reverse_index, c in enumerate(text[::-1]):
                w,_ = text_dimensions(c, prop)
                if row_right - w < x:
                    return row_at_point, len(text) - reverse_index
                # "New" right side is one character back
                row_right -= w
        else:
            # Start from left
            for index, c in enumerate(text):
                w, _ = text_dimensions(c, prop)
                if row_left + w > x:
                    return row_at_point, index
                # "New" left side is one character forward
                row_left += w
        # Return the very end of the box if we can't figure it out.
        return len(rows) - 1, len(rows[len(rows) - 1])
Example #6
0
    def row_col_at_point(self, x, y):
        rows = self.text.split("\n")
        prop = self.actor.GetTextProperty()

        dpi = self.interactor.GetRenderWindow().GetDPI()
        text_width, text_height = text_dimensions(self.text, prop, dpi)

        # Viewport coordinates of widget
        sw, sh = self.interactor.GetRenderWindow().GetSize()
        # Normalize to window space
        if x < 1 and y < 1:
            x = sw * x
            y = sh * y

        # Rotate the click out of box space
        x -= self.x
        y -= self.y

        x, y = rotate((x, y), -1 * prop.GetOrientation())

        x += self.x
        y += self.y

        x0, y0 = self.left, sh - self.top

        # Adjust click coords to widget's bounds
        x = abs(x - x0)
        y = text_height - abs(y - y0)

        # Calculate the bounds of each row
        row_bounds = []
        max_width = 0
        # We're iterating in reverse because y goes from 0 at the bottom to 1
        # at the top
        row_at_point = None

        for row in rows[::-1]:
            if row == '':
                dim_row = ' '
            else:
                dim_row = row

            w, h = text_dimensions(dim_row, prop, dpi)
            row_bounds.append((w, h))

            if w > max_width:
                # Use for x offset calculations
                max_width = w

            if h < y:
                y = y - h
            else:
                if row_at_point is None:
                    row_at_point = rows.index(row)

        if row_at_point is None:
            row_at_point = 0

        # List was assembled backwards
        row_bounds.reverse()

        # Now let's find the column clicked...
        row = row_bounds[row_at_point]
        text = rows[row_at_point]

        # If max_width == row[0], then offset is 0 and all of the calcs below
        # still work
        just = prop.GetJustificationAsString()

        if just == "Left":
            row_left = 0
        elif just == "Centered":
            row_left = (max_width - row[0]) / 2.
        elif just == "Right":
            row_left = max_width - row[0]

        row_right = row_left + row[0]

        if x < row_left:
            # Clicked to the left of the row
            return row_at_point, 0

        if x > row_right:
            # Clicked to the right of the row
            return row_at_point, len(rows[row_at_point])

        if row == '':
            # Clicked on the blank row (inserted a space when calculating width
            # earlier, for height considerations)
            return row_at_point, 1

        # OK, no easy answer; have to calc the width of each letter in the row till we find the column
        # Start from left
        w = 0
        ind = 1

        while row_left + w < x and ind < len(text):
            w, _ = text_dimensions(text[:ind], prop, dpi)
            ind += 1

        return row_at_point, ind - 1
Example #7
0
    def place_cursor(self):
        # Find current position of the text actor
        x, y = self.left, self.top

        # Use to adjust all window-space numbers
        w, h = self.interactor.GetRenderWindow().GetSize()

        # Translate distance from top to distance from bottom
        y = h - y

        # Prep a text property for getting measurements
        prop = vtk.vtkTextProperty()
        prop.ShallowCopy(self.actor.GetTextProperty())

        # Store for rotating the cursor's coords
        angle = prop.GetOrientation()

        # Reset so we get accurate dimensions
        prop.SetOrientation(0)

        rows = self.text.split("\n")

        dpi = self.interactor.GetRenderWindow().GetDPI()
        width, height = text_dimensions(self.text, prop, dpi)
        line_height = float(height) / len(rows)

        column_adjustment, _ = text_dimensions(rows[self.row][:self.column],
                                               prop, dpi)

        x += column_adjustment

        row_width, _ = text_dimensions(rows[self.row], prop, dpi)

        # Adjust for blank space caused by justifications
        halign = prop.GetJustificationAsString()
        if halign == "Centered":
            x += (width - row_width) / 2.
        elif halign == "Right":
            x += (width - row_width) + 1  # Adjust for some margin issues
        elif halign == "Left":
            x -= 3  # Adjust for some margin issues

        # Manual adjustments for justification artefacts
        valign = prop.GetVerticalJustificationAsString()
        if valign == "Top":
            y += 2
        elif valign == "Centered":
            pass
        elif valign == "Bottom":
            y -= 2

        # Get to the current row
        y -= line_height * self.row

        # Rotate both points to the orientation as the text
        y1 = y
        y2 = y - line_height

        x1 = x
        x2 = x

        x1, x2 = x1 - self.x, x2 - self.x
        y1, y2 = y1 - self.y, y2 - self.y

        x1, y1 = rotate((x1, y1), angle)
        x2, y2 = rotate((x2, y2), angle)

        x1 += self.x
        x2 += self.x
        y1 += self.y
        y2 += self.y

        self.cursor.point_1 = (x1, y1)
        self.cursor.point_2 = (x2, y2)
Example #8
0
    def row_col_at_point(self, x, y):
        rows = self.text.split("\n")
        prop = self.actor.GetTextProperty()

        text_width, text_height = text_dimensions(self.text, prop)

        # Viewport coordinates of widget
        sw, sh = self.interactor.GetRenderWindow().GetSize()

        x0, y0 = self.left, sh - self.top

        # Adjust click coords to widget's bounds
        x = abs(x - x0)
        y = text_height - abs(y - y0)

        # Calculate the bounds of each row
        row_bounds = []
        max_width = 0
        # We're iterating in reverse because y goes from 0 at the bottom to 1 at the top
        row_at_point = None
        for row in rows[::-1]:
            if row == '':
                row = ' '

            w, h = text_dimensions(row, prop)
            row_bounds.append((w, h))

            if w > max_width:
                # Use for x offset calculations
                max_width = w

            if h < y and row_at_point is None:
                y = y - h
            else:
                row_at_point = rows.index(row)

        if row_at_point is None:
            row_at_point = len(rows) - 1

        # List was assembled backwards
        row_bounds.reverse()

        # Now let's find the column clicked...
        row = row_bounds[row_at_point]
        text = rows[row_at_point]

        # If max_width == row[0], then offset is 0 and all of the calcs below still work
        x -= (max_width - row[0]) / 2.0

        row_left = 0
        row_right = row[0]

        if x < row_left:
            # Clicked to the left of the row
            return row_at_point, 0

        if x > row_right:
            # Clicked to the right of the row
            return row_at_point, len(rows[row_at_point])

        if row == '':
            # Clicked on the blank row (inserted a space when calculating width earlier, for height considerations)
            return row_at_point, 1

        # OK, no easy answer; have to calc the width of each letter in the row till we find the column
        # Start at left or right depending on which side the click is closer to
        if x - row_left > row_right - x:
            # Start from right
            for reverse_index, c in enumerate(text[::-1]):
                w, _ = text_dimensions(c, prop)
                if row_right - w < x:
                    return row_at_point, len(text) - reverse_index
                # "New" right side is one character back
                row_right -= w
        else:
            # Start from left
            for index, c in enumerate(text):
                w, _ = text_dimensions(c, prop)
                if row_left + w > x:
                    return row_at_point, index
                # "New" left side is one character forward
                row_left += w
        # Return the very end of the box if we can't figure it out.
        return len(rows) - 1, len(rows[len(rows) - 1])