Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Text Wrapping for Requirement Name #322

Merged
merged 7 commits into from
May 29, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions gaphor/SysML/requirements/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def update_shapes(self, event=None):
),
EditableText(
text=lambda: self.subject.name or "",
width=lambda: self.width - 4,
style={
"font-weight": FontWeight.BOLD,
"font-style": FontStyle.ITALIC
Expand Down
40 changes: 27 additions & 13 deletions gaphor/diagram/shapes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from math import pi
from typing import List, Optional, Tuple

import cairo
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
from gaphas.geometry import Rectangle
from typing_extensions import TypedDict

Expand All @@ -10,9 +11,9 @@
TextAlign,
TextDecoration,
VerticalAlign,
focus_box_pos,
text_draw,
text_draw_focus_box,
text_point_in_box,
text_size,
)

Expand Down Expand Up @@ -290,30 +291,34 @@ def size(self, cr):
max(min_h, height + padding[Padding.TOP] + padding[Padding.BOTTOM]),
)

def draw(self, context, bounding_box):
cr = context.cairo
min_w = max(self.style("min-width"), bounding_box.width)
min_h = max(self.style("min-height"), bounding_box.height)
text_align = self.style("text-align")
vertical_align = self.style("vertical-align")
def text_box(self, bounding_box: cairo.Context) -> Rectangle:
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
"""Add padding to a bounding box."""
padding = self.style("padding")

text_box = Rectangle(
return Rectangle(
bounding_box.x + padding[Padding.LEFT],
bounding_box.y + padding[Padding.TOP],
bounding_box.width - padding[Padding.RIGHT] - padding[Padding.LEFT],
bounding_box.height - padding[Padding.TOP] - padding[Padding.BOTTOM],
)

def draw(
self, context: cairo.Context, bounding_box: Rectangle
) -> Tuple[int, int, int, int]:
"""Draw the text, return the location and size."""
cr = context.cairo
min_w = max(self.style("min-width"), bounding_box.width)
min_h = max(self.style("min-height"), bounding_box.height)
text_align = self.style("text-align")
text_box = self.text_box(bounding_box)

x, y, w, h = text_draw(
cr,
self.text(),
self.font(),
lambda w, h: text_point_in_box(
text_box, (w, h), text_align, vertical_align
),
lambda w, h: (bounding_box.x, bounding_box.y),
width=text_box.width,
default_size=(min_w, min_h),
text_align=text_align,
)
return x, y, w, h

Expand All @@ -323,10 +328,19 @@ def __init__(self, text=lambda: "", width=lambda: -1, style: Style = {}):
super().__init__(text, width, style)
self.bounding_box = Rectangle()

def draw(self, context, bounding_box):
def draw(
self, context: cairo.Context, bounding_box: Rectangle
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
) -> Tuple[int, int, int, int]:
"""Draw the editable text."""
x, y, w, h = super().draw(context, bounding_box)
text_box = super().text_box(bounding_box)
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
cr = context.cairo
text_align = self.style("text-align")
vertical_align = self.style("vertical-align")
x, y = focus_box_pos(text_box, self.size(cr), text_align, vertical_align)
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
text_draw_focus_box(context, x, y, w, h)
self.bounding_box = Rectangle(x, y, width=w, height=h)
return x, y, w, h


def draw_default_head(context):
Expand Down
25 changes: 20 additions & 5 deletions gaphor/diagram/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import cairo
import gi
from gaphas.freehand import FreeHandCairoContext
from gaphas.geometry import Rectangle
from gaphas.painter import CairoBoundingBoxContext

# fmt: off
Expand Down Expand Up @@ -50,7 +51,6 @@ def text_draw_focus_box(context, x, y, w, h):
cr = context.cairo
cr.save()
try:
# cr.set_dash(() if context.focused else (2.0, 2.0), 0)
cr.set_dash((), 0)
if context.focused:
cr.set_source_rgb(0.6, 0.6, 0.6)
Expand All @@ -73,7 +73,15 @@ def text_size(
return layout.get_pixel_size() # type: ignore[no-any-return] # noqa: F723


def text_draw(cr, text, font, calculate_pos, width=-1, default_size=(0, 0)):
def text_draw(
cr,
text,
font,
calculate_pos,
width=-1,
default_size=(0, 0),
text_align=TextAlign.CENTER,
):
"""
Draw text relative to (x, y).
text - text to print (utf8)
Expand All @@ -83,7 +91,7 @@ def text_draw(cr, text, font, calculate_pos, width=-1, default_size=(0, 0)):
"""

if text:
layout = _text_layout(cr, text, font, width)
layout = _text_layout(cr, text, font, width, text_align)
w, h = layout.get_pixel_size()
else:
layout = None
Expand All @@ -99,7 +107,7 @@ def text_draw(cr, text, font, calculate_pos, width=-1, default_size=(0, 0)):
return (x, y, w, h)


def _text_layout(cr, text, font, width):
def _text_layout(cr, text, font, width, text_align=TextAlign.CENTER):
underline = False
layout = _pango_cairo_create_layout(cr)

Expand Down Expand Up @@ -132,6 +140,7 @@ def _text_layout(cr, text, font, width):
else:
layout.set_text(text, length=-1)
layout.set_width(int(width * Pango.SCALE))
layout.set_alignment(getattr(Pango.Alignment, text_align.name))
return layout


Expand Down Expand Up @@ -162,7 +171,13 @@ def _pango_cairo_show_layout(cr, layout):
PangoCairo.show_layout(cr, layout)


def text_point_in_box(bounding_box, text_size, text_align, vertical_align):
def focus_box_pos(
bounding_box: Rectangle,
text_size: cairo.Context,
danyeaw marked this conversation as resolved.
Show resolved Hide resolved
text_align: TextAlign,
vertical_align: VerticalAlign,
) -> Tuple[int, int]:
"""Calculate the focus box position based on alignment style."""
x, y, width, height = bounding_box
w, h = text_size

Expand Down