Dart and Flutter upgrade; More things done
This commit is contained in:
parent
9b09f4797f
commit
7eeba12968
10 changed files with 338 additions and 89 deletions
27
.metadata
27
.metadata
|
|
@ -4,8 +4,8 @@
|
||||||
# This file should be version controlled.
|
# This file should be version controlled.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
revision: e7ab3b07f88024b8f7e30a1e533134700fae1fb9
|
||||||
channel: stable
|
channel: master
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
|
||||||
|
|
@ -13,26 +13,11 @@ project_type: app
|
||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
create_revision: e7ab3b07f88024b8f7e30a1e533134700fae1fb9
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
base_revision: e7ab3b07f88024b8f7e30a1e533134700fae1fb9
|
||||||
- platform: android
|
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
- platform: ios
|
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
- platform: linux
|
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
- platform: macos
|
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
- platform: web
|
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
|
||||||
- platform: windows
|
- platform: windows
|
||||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
create_revision: e7ab3b07f88024b8f7e30a1e533134700fae1fb9
|
||||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
base_revision: e7ab3b07f88024b8f7e30a1e533134700fae1fb9
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|
|
||||||
200
lib/main.dart
200
lib/main.dart
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:socket_io_client/socket_io_client.dart' as io;
|
import 'package:socket_io_client/socket_io_client.dart' as io;
|
||||||
|
|
@ -174,27 +176,209 @@ class HomePage extends StatefulWidget {
|
||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
late io.Socket socket;
|
late io.Socket socket;
|
||||||
|
late AuthData authData = Get.find();
|
||||||
|
|
||||||
|
var guessersPlayers = <String>[].obs;
|
||||||
|
var suggestersPlayers = <String>[].obs;
|
||||||
|
var incommingRequests = <String>[].obs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
socket = Get.find();
|
socket = Get.find();
|
||||||
|
|
||||||
|
socket.on("hello", (idky) {
|
||||||
|
socket.dispose();
|
||||||
|
Get.offAllNamed("/auth");
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("update", (update) {
|
||||||
|
bool ok = update[0];
|
||||||
|
if (ok) {
|
||||||
|
var data = update[1];
|
||||||
|
guessersPlayers.value = (data["guessers"] as List<dynamic>? ?? [])
|
||||||
|
.map((e) => e.toString())
|
||||||
|
.toList(growable: false);
|
||||||
|
suggestersPlayers.value = (data["suggesters"] as List<dynamic>? ?? [])
|
||||||
|
.map((e) => e.toString())
|
||||||
|
.toList(growable: false);
|
||||||
|
} else {
|
||||||
|
Get.snackbar("Error", "Update failed with message: ${update[1]}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("updateNeeded", (data) {
|
||||||
|
socket.emit("getUpdate");
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("gameRequest", (requestFrom) {
|
||||||
|
setState(() {
|
||||||
|
incommingRequests.add(requestFrom);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("getUpdate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final shortestSide = MediaQuery.of(context).size.shortestSide;
|
||||||
|
final useMobileLayout = shortestSide < 600;
|
||||||
|
final elements = [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: _buildPlayerList(
|
||||||
|
guessersPlayers,
|
||||||
|
"Guessers",
|
||||||
|
"guessers",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: _buildPlayerList(
|
||||||
|
suggestersPlayers,
|
||||||
|
"Suggesters",
|
||||||
|
"suggesters",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text("HUACU"),
|
title: const Text("HUACU"),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: useMobileLayout
|
||||||
child: Column(
|
? Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
mainAxisSize: MainAxisSize.max,
|
||||||
Text("Hello, ${Get.find<AuthData>().login}"),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
],
|
children: elements,
|
||||||
),
|
)
|
||||||
),
|
: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: elements,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildPlayerList(RxList<String> players, String title, String team) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(title),
|
||||||
|
Obx(() => Text("Count: ${players.length}")),
|
||||||
|
Expanded(
|
||||||
|
child: ObxValue(
|
||||||
|
(data) => ListView.builder(
|
||||||
|
itemCount: data.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(
|
||||||
|
"${data[index]} ${authData.login == data[index] ? "(you)" : ""}"
|
||||||
|
.trim(),
|
||||||
|
),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (incommingRequests.contains(data[index]))
|
||||||
|
InkResponse(
|
||||||
|
onTap: () =>
|
||||||
|
_handleRequestResponseAction(data[index], true),
|
||||||
|
child: const Icon(Icons.check),
|
||||||
|
),
|
||||||
|
if (incommingRequests.contains(data[index]))
|
||||||
|
InkResponse(
|
||||||
|
onTap: () => _handleRequestResponseAction(
|
||||||
|
data[index], false),
|
||||||
|
child: const Icon(Icons.close),
|
||||||
|
),
|
||||||
|
if (authData.login != data[index])
|
||||||
|
InkResponse(
|
||||||
|
onTap: () => _handleSendRequestClick(data[index]),
|
||||||
|
child: const Icon(Icons.connect_without_contact),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
players,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ObxValue(
|
||||||
|
(data) => players.contains(authData.login)
|
||||||
|
? ElevatedButton(
|
||||||
|
onPressed: () => _handleLeaveClick(team),
|
||||||
|
child: const Text("Leave"),
|
||||||
|
)
|
||||||
|
: ElevatedButton(
|
||||||
|
onPressed: () => _handleJoinClick(team),
|
||||||
|
child: const Text("Join"),
|
||||||
|
),
|
||||||
|
guessersPlayers,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _joinResponseHandler(dynamic data) {
|
||||||
|
bool ok = data[0];
|
||||||
|
if (!ok) {
|
||||||
|
int status = data[1];
|
||||||
|
Get.snackbar("Error", "Join failed with status $status");
|
||||||
|
}
|
||||||
|
socket.off("joinResponse", _joinResponseHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleJoinClick(String side) {
|
||||||
|
socket.on("joinResponse", _joinResponseHandler);
|
||||||
|
socket.emit("join", side);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _leaveResponseHandler(dynamic data) {
|
||||||
|
bool ok = data[0];
|
||||||
|
if (!ok) {
|
||||||
|
int status = data[1];
|
||||||
|
Get.snackbar("Error", "Leaving failed with status $status");
|
||||||
|
}
|
||||||
|
socket.off("leaveResponse", _leaveResponseHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleLeaveClick(String side) {
|
||||||
|
socket.on("leaveResponse", _leaveResponseHandler);
|
||||||
|
socket.emit("leave", side);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sendRequestResponseHandler(dynamic data) {
|
||||||
|
bool ok = data[0];
|
||||||
|
if (ok) {
|
||||||
|
Get.snackbar("Success", "Request sent");
|
||||||
|
} else {
|
||||||
|
Get.snackbar("Error", "Request failed");
|
||||||
|
}
|
||||||
|
socket.off("sendRequestResponse", _leaveResponseHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleSendRequestClick(String player) {
|
||||||
|
socket.on("sendRequestResponse", _sendRequestResponseHandler);
|
||||||
|
socket.emit("sendRequest", player);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleRequestResponseAction(String data, bool bool) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
107
pubspec.lock
107
pubspec.lock
|
|
@ -5,49 +5,56 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.9.0"
|
version: "2.10.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.3.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.17.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.dartlang.org"
|
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
flutter:
|
flutter:
|
||||||
|
|
@ -59,7 +66,8 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
@ -71,58 +79,66 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: get
|
name: get
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.6.5"
|
version: "4.6.5"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.5"
|
version: "0.6.7"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.12"
|
version: "0.12.14"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
url: "https://pub.dartlang.org"
|
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.5"
|
version: "0.2.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "12307e7f0605ce3da64cf0db90e5fcab0869f3ca03f76be6bb2991ce0a55e82b"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.9.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.2"
|
version: "1.8.3"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -132,64 +148,73 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: socket_io_client
|
name: socket_io_client
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a9c589d3fe2658506be38ddb36f23348daab73a00ff1645533669d07a5111cfc
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
socket_io_common:
|
socket_io_common:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: socket_io_common
|
name: socket_io_common
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5a218a784df4d1927ae713e17af619caa736cb2ebac287c59e4e24228b22da29"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.9.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.2.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.1"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6182294da5abf431177fccc1ee02401f6df30f766bc6130a0852c6b6d7ee6b2d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.12"
|
version: "0.4.18"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.18.5 <3.0.0"
|
dart: ">=2.19.0 <4.0.0"
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ add_subdirectory(${FLUTTER_MANAGED_DIR})
|
||||||
# Application build; see runner/CMakeLists.txt.
|
# Application build; see runner/CMakeLists.txt.
|
||||||
add_subdirectory("runner")
|
add_subdirectory("runner")
|
||||||
|
|
||||||
|
|
||||||
# Generated plugin build rules, which manage building the plugins and adding
|
# Generated plugin build rules, which manage building the plugins and adding
|
||||||
# them to the application.
|
# them to the application.
|
||||||
include(flutter/generated_plugins.cmake)
|
include(flutter/generated_plugins.cmake)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
||||||
# Add dependency libraries and include directories. Add any application-specific
|
# Add dependency libraries and include directories. Add any application-specific
|
||||||
# dependencies here.
|
# dependencies here.
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
||||||
|
|
||||||
# Run the Flutter tool portions of the build. This must not be removed.
|
# Run the Flutter tool portions of the build. This must not be removed.
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,11 @@ bool FlutterWindow::OnCreate() {
|
||||||
}
|
}
|
||||||
RegisterPlugins(flutter_controller_->engine());
|
RegisterPlugins(flutter_controller_->engine());
|
||||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
||||||
|
|
||||||
|
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
||||||
|
this->Show();
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||||
FlutterWindow window(project);
|
FlutterWindow window(project);
|
||||||
Win32Window::Point origin(10, 10);
|
Win32Window::Point origin(10, 10);
|
||||||
Win32Window::Size size(1280, 720);
|
Win32Window::Size size(1280, 720);
|
||||||
if (!window.CreateAndShow(L"huacu_mobile", origin, size)) {
|
if (!window.Create(L"huacu_mobile", origin, size)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
window.SetQuitOnClose(true);
|
window.SetQuitOnClose(true);
|
||||||
|
|
|
||||||
|
|
@ -47,16 +47,17 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) {
|
||||||
}
|
}
|
||||||
int target_length = ::WideCharToMultiByte(
|
int target_length = ::WideCharToMultiByte(
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
||||||
-1, nullptr, 0, nullptr, nullptr);
|
-1, nullptr, 0, nullptr, nullptr)
|
||||||
|
-1; // remove the trailing null character
|
||||||
|
int input_length = (int)wcslen(utf16_string);
|
||||||
std::string utf8_string;
|
std::string utf8_string;
|
||||||
if (target_length == 0 || target_length > utf8_string.max_size()) {
|
if (target_length <= 0 || target_length > utf8_string.max_size()) {
|
||||||
return utf8_string;
|
return utf8_string;
|
||||||
}
|
}
|
||||||
utf8_string.resize(target_length);
|
utf8_string.resize(target_length);
|
||||||
int converted_length = ::WideCharToMultiByte(
|
int converted_length = ::WideCharToMultiByte(
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
||||||
-1, utf8_string.data(),
|
input_length, utf8_string.data(), target_length, nullptr, nullptr);
|
||||||
target_length, nullptr, nullptr);
|
|
||||||
if (converted_length == 0) {
|
if (converted_length == 0) {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,31 @@
|
||||||
#include "win32_window.h"
|
#include "win32_window.h"
|
||||||
|
|
||||||
|
#include <dwmapi.h>
|
||||||
#include <flutter_windows.h>
|
#include <flutter_windows.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
/// Window attribute that enables dark mode window decorations.
|
||||||
|
///
|
||||||
|
/// Redefined in case the developer's machine has a Windows SDK older than
|
||||||
|
/// version 10.0.22000.0.
|
||||||
|
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
|
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||||
|
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
||||||
|
|
||||||
|
/// Registry key for app theme preference.
|
||||||
|
///
|
||||||
|
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
|
||||||
|
/// value indicates apps should use light mode.
|
||||||
|
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
|
||||||
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||||
|
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
|
||||||
|
|
||||||
// The number of Win32Window objects that currently exist.
|
// The number of Win32Window objects that currently exist.
|
||||||
static int g_active_window_count = 0;
|
static int g_active_window_count = 0;
|
||||||
|
|
||||||
|
|
@ -31,8 +49,8 @@ void EnableFullDpiSupportIfAvailable(HWND hwnd) {
|
||||||
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
||||||
if (enable_non_client_dpi_scaling != nullptr) {
|
if (enable_non_client_dpi_scaling != nullptr) {
|
||||||
enable_non_client_dpi_scaling(hwnd);
|
enable_non_client_dpi_scaling(hwnd);
|
||||||
FreeLibrary(user32_module);
|
|
||||||
}
|
}
|
||||||
|
FreeLibrary(user32_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
@ -42,7 +60,7 @@ class WindowClassRegistrar {
|
||||||
public:
|
public:
|
||||||
~WindowClassRegistrar() = default;
|
~WindowClassRegistrar() = default;
|
||||||
|
|
||||||
// Returns the singleton registar instance.
|
// Returns the singleton registrar instance.
|
||||||
static WindowClassRegistrar* GetInstance() {
|
static WindowClassRegistrar* GetInstance() {
|
||||||
if (!instance_) {
|
if (!instance_) {
|
||||||
instance_ = new WindowClassRegistrar();
|
instance_ = new WindowClassRegistrar();
|
||||||
|
|
@ -102,9 +120,9 @@ Win32Window::~Win32Window() {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Win32Window::CreateAndShow(const std::wstring& title,
|
bool Win32Window::Create(const std::wstring& title,
|
||||||
const Point& origin,
|
const Point& origin,
|
||||||
const Size& size) {
|
const Size& size) {
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
const wchar_t* window_class =
|
const wchar_t* window_class =
|
||||||
|
|
@ -117,7 +135,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
|
||||||
double scale_factor = dpi / 96.0;
|
double scale_factor = dpi / 96.0;
|
||||||
|
|
||||||
HWND window = CreateWindow(
|
HWND window = CreateWindow(
|
||||||
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||||
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
||||||
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
||||||
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
||||||
|
|
@ -126,9 +144,15 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateTheme(window);
|
||||||
|
|
||||||
return OnCreate();
|
return OnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Win32Window::Show() {
|
||||||
|
return ShowWindow(window_handle_, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
||||||
UINT const message,
|
UINT const message,
|
||||||
|
|
@ -188,6 +212,10 @@ Win32Window::MessageHandler(HWND hwnd,
|
||||||
SetFocus(child_content_);
|
SetFocus(child_content_);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case WM_DWMCOLORIZATIONCOLORCHANGED:
|
||||||
|
UpdateTheme(hwnd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(window_handle_, message, wparam, lparam);
|
return DefWindowProc(window_handle_, message, wparam, lparam);
|
||||||
|
|
@ -243,3 +271,18 @@ bool Win32Window::OnCreate() {
|
||||||
void Win32Window::OnDestroy() {
|
void Win32Window::OnDestroy() {
|
||||||
// No-op; provided for subclasses.
|
// No-op; provided for subclasses.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32Window::UpdateTheme(HWND const window) {
|
||||||
|
DWORD light_mode;
|
||||||
|
DWORD light_mode_size = sizeof(light_mode);
|
||||||
|
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
|
||||||
|
kGetPreferredBrightnessRegValue,
|
||||||
|
RRF_RT_REG_DWORD, nullptr, &light_mode,
|
||||||
|
&light_mode_size);
|
||||||
|
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
BOOL enable_dark_mode = light_mode == 0;
|
||||||
|
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&enable_dark_mode, sizeof(enable_dark_mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,16 @@ class Win32Window {
|
||||||
Win32Window();
|
Win32Window();
|
||||||
virtual ~Win32Window();
|
virtual ~Win32Window();
|
||||||
|
|
||||||
// Creates and shows a win32 window with |title| and position and size using
|
// Creates a win32 window with |title| that is positioned and sized using
|
||||||
// |origin| and |size|. New windows are created on the default monitor. Window
|
// |origin| and |size|. New windows are created on the default monitor. Window
|
||||||
// sizes are specified to the OS in physical pixels, hence to ensure a
|
// sizes are specified to the OS in physical pixels, hence to ensure a
|
||||||
// consistent size to will treat the width height passed in to this function
|
// consistent size this function will scale the inputted width and height as
|
||||||
// as logical pixels and scale to appropriate for the default monitor. Returns
|
// as appropriate for the default monitor. The window is invisible until
|
||||||
// true if the window was created successfully.
|
// |Show| is called. Returns true if the window was created successfully.
|
||||||
bool CreateAndShow(const std::wstring& title,
|
bool Create(const std::wstring& title, const Point& origin, const Size& size);
|
||||||
const Point& origin,
|
|
||||||
const Size& size);
|
// Show the current window. Returns true if the window was successfully shown.
|
||||||
|
bool Show();
|
||||||
|
|
||||||
// Release OS resources associated with window.
|
// Release OS resources associated with window.
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
@ -76,7 +77,7 @@ class Win32Window {
|
||||||
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
||||||
// is passed when the non-client area is being created and enables automatic
|
// is passed when the non-client area is being created and enables automatic
|
||||||
// non-client DPI scaling so that the non-client area automatically
|
// non-client DPI scaling so that the non-client area automatically
|
||||||
// responsponds to changes in DPI. All other messages are handled by
|
// responds to changes in DPI. All other messages are handled by
|
||||||
// MessageHandler.
|
// MessageHandler.
|
||||||
static LRESULT CALLBACK WndProc(HWND const window,
|
static LRESULT CALLBACK WndProc(HWND const window,
|
||||||
UINT const message,
|
UINT const message,
|
||||||
|
|
@ -86,6 +87,9 @@ class Win32Window {
|
||||||
// Retrieves a class instance pointer for |window|
|
// Retrieves a class instance pointer for |window|
|
||||||
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
||||||
|
|
||||||
|
// Update the window frame's theme to match the system theme.
|
||||||
|
static void UpdateTheme(HWND const window);
|
||||||
|
|
||||||
bool quit_on_close_ = false;
|
bool quit_on_close_ = false;
|
||||||
|
|
||||||
// window handle for top level window.
|
// window handle for top level window.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue