C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

ルーティングを行いたい2

こちらの続きです。
ルーティングを行いたい1 - C#ATIA
こちらも関連してます。
Canvasでon_hoverイベント3 - C#ATIA

早い話が、くっ付けました。

# python using-flet
import flet as ft
import flet.canvas as cv
import math

def main(page: ft.Page):

    canvasWidth = 600
    canvasHeight = 600

    stroke_paint = ft.Paint(stroke_width=5, style=ft.PaintingStyle.STROKE)
    line_paint = ft.Paint(stroke_width=1, style=ft.PaintingStyle.STROKE)
    fill_paint = ft.Paint(style=ft.PaintingStyle.FILL, color=ft.colors.BLACK)

    def on_hover(e: ft.DragStartEvent) -> None:
        x=e.local_x-(canvasWidth*0.5)
        y=(e.local_y-(canvasHeight*0.5))*-1

        shapes = [s for s in canvas.shapes if isinstance(s, cv.Circle)]
        change_color(shapes, e.local_x, e.local_y)

        pos.value = f"{x},{y}"
        pos.update()

    def on_exit(e: ft.DragStartEvent) -> None:
        pos.value = "-"
        pos.update()

    def is_hover(shape, x, y) -> None:
        return  math.sqrt(
            (shape.x - x)*(shape.x - x) + (shape.y - y)*(shape.y - y)
        ) < shape.radius

    def change_color(shapes, x, y) -> None:
        for shape in reversed(shapes):
            if is_hover(shape, x, y):
                shape.paint.color = ft.colors.RED
            elif shape.paint.color != ft.colors.BLACK:
                shape.paint.color = ft.colors.BLACK
            shape.update()

    def create_circle(e: ft.DragStartEvent) -> None:
        canvas.shapes = canvas.shapes[:3]
        canvas.update()

        lst = e.control.value.split("\n")
        for txt in lst:
            info = txt.split(",")
            if len(info) < 3: continue
            if not all([is_float(v) for v in info]): continue

            canvas.shapes.append(
                cv.Circle(
                    x=float(info[0])+(canvasWidth*0.5),
                    y=(float(info[1])*-1)+(canvasHeight*0.5),
                    radius=float(info[2])*0.5,
                    paint=fill_paint,
                )
            )
        canvas.update()

    def is_float(value) -> bool:
        try:
            float(value)
            return True
        except:
            return False

    gd = ft.GestureDetector(
        hover_interval=10,
        on_hover=on_hover,
        on_exit=on_exit,
    )

    canvas = cv.Canvas(
        [
            cv.Rect(0,0,canvasWidth,canvasHeight,10,stroke_paint),
            cv.Line(canvasWidth*0.5,0,canvasWidth*0.5,canvasHeight,line_paint),
            cv.Line(0,canvasHeight*0.5,canvasWidth,canvasHeight*0.5,line_paint),
        ],
        width=canvasWidth,
        height=canvasHeight,
        content=gd,
    )

    pos = ft.Text(
        "-",
        size=30,
    )

    view1: ft.View = ft.View(
        "/",
         [
            ft.Text(),
            ft.ElevatedButton(
                "Go to canvas",
                on_click=lambda _: page.go("/canvas")),
        ]
    )

    view2: ft.View = ft.View(
        "/canvas", 
        [
            ft.Row(
                controls=[
                    canvas,
                    ft.Column(
                        controls=[
                            ft.Container(
                                bgcolor=ft.colors.BLUE_100,
                                alignment=ft.alignment.top_center,
                                width=200,
                                content=pos
                            ),
                            ft.TextField(
                                multiline=True,
                                max_lines=10,
                                on_change=create_circle,
                            ),
                            ft.ElevatedButton(
                                "Go to Home",
                                on_click=lambda _: page.go("/")
                            ),
                        ]
                    ),
                ]
            ),
        ]
    )

    def route_change(route):
        page.views.clear()
        page.views.append(view1)
        if page.route == "/canvas":
            # to canvas
            page.views.append(view2)
        else:
            # to home
            view1.controls[0].value = view2.controls[0].controls[1].controls[1].value
        page.update()

    def view_pop(view):
        page.views.pop()
        top_view = page.views[-1]
        page.go(top_view.route)


    page.on_route_change = route_change
    page.on_view_pop = view_pop

    page.theme_mode = ft.ThemeMode.LIGHT
    page.title = "Routing Test"
    page.views.clear()
    page.go(page.route)

if __name__ == "__main__":
    ft.app(target=main)

起動時はこんな感じです。

ボタンの上にはft.Textが配置されていますが、文字が空の為見ええません。

ボタンを押した際は、例のcanvasが表示されます。

適当に円を設定し、元のビューに戻ります。


canvas側の文字が反映されます。
異なるビューでのデータ受け渡しも出来ました。