Skip to content

Commit 02e09cd

Browse files
committed
Refactor icon generation and usage
Replaces shell scripts with a unified Python script using Jinja2 templates for icon generation. Adds template files and generated icon lists for both Material and Cupertino icons in Dart and Python. Updates Flet core extension to use icon indices instead of codepoints, simplifying icon lookup and usage. Removes legacy generated icon files and updates build scripts to remove '--no-tree-shake-icons' flag.
1 parent 6012733 commit 02e09cd

File tree

18 files changed

+20435
-9993
lines changed

18 files changed

+20435
-9993
lines changed

.appveyor.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ for:
213213

214214
- cd client
215215
- set RELEASE_DIR=build\windows\x64\runner\Release
216-
- flutter build windows --no-tree-shake-icons --build-name=%APPVEYOR_BUILD_VERSION%
216+
- flutter build windows --build-name=%APPVEYOR_BUILD_VERSION%
217217

218218
- copy "%WINDIR%\system32\msvcp140.dll" %RELEASE_DIR%
219219
- copy "%WINDIR%\system32\vcruntime140.dll" %RELEASE_DIR%
@@ -277,7 +277,7 @@ for:
277277
build_script:
278278
# Flutter macOS client
279279
- pushd client
280-
- flutter build macos --no-tree-shake-icons --build-name=$APPVEYOR_BUILD_VERSION
280+
- flutter build macos --build-name=$APPVEYOR_BUILD_VERSION
281281
- tar -czvf flet-macos.tar.gz -C build/macos/Build/Products/Release Flet.app
282282
- mkdir -p $flet_sdk_root/packages/flet-desktop/src/flet_desktop/app
283283
- cp flet-macos.tar.gz $flet_sdk_root/packages/flet-desktop/src/flet_desktop/app
@@ -357,7 +357,7 @@ for:
357357
patch_flet_desktop_package_name "flet-desktop-light"
358358
artifact_suffix="-light"
359359
fi
360-
- flutter build linux --no-tree-shake-icons --build-name=$APPVEYOR_BUILD_VERSION
360+
- flutter build linux --build-name=$APPVEYOR_BUILD_VERSION
361361
- mv build/linux/$build_arch/release/bundle build/linux/$build_arch/release/flet
362362
- tar -czvf flet-linux$artifact_suffix-$ARCH.tar.gz -C build/linux/$build_arch/release flet
363363
- mkdir -p $flet_sdk_root/packages/flet-desktop/src/flet_desktop/app
@@ -412,7 +412,7 @@ for:
412412
build_script:
413413
# Flutter Web client
414414
- pushd client
415-
- flutter build web --wasm --no-tree-shake-icons
415+
- flutter build web --wasm
416416
- cp -R build/web $flet_sdk_root/packages/flet-web/src/flet_web
417417
# fix on mobile Safari: https://github.com/flutter/flutter/issues/145111#issuecomment-2714599139
418418
- ls "$(dirname "$(command -v flutter)")/cache/flutter_web_sdk/flutter_js"

.ruff.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exclude = ["ci/templates"]

ci/generate_cupertino_icons.sh

Lines changed: 0 additions & 6 deletions
This file was deleted.

ci/generate_icons.py

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1+
# /// script
2+
# dependencies = [
3+
# "requests",
4+
# "Jinja2",
5+
# ]
6+
# ///
7+
18
import re
2-
import sys
9+
from pathlib import Path
310

411
import requests
12+
from jinja2 import Environment, FileSystemLoader
513

