Skip to content

Conversation

@ndonkoHenri
Copy link
Contributor

@ndonkoHenri ndonkoHenri commented Nov 5, 2025

Fix #4642
Fix #5728

Example

import flet as ft


def main(page: ft.Page):
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    async def handle_zoom_in(e: ft.Event[ft.Button]):
        await i.zoom(1.2)

    async def handle_zoom_out(e: ft.Event[ft.Button]):
        await i.zoom(0.8)

    async def handle_pan(e: ft.Event[ft.Button]):
        await i.pan(dx=50, dy=50)

    async def handle_reset(e: ft.Event[ft.Button]):
        await i.reset()

    async def handle_reset_slow(e: ft.Event[ft.Button]):
        await i.reset(animation_duration=ft.Duration(seconds=2))

    async def handle_save_state(e: ft.Event[ft.Button]):
        await i.save_state()

    async def handle_restore_state(e: ft.Event[ft.Button]):
        await i.restore_state()

    page.add(
        i := ft.InteractiveViewer(
            min_scale=0.1,
            max_scale=5,
            boundary_margin=ft.Margin.all(20),
            content=ft.Image(src="https://picsum.photos/500/500"),
        ),
        ft.Row(
            wrap=True,
            controls=[
                ft.Button("Zoom In", on_click=handle_zoom_in),
                ft.Button("Zoom Out", on_click=handle_zoom_out),
                ft.Button("Pan", on_click=handle_pan),
                ft.Button("Save State", on_click=handle_save_state),
                ft.Button("Restore State", on_click=handle_restore_state),
                ft.Button("Reset (instant)", on_click=handle_reset),
                ft.Button("Reset (slow)", on_click=handle_reset_slow),
            ],
        ),
    )


ft.run(main)

Summary by Sourcery

Enable robust programmatic zooming, panning, resetting, and state management on InteractiveViewer while enforcing boundary and scale constraints and enrich the Python API with more descriptive properties and examples.

Bug Fixes:

  • Fix programmatic zoom, pan, and reset actions to correctly respect min/max scales and boundary margins

Enhancements:

  • Add matrix-based scaling and translation logic to enforce viewport boundaries in Dart code
  • Improve Python InteractiveViewer API documentation with detailed descriptions for properties like constrained, boundary_margin, clip_behavior, and scale_factor
  • Include a new example demonstrating programmatic transformations in InteractiveViewer

Documentation:

  • Augment interactive_viewer documentation with a programmatic transformations example
  • Update enum and class docstrings for clarity in the Python SDK

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 5, 2025

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 94380a8
Status: ✅  Deploy successful!
Preview URL: https://5fcdd191.flet-docs.pages.dev
Branch Preview URL: https://fix-interactive-viewer.flet-docs.pages.dev

View logs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances documentation across several Flet controls, particularly focusing on the InteractiveViewer control. The changes include improved docstrings with more detailed explanations, formatting improvements, and a new example demonstrating programmatic transformations.

  • Enhanced documentation for InteractiveViewer properties with expanded explanations and usage notes
  • Added documentation for enum values in ImageRepeat and improved formatting in VisualDensity and other types
  • Created a new example showcasing programmatic transformations in InteractiveViewer
  • Implemented boundary-aware transformation logic in the Dart implementation

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sdk/python/packages/flet/src/flet/controls/types.py Updated docstrings for UrlTarget, ClipBehavior, ImageRepeat, and VisualDensity enums with improved formatting and descriptions
sdk/python/packages/flet/src/flet/controls/core/interactive_viewer.py Enhanced documentation for InteractiveViewer properties with detailed explanations, changed default value of boundary_margin to use factory function
sdk/python/packages/flet/docs/controls/interactiveviewer.md Added new section for programmatic transformations example
sdk/python/examples/controls/interactive_viewer/transformations.py New example file demonstrating zoom, pan, reset, and state save/restore operations
packages/flet/lib/src/controls/interactive_viewer.dart Implemented boundary-aware transformation logic with helper methods for scaling and panning operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +471 to +480
"""Repeat the image in both the x and y directions until the box is filled."""

REPEAT = "repeat"
"""Repeat the image in the x direction until the box is filled horizontally."""

REPEAT_X = "repeatX"
"""Repeat the image in the y direction until the box is filled vertically."""

REPEAT_Y = "repeatY"
"""Leave uncovered portions of the box transparent."""
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for ImageRepeat enum values is incorrect. The descriptions are mismatched with the enum values. NO_REPEAT should leave portions transparent (not repeat), REPEAT should repeat in both directions, REPEAT_X should repeat in x direction, and REPEAT_Y should repeat in y direction. The current mapping has these backwards.

Suggested change
"""Repeat the image in both the x and y directions until the box is filled."""
REPEAT = "repeat"
"""Repeat the image in the x direction until the box is filled horizontally."""
REPEAT_X = "repeatX"
"""Repeat the image in the y direction until the box is filled vertically."""
REPEAT_Y = "repeatY"
"""Leave uncovered portions of the box transparent."""
"""Do not repeat the image. Leave uncovered portions of the box transparent."""
REPEAT = "repeat"
"""Repeat the image in both the x and y directions until the box is filled."""
REPEAT_X = "repeatX"
"""Repeat the image in the x direction until the box is filled horizontally."""
REPEAT_Y = "repeatY"
"""Repeat the image in the y direction until the box is filled vertically."""

Copilot uses AI. Check for mistakes.
A margin for the visible boundaries of the [`content`][(c).].
Any transformation that results in the viewport being able to view outside
of the boundaries will be stopped at the boundary. The boundaries do not
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using a lambda in default_factory is unnecessarily verbose. Consider using default_factory=lambda: Margin.all(0) can be simplified to a partial function or a named function if this pattern is repeated, or use field(default_factory=Margin) if Margin.all(0) is the default constructor behavior.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: InteractiveViewer cannot shrink to the specified scale InteractiveViewer: zoom(...) ignores min_scale/max_scale, pan ignores control bounds

2 participants