Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions client/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ void main([List<String>? args]) async {
assetsDir = args[2];
debugPrint("Args contain a path assets directory: $assetsDir}");
}
} else if (!kDebugMode &&
(Platform.isWindows || Platform.isMacOS || Platform.isLinux)) {
} else if (!kDebugMode && isDesktopPlatform()) {
throw Exception(
'In desktop mode Flet app URL must be provided as a first argument.');
}
Expand Down
34 changes: 28 additions & 6 deletions packages/flet/lib/src/controls/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import '../utils/session_store_web.dart'
import '../utils/theme.dart';
import '../utils/time.dart';
import '../utils/user_fonts.dart';
import '../utils/web_interface.dart'
if (dart.library.io) "../utils/io_interface.dart";
import '../widgets/animated_transition_page.dart';
import '../widgets/loading_page.dart';
import '../widgets/page_context.dart';
Expand Down Expand Up @@ -59,6 +61,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
ServiceRegistry? _userServices;
bool? _prevOnKeyboardEvent;
bool _keyboardHandlerSubscribed = false;
bool? _prevFullScreen;
String? _prevViewRoutes;

final Map<int, MultiView> _multiViews = <int, MultiView>{};
Expand Down Expand Up @@ -95,6 +98,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {

_attachKeyboardListenerIfNeeded();
widget.control.addInvokeMethodListener(_invokeMethod);
_applyFullScreenFromControl(widget.control);
}

@override
Expand Down Expand Up @@ -131,6 +135,7 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {

_attachKeyboardListenerIfNeeded();
_loadFontsIfNeeded(FletBackend.of(context));
_applyFullScreenFromControl(widget.control);
}

@override
Expand All @@ -151,6 +156,25 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
super.dispose();
}

/// Applies full screen mode to the app.
Future<void> _applyFullScreenFromControl(Control control) async {
final fullScreen = control.getBool("full_screen", false)!;
if (_prevFullScreen != fullScreen) {
_prevFullScreen = fullScreen;
if (isDesktopPlatform() || isWebPlatform()) {
await setWindowFullScreen(fullScreen);
} else if (isMobilePlatform()) {
if (fullScreen) {
await SystemChrome.setEnabledSystemUIMode(
SystemUiMode.immersiveSticky);
} else {
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: SystemUiOverlay.values);
}
}
}
}

Future<dynamic> _invokeMethod(String name, dynamic args) async {
debugPrint("Page.$name($args)");

Expand Down Expand Up @@ -197,7 +221,6 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
await SystemChrome.setPreferredOrientations(orientations);
}
break;

default:
throw Exception("Unknown Page method: $name");
}
Expand Down Expand Up @@ -375,11 +398,10 @@ class _PageControlState extends State<PageControl> with WidgetsBindingObserver {
}

Widget _buildApp(Control control, Widget? home) {
var platform = TargetPlatform.values.firstWhere(
(a) =>
a.name.toLowerCase() ==
control.getString("platform", "")!.toLowerCase(),
orElse: () => defaultTargetPlatform);
_applyFullScreenFromControl(control);

var platform =
control.getTargetPlatform("platform", defaultTargetPlatform)!;

var widgetsDesign = control.adaptive == true &&
(platform == TargetPlatform.iOS || platform == TargetPlatform.macOS)
Expand Down
44 changes: 17 additions & 27 deletions packages/flet/lib/src/utils/form_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,22 @@ FormFieldInputBorder? parseFormFieldInputBorder(String? value,

TextInputType? parseTextInputType(String? value,
[TextInputType? defaultValue]) {
switch (value?.toLowerCase()) {
case "datetime":
return TextInputType.datetime;
case "email":
return TextInputType.emailAddress;
case "multiline":
return TextInputType.multiline;
case "name":
return TextInputType.name;
case "none":
return TextInputType.none;
case "number":
return TextInputType.number;
case "phone":
return TextInputType.phone;
case "streetaddress":
return TextInputType.streetAddress;
case "text":
return TextInputType.text;
case "url":
return TextInputType.url;
case "visiblepassword":
return TextInputType.visiblePassword;
default:
return defaultValue;
}
const typeMap = {
"datetime": TextInputType.datetime,
"email": TextInputType.emailAddress,
"multiline": TextInputType.multiline,
"name": TextInputType.name,
"none": TextInputType.none,
"number": TextInputType.number,
"phone": TextInputType.phone,
"streetaddress": TextInputType.streetAddress,
"text": TextInputType.text,
"url": TextInputType.url,
"visiblepassword": TextInputType.visiblePassword,
"websearch": TextInputType.webSearch,
"twitter": TextInputType.twitter,
};
return typeMap[value?.toLowerCase()] ?? defaultValue;
}

InputDecoration buildInputDecoration(
Expand Down Expand Up @@ -86,7 +76,7 @@ InputDecoration buildInputDecoration(
?.replaceAll("{value_length}", valueLength.toString())
.replaceAll("{max_length}", maxLength?.toString() ?? "None")
.replaceAll("{symbols_left}",
"${maxLength == null ? 'None' : (maxLength - (valueLength ?? 0))}");
"${maxLength == null ? 'None' : (maxLength - (valueLength ?? 0))}");
}

// error
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import 'dart:typed_data';
import 'dart:io';
import 'dart:typed_data';

import 'desktop.dart' as desktop show setWindowFullScreen;

Future<ByteData> fetchFontFromFile(String path) async {
File file = File(path);
Uint8List bytes = await file.readAsBytes();
return ByteData.view(bytes.buffer);
}

Future setWindowFullScreen(bool fullScreen) async {
await desktop.setWindowFullScreen(fullScreen);
}
2 changes: 1 addition & 1 deletion packages/flet/lib/src/utils/user_fonts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;

import '../models/control.dart';
import 'user_fonts_web.dart' if (dart.library.io) "user_fonts_io.dart";
import 'web_interface.dart' if (dart.library.io) "io_interface.dart";

class UserFonts {
static Map<String, FontLoader> fontLoaders = {};
Expand Down
5 changes: 0 additions & 5 deletions packages/flet/lib/src/utils/user_fonts_web.dart

This file was deleted.

15 changes: 15 additions & 0 deletions packages/flet/lib/src/utils/web_interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'dart:typed_data';

import 'package:web/web.dart' as web show window;

Future<ByteData> fetchFontFromFile(String path) async {
throw UnimplementedError();
}

Future setWindowFullScreen(bool fullScreen) async {
if (fullScreen) {
web.window.document.documentElement?.requestFullscreen();
} else {
web.window.document.exitFullscreen();
}
}
22 changes: 22 additions & 0 deletions sdk/python/examples/controls/page/fullscreen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import flet as ft


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

def handle_fullscreen_change(e: ft.Event[ft.Switch]):
page.full_screen = e.control.value

page.add(
ft.SafeArea(
ft.Switch(
value=page.full_screen,
label="Toggle Fullscreen",
on_change=handle_fullscreen_change,
),
)
)


ft.run(main)
15 changes: 15 additions & 0 deletions sdk/python/packages/flet/docs/controls/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ Shows how to lock your app to specific device orientations
--8<-- "{{ examples }}/app_exit_confirm_dialog.py"
```

### Toggle Fullscreen

This example demonstrates how to toggle fullscreen mode in a Flet application.

/// admonition
type: note
[`Page.full_screen`][flet.] is cross-platform (mobile, desktop and web), whereas
[`Page.window.full_screen`][flet.Window.full_screen] is desktop only.
///


```python
--8<-- "{{ examples }}/fullscreen.py"
```

### Hidden app window on startup

```python
Expand Down
Loading
Loading