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

NEW FEATURES: Drop Zone, Layout Builder, Window Background Blur #4441

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
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
5 changes: 5 additions & 0 deletions client/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:flet_permission_handler/flet_permission_handler.dart'
as flet_permission_handler;
import 'package:flet_rive/flet_rive.dart' as flet_rive;
import 'package:flet_ads/flet_ads.dart' as flet_ads;
import 'package:flet_dropzone/flet_dropzone.dart' as flet_dropzone;
// --FAT_CLIENT_START--
import 'package:flet_video/flet_video.dart' as flet_video;
// --FAT_CLIENT_END--
Expand All @@ -22,6 +23,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:url_strategy/url_strategy.dart';



const bool isProduction = bool.fromEnvironment('dart.vm.product');

void main([List<String>? args]) async {
Expand All @@ -47,6 +50,7 @@ void main([List<String>? args]) async {
flet_rive.ensureInitialized();
flet_webview.ensureInitialized();
flet_flashlight.ensureInitialized();
flet_dropzone.ensureInitialized();

var pageUrl = Uri.base.toString();
var assetsDir = "";
Expand Down Expand Up @@ -117,6 +121,7 @@ void main([List<String>? args]) async {
flet_rive.createControl,
flet_webview.createControl,
flet_flashlight.createControl,
flet_dropzone.createControl,
],
));
}
8 changes: 8 additions & 0 deletions client/linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "generated_plugin_registrant.h"

#include <audioplayers_linux/audioplayers_linux_plugin.h>
#include <desktop_drop/desktop_drop_plugin.h>
#include <flutter_acrylic/flutter_acrylic_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h>
#include <record_linux/record_linux_plugin.h>
Expand All @@ -20,6 +22,12 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
g_autoptr(FlPluginRegistrar) desktop_drop_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin");
desktop_drop_plugin_register_with_registrar(desktop_drop_registrar);
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
Expand Down
2 changes: 2 additions & 0 deletions client/linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_linux
desktop_drop
flutter_acrylic
media_kit_libs_linux
media_kit_video
record_linux
Expand Down
4 changes: 4 additions & 0 deletions client/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import FlutterMacOS
import Foundation

import audioplayers_darwin
import desktop_drop
import geolocator_apple
import macos_window_utils
import media_kit_libs_macos_video
import media_kit_video
import package_info_plus
Expand All @@ -24,7 +26,9 @@ import window_to_front

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
Expand Down
31 changes: 31 additions & 0 deletions client/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
desktop_drop:
dependency: transitive
description:
name: desktop_drop
sha256: "03abf1c0443afdd1d65cf8fa589a2f01c67a11da56bbb06f6ea1de79d5628e94"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
dio:
dependency: transitive
description:
Expand Down Expand Up @@ -268,6 +276,13 @@ packages:
path: "../packages/flet_audio_recorder"
relative: true
source: path
version: "0.25.1"
flet_dropzone:
dependency: "direct main"
description:
path: "../packages/flet_dropzone"
relative: true
source: path
version: "0.25.2"
flet_flashlight:
dependency: "direct main"
Expand Down Expand Up @@ -330,6 +345,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_acrylic:
dependency: transitive
description:
name: flutter_acrylic
sha256: b3996dbde5abf5823cc9ead4cf2e5267c3181f15585fe47ce4dc4472e7ec827a
url: "https://pub.dev"
source: hosted
version: "1.1.4"
flutter_driver:
dependency: transitive
description: flutter
Expand Down Expand Up @@ -632,6 +655,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.2"
macos_window_utils:
dependency: transitive
description:
name: macos_window_utils
sha256: "3534f2af024f2f24112ca28789a44e6750083f8c0065414546c6593ee48a5009"
url: "https://pub.dev"
source: hosted
version: "1.6.1"
markdown:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions client/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ dependencies:
path: ../packages/flet_webview
flet_flashlight:
path: ../packages/flet_flashlight
flet_dropzone:
path: ../packages/flet_dropzone

url_strategy: ^0.2.0
cupertino_icons: ^1.0.6
Expand Down
6 changes: 6 additions & 0 deletions client/windows/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "generated_plugin_registrant.h"