614
# Regex for parsing icon definitions (handles multi-line IconData)
7-
ICON_ENTRY_PATTERN = re.compile(
8-
r"""
9-
^\s*///.*?"(?P<name>.+?)"(?:\s+\((?P<style>\w+)\))?.*?\n # doc line
10-
^\s*static\s+const\s+IconData\s+(?P<var_name>\w+)\s*=\s*IconData\s*\(\s* # var line
11-
0x(?P<codepoint>[0-9a-fA-F]+), # codepoint
12-
""",
13-
re.MULTILINE | re.VERBOSE,
15+
ICON_VAR_PATTERN = re.compile(
16+
r"""^\s*static const IconData\s+(\w+)\s*=""", re.MULTILINE
1417
)
1518

19+
file_loader = FileSystemLoader(Path(__file__).parent / "templates")
20+
templates = Environment(loader=file_loader)
1621

17-
def normalize_enum_name(var_name: str) -> str:
18-
return var_name.upper()
22+
# def normalize_enum_name(var_name: str) -> str:
23+
# return var_name.upper()
1924

2025

2126
def download_dart_file(url: str) -> str:
@@ -26,45 +31,63 @@ def download_dart_file(url: str) -> str:
2631

2732

2833
def parse_dart_icons(dart_content: str, set_id: int):
34+
# Extract and sort icon names alphabetically
35+
icon_names = sorted(ICON_VAR_PATTERN.findall(dart_content))
36+
2937
icons = []
30-
for match in ICON_ENTRY_PATTERN.finditer(dart_content):
31-
var_name = match.group("var_name")
32-
codepoint = int(match.group("codepoint"), 16)
33-
packed_value = (set_id << 24) | codepoint
34-
icons.append((normalize_enum_name(var_name), hex(packed_value)))
35-
print(f"🔍 Found {len(icons)} icons for set ID {set_id}.")
38+
for i, icon_name in enumerate(icon_names):
39+
packed_value = (set_id << 16) | i
40+
icons.append((icon_name, packed_value))
41+
42+
print(f"🔍 Found {len(icons)} icons for set ID {set_id} (sorted).")
3643
return icons
3744

3845

39-
def generate_python_enum(icons, output_file: str, class_name: str):
40-
with open(output_file, "w", encoding="utf-8") as f:
41-
f.write(f"class {class_name}(IconData):\n")
42-
for name, code in icons:
43-
f.write(f" {name} = {code}\n")
44-
print(f"✅ Enum written to {output_file}")
46+
def generate_file(icons, template_name, output_file: str):
47+
template = templates.get_template(template_name)
48+
with open(
49+
Path(__file__).parent.joinpath(output_file).resolve(), "w", encoding="utf-8"
50+
) as f:
51+
f.write(template.render(icons=icons))
52+
print(f"✅ File written to {output_file}")
4553

4654

4755
def main():
48-
if len(sys.argv) < 5:
49-
print(
50-
"Usage: python generate_icons.py <https://path/to/Icons.dart> <output-file> <class-name> <set-id>"
51-
)
52-
sys.exit(1)
53-
54-
url = sys.argv[1]
55-
output_file = sys.argv[2]
56-
class_name = sys.argv[3]
57-
set_id = int(sys.argv[4])
58-
56+
# material icons
57+
url = "https://raw.githubusercontent.com/flutter/flutter/refs/heads/stable/packages/flutter/lib/src/material/icons.dart"
58+
set_id = 1
5959
dart_content = download_dart_file(url)
60-
6160
icons = parse_dart_icons(dart_content, set_id)
6261

63-
if not icons:
64-
print("⚠️ No icons found. Please check the format.")
65-
sys.exit(1)
62+
generate_file(
63+
icons,
64+
"material_icons.dart",
65+
"../packages/flet/lib/src/utils/material_icons.dart",
66+
)
67+
68+
generate_file(
69+
icons,
70+
"material_icons.py",
71+
"../sdk/python/packages/flet/src/flet/controls/material/icons.py",
72+
)
73+
74+
# cupertino icons
75+
url = "https://raw.githubusercontent.com/flutter/flutter/refs/heads/stable/packages/flutter/lib/src/cupertino/icons.dart"
76+
set_id = 2
77+
dart_content = download_dart_file(url)
78+
icons = parse_dart_icons(dart_content, set_id)
6679

67-
generate_python_enum(icons, output_file, class_name)
80+
generate_file(
81+
icons,
82+
"cupertino_icons.dart",
83+
"../packages/flet/lib/src/utils/cupertino_icons.dart",
84+
)
85+
86+
generate_file(
87+
icons,
88+
"cupertino_icons.py",
89+
"../sdk/python/packages/flet/src/flet/controls/cupertino/cupertino_icons.py",
90+
)
6891

6992

7093
if __name__ == "__main__":

ci/generate_material_icons.sh

Lines changed: 0 additions & 6 deletions
This file was deleted.

ci/templates/cupertino_icons.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'package:flutter/cupertino.dart';
2+
3+
List<IconData> cupertinoIcons = [
4+
{% for name, code in icons -%}
5+
CupertinoIcons.{{ name }},
6+
{% endfor -%}
7+
];

ci/templates/cupertino_icons.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Flet Cupertino Icons
3+
4+
To generate/update this file run from the root of the repository:
5+
6+
```
7+
uv run ci/generate_icons.py
8+
```
9+
"""
10+
11+
from flet.controls.icon_data import IconData
12+
13+
__all__ = ["CupertinoIcons"]
14+
15+
16+
class CupertinoIcons(IconData):
17+
{% for name, code in icons -%}
18+
{{ name.upper() }} = {{ "0x%X" % code }}
19+
{% endfor -%}

ci/templates/material_icons.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'package:flutter/material.dart';
2+
3+
List<IconData> materialIcons = [
4+
{% for name, code in icons -%}
5+
Icons.{{ name }},
6+
{% endfor -%}
7+
];

ci/templates/material_icons.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Flet Material Icons
3+
4+
To generate/update this file run from the root of the repository:
5+
6+
```
7+
uv run ci/generate_icons.py
8+
```
9+
"""
10+
11+
from flet.controls.icon_data import IconData
12+
13+
__all__ = ["Icons"]
14+
15+
16+
class Icons(IconData):
17+
{% for name, code in icons -%}
18+
{{ name.upper() }} = {{ "0x%X" % code }}
19+
{% endfor -%}

packages/flet/lib/flet.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ library flet;
22

33
export 'dart:io';
44

5+
export 'package:flutter/cupertino.dart' show CupertinoIcons;
6+
export 'package:flutter/material.dart' show Icons;
7+
58
export 'src/controls/base_controls.dart';
69
export 'src/extensions/control.dart';
710
export 'src/flet_app.dart';

0 commit comments

Comments
 (0)