#include <audioplayers_windows/audioplayers_windows_plugin.h>
#include <desktop_drop/desktop_drop_plugin.h>
#include <flutter_acrylic/flutter_acrylic_plugin.h>
#include <geolocator_windows/geolocator_windows.h>
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
#include <media_kit_video/media_kit_video_plugin_c_api.h>
Expand All @@ -22,6 +24,10 @@
void RegisterPlugins(flutter::PluginRegistry* registry) {
AudioplayersWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
DesktopDropPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
FlutterAcrylicPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar(
Expand Down
2 changes: 2 additions & 0 deletions client/windows/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_windows
desktop_drop
flutter_acrylic
geolocator_windows
media_kit_libs_windows_video
media_kit_video
Expand Down
10 changes: 10 additions & 0 deletions packages/flet/lib/src/controls/create_control.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import 'time_picker.dart';
import 'transparent_pointer.dart';
import 'vertical_divider.dart';
import 'window_drag_area.dart';
import 'layout_builder.dart';

Widget createControl(Control? parent, String id, bool parentDisabled,
{Widget? nextChild, bool? parentAdaptive}) {
Expand Down Expand Up @@ -995,6 +996,15 @@ Widget createWidget(
parentDisabled: parentDisabled,
parentAdaptive: parentAdaptive,
backend: backend);
case "layoutbuilder":
return LayoutBuilderControl(
key: key,
parent: parent,
control: controlView.control,
children: controlView.children,
parentDisabled: parentDisabled,
parentAdaptive: parentAdaptive,
backend: backend);
default:
return ErrorControl("Unknown control: ${controlView.control.type}");
}
Expand Down
110 changes: 110 additions & 0 deletions packages/flet/lib/src/controls/layout_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import 'package:flutter/widgets.dart';
import '../models/control.dart';
import '../utils/alignment.dart';
import 'create_control.dart';
import '../flet_control_backend.dart';
import 'flet_store_mixin.dart';
import 'dart:convert';

class LayoutBuilderControl extends StatefulWidget {
final Control? parent;
final Control control;
final bool parentDisabled;
final bool? parentAdaptive;
final List<Control> children;
final FletControlBackend backend;

const LayoutBuilderControl({
super.key,
this.parent,
required this.control,
required this.children,
required this.parentDisabled,
required this.parentAdaptive,
required this.backend,
});

@override
State<LayoutBuilderControl> createState() => _LayoutBuilderControlState();
}

class _LayoutBuilderControlState extends State<LayoutBuilderControl>
with FletStoreMixin {
Size? _lastSize;
bool _hasInitialized = false;
bool _updateOnBuild = false;

@override
void initState() {
super.initState();
_updateOnBuild = widget.control.attrBool("update_on_build") ?? false;
}

void onChange(double width, double height) {
widget.backend.updateControlState(widget.control.id, {"layoutWidth": width.toString()});
widget.backend.updateControlState(widget.control.id, {"layoutHeight": height.toString()});

widget.backend.triggerControlEvent(
widget.control.id,
"layout_change",
jsonEncode({
"height": height,
"width": width,
}),
);

setState(() {});
}


@override
Widget build(BuildContext context) {
debugPrint("Stack with layout builder build: ${widget.control.id}");

bool disabled = widget.control.isDisabled || widget.parentDisabled;
bool? adaptive =
widget.control.attrBool("adaptive") ?? widget.parentAdaptive;

var contentCtrls =
widget.children.where((c) => c.name == "content" && c.isVisible);

Widget? child = contentCtrls.isNotEmpty
? createControl(widget.control, contentCtrls.first.id, disabled,
parentAdaptive: adaptive)
: null;

var layoyt_ = LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
WidgetsBinding.instance.addPostFrameCallback((_) {
final Size currentSize =
Size(constraints.maxWidth, constraints.maxHeight);
if (_hasInitialized == false && _updateOnBuild == true) {
onChange(constraints.maxWidth, constraints.maxHeight);
}
if (_hasInitialized == true && _lastSize != currentSize) {
onChange(constraints.maxWidth, constraints.maxHeight);
}
_hasInitialized = true;

_lastSize = currentSize;
debugPrint(
"LayoutBuilder dimensions: Width: ${constraints.maxWidth}, Height: ${constraints.maxHeight}");
});

return Container(
clipBehavior: Clip.none,
alignment: parseAlignment(widget.control, "alignment") ?? AlignmentDirectional.topStart,
child: child
);

},
);

return constrainedControl(
context,
layoyt_,
widget.parent,
widget.control,
);
}
}
Loading