feat:增加主题色
This commit is contained in:
@@ -3,8 +3,11 @@ import 'package:task_hub/pages/home_page.dart';
|
|||||||
import 'package:task_hub/pages/schedule_page.dart';
|
import 'package:task_hub/pages/schedule_page.dart';
|
||||||
import 'package:task_hub/pages/settings_page.dart';
|
import 'package:task_hub/pages/settings_page.dart';
|
||||||
import 'package:task_hub/pages/task_page.dart';
|
import 'package:task_hub/pages/task_page.dart';
|
||||||
|
import 'package:window_size/window_size.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
setWindowMinSize(const Size(800, 600));
|
||||||
runApp(const TaskHubApp());
|
runApp(const TaskHubApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,10 +17,11 @@ class TaskHubApp extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FluentApp(
|
return FluentApp(
|
||||||
title: 'TaskHub',
|
title: '拾光记',
|
||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
theme: FluentThemeData(
|
theme: FluentThemeData(
|
||||||
fontFamily: 'CustomFont',
|
fontFamily: 'CustomFont',
|
||||||
|
accentColor: Colors.purple
|
||||||
),
|
),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
home: const MainLayout(),
|
home: const MainLayout(),
|
||||||
@@ -38,49 +42,32 @@ class _MainLayoutState extends State<MainLayout> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return NavigationView(
|
return NavigationView(
|
||||||
titleBar: TitleBar(
|
titleBar: TitleBar(title: const Text('拾光记')),
|
||||||
icon: const FlutterLogo(),
|
|
||||||
title: const Text('TaskHub')
|
|
||||||
),
|
|
||||||
pane: NavigationPane(
|
pane: NavigationPane(
|
||||||
selected: _currentIndex,
|
selected: _currentIndex,
|
||||||
onChanged: (index) => setState(() => _currentIndex = index),
|
onChanged: (index) => setState(() => _currentIndex = index),
|
||||||
size: NavigationPaneSize(
|
size: NavigationPaneSize(openWidth: 150),
|
||||||
openWidth: 150
|
|
||||||
),
|
|
||||||
items: [
|
items: [
|
||||||
PaneItem(
|
PaneItem(
|
||||||
icon: const Icon(FluentIcons.home),
|
icon: const Icon(FluentIcons.home),
|
||||||
title: const Text('首页'),
|
title: const Text('首页'),
|
||||||
body: Container(
|
body: Container(color: Colors.white, child: const HomePage()),
|
||||||
color: Colors.white,
|
|
||||||
child: const HomePage(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
PaneItem(
|
PaneItem(
|
||||||
icon: const Icon(FluentIcons.check_list),
|
icon: const Icon(FluentIcons.check_list),
|
||||||
title: const Text('待办'),
|
title: const Text('待办'),
|
||||||
body: Container(
|
body: Container(color: Colors.white, child: const TaskPage()),
|
||||||
color: Colors.white,
|
|
||||||
child: const TaskPage(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
PaneItem(
|
PaneItem(
|
||||||
icon: const Icon(FluentIcons.calendar),
|
icon: const Icon(FluentIcons.calendar),
|
||||||
title: const Text('日程'),
|
title: const Text('日程'),
|
||||||
body: Container(
|
body: Container(color: Colors.white, child: const SchedulePage()),
|
||||||
color: Colors.white,
|
|
||||||
child: const SchedulePage(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
PaneItemSeparator(),
|
PaneItemSeparator(),
|
||||||
PaneItem(
|
PaneItem(
|
||||||
icon: const Icon(FluentIcons.settings),
|
icon: const Icon(FluentIcons.settings),
|
||||||
title: const Text('设置'),
|
title: const Text('设置'),
|
||||||
body: Container(
|
body: Container(color: Colors.white, child: const SettingsPage()),
|
||||||
color: Colors.white,
|
|
||||||
child: const SettingsPage(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
footerItems: [
|
footerItems: [
|
||||||
|
|||||||
@@ -20,12 +20,11 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
String _sortBy = 'created';
|
String _sortBy = 'created';
|
||||||
|
|
||||||
List<Task> get _filteredTasks {
|
List<Task> get _filteredTasks {
|
||||||
List<Task> tasks =
|
List<Task> tasks = _tasks.where((task) {
|
||||||
_tasks.where((task) {
|
if (_filter == 'active') return !task.isCompleted;
|
||||||
if (_filter == 'active') return !task.isCompleted;
|
if (_filter == 'completed') return task.isCompleted;
|
||||||
if (_filter == 'completed') return task.isCompleted;
|
return true;
|
||||||
return true;
|
}).toList();
|
||||||
}).toList();
|
|
||||||
|
|
||||||
tasks.sort((a, b) {
|
tasks.sort((a, b) {
|
||||||
switch (_sortBy) {
|
switch (_sortBy) {
|
||||||
@@ -48,32 +47,30 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
void _addTask() {
|
void _addTask() {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder: (context) => TaskDialog(
|
||||||
(context) => TaskDialog(
|
onSave: (task) {
|
||||||
onSave: (task) {
|
setState(() {
|
||||||
setState(() {
|
_tasks.add(task);
|
||||||
_tasks.add(task);
|
});
|
||||||
});
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _editTask(Task task) {
|
void _editTask(Task task) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder: (context) => TaskDialog(
|
||||||
(context) => TaskDialog(
|
task: task,
|
||||||
task: task,
|
onSave: (editedTask) {
|
||||||
onSave: (editedTask) {
|
setState(() {
|
||||||
setState(() {
|
final index = _tasks.indexWhere((t) => t.id == task.id);
|
||||||
final index = _tasks.indexWhere((t) => t.id == task.id);
|
if (index != -1) {
|
||||||
if (index != -1) {
|
_tasks[index] = editedTask;
|
||||||
_tasks[index] = editedTask;
|
}
|
||||||
}
|
});
|
||||||
});
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +134,7 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
final activeCount = _tasks.length - completedCount;
|
final activeCount = _tasks.length - completedCount;
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
backgroundColor: Colors.grey[20],
|
backgroundColor: FluentTheme.of(context).accentColor.lighter,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -157,10 +154,14 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
value,
|
value,
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(label, style: TextStyle(color: Colors.grey)),
|
Text(label, style: TextStyle(color: Colors.white)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -232,7 +233,11 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(FluentIcons.check_list, size: 64, color: Colors.blue),
|
Icon(
|
||||||
|
FluentIcons.check_list,
|
||||||
|
size: 64,
|
||||||
|
color: FluentTheme.of(context).accentColor,
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const Text(
|
const Text(
|
||||||
'还没有任务',
|
'还没有任务',
|
||||||
@@ -256,7 +261,7 @@ class _TaskPageState extends State<TaskPage> {
|
|||||||
task: task,
|
task: task,
|
||||||
onToggleComplete: () => _toggleTaskComplete(task),
|
onToggleComplete: () => _toggleTaskComplete(task),
|
||||||
onEdit: () => _editTask(task),
|
onEdit: () => _editTask(task),
|
||||||
onDelete: () => _deleteTask(task.id)
|
onDelete: () => _deleteTask(task.id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ class _ScheduleDialogState extends State<ScheduleDialog> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_titleController = TextEditingController(text: widget.schedule?.title ?? '');
|
_titleController = TextEditingController(
|
||||||
|
text: widget.schedule?.title ?? '',
|
||||||
|
);
|
||||||
_selectedStartTime = widget.schedule?.startTime;
|
_selectedStartTime = widget.schedule?.startTime;
|
||||||
_selectedEndTime = widget.schedule?.endTime;
|
_selectedEndTime = widget.schedule?.endTime;
|
||||||
_selectedScheduleDate = widget.schedule?.scheduleDate;
|
_selectedScheduleDate = widget.schedule?.scheduleDate;
|
||||||
@@ -35,34 +37,43 @@ class _ScheduleDialogState extends State<ScheduleDialog> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConfirmClick()async {
|
void onConfirmClick() async {
|
||||||
if (_selectedStartTime == null) {
|
if (_selectedStartTime == null) {
|
||||||
await displayInfoBar(context, builder: (context, close) {
|
await displayInfoBar(
|
||||||
return InfoBar(
|
context,
|
||||||
title: const Text('请选择开始时间'),
|
builder: (context, close) {
|
||||||
severity: InfoBarSeverity.error,
|
return InfoBar(
|
||||||
);
|
title: const Text('请选择开始时间'),
|
||||||
});
|
severity: InfoBarSeverity.error,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_selectedEndTime == null) {
|
if (_selectedEndTime == null) {
|
||||||
await displayInfoBar(context, builder: (context, close) {
|
await displayInfoBar(
|
||||||
return InfoBar(
|
context,
|
||||||
title: const Text('请选择结束时间'),
|
builder: (context, close) {
|
||||||
severity: InfoBarSeverity.error,
|
return InfoBar(
|
||||||
);
|
title: const Text('请选择结束时间'),
|
||||||
});
|
severity: InfoBarSeverity.error,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_selectedEndTime!.isAfter(_selectedStartTime!)) {
|
if (!_selectedEndTime!.isAfter(_selectedStartTime!)) {
|
||||||
await displayInfoBar(context, builder: (context, close) {
|
await displayInfoBar(
|
||||||
return InfoBar(
|
context,
|
||||||
title: const Text('结束时间必须晚于开始时间'),
|
builder: (context, close) {
|
||||||
severity: InfoBarSeverity.error,
|
return InfoBar(
|
||||||
);
|
title: const Text('结束时间必须晚于开始时间'),
|
||||||
});
|
severity: InfoBarSeverity.error,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +93,7 @@ class _ScheduleDialogState extends State<ScheduleDialog> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ContentDialog(
|
return ContentDialog(
|
||||||
title: Text(widget.schedule == null ? '添加日程' : '编辑日程'),
|
title: Center(child: Text(widget.schedule == null ? '添加日程' : '编辑日程')),
|
||||||
content: _buildForm(),
|
content: _buildForm(),
|
||||||
actions: [
|
actions: [
|
||||||
Button(
|
Button(
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class _TaskDialogState extends State<TaskDialog> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ContentDialog(
|
return ContentDialog(
|
||||||
title: Text(widget.task == null ? '添加任务' : '编辑任务'),
|
title: Center(child: Text(widget.task == null ? '添加任务' : '编辑任务')),
|
||||||
content: _buildForm(),
|
content: _buildForm(),
|
||||||
actions: [
|
actions: [
|
||||||
Button(
|
Button(
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ class TaskItem extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
_buildPriorityIndicator(task.priority),
|
_buildPriorityIndicator(task.priority),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(child: _buildTitle()),
|
Expanded(child: _buildTitle(context)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 4),
|
||||||
if (task.desc != null && task.desc!.isNotEmpty) _buildDesc(),
|
if (task.desc != null && task.desc!.isNotEmpty) _buildDesc(),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 4),
|
||||||
if (task.dueDate != null || task.scheduleDate != null)
|
if (task.dueDate != null || task.scheduleDate != null)
|
||||||
_buildDate(),
|
_buildDate(),
|
||||||
],
|
],
|
||||||
@@ -62,14 +62,14 @@ class TaskItem extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTitle() {
|
Widget _buildTitle(BuildContext context) {
|
||||||
return Text(
|
return Text(
|
||||||
task.title,
|
task.title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.bold,
|
||||||
decoration: task.isCompleted ? TextDecoration.lineThrough : null,
|
decoration: task.isCompleted ? TextDecoration.lineThrough : null,
|
||||||
color: task.isCompleted ? Colors.grey : Colors.red,
|
color: task.isCompleted ? Colors.grey[100] : FluentTheme.of(context).accentColor,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ class TaskItem extends StatelessWidget {
|
|||||||
return Text(
|
return Text(
|
||||||
task.desc!,
|
task.desc!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.grey,
|
color: Colors.grey[150],
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
decoration: task.isCompleted ? TextDecoration.lineThrough : null,
|
decoration: task.isCompleted ? TextDecoration.lineThrough : null,
|
||||||
),
|
),
|
||||||
@@ -89,20 +89,20 @@ class TaskItem extends StatelessWidget {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
if (task.dueDate != null) ...[
|
if (task.dueDate != null) ...[
|
||||||
const Icon(FluentIcons.calendar, size: 12, color: Colors.grey),
|
Icon(FluentIcons.calendar, size: 12, color: Colors.grey),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
'截止日期: ${_formatDate(task.dueDate!)}',
|
'截止日期: ${_formatDate(task.dueDate!)}',
|
||||||
style: const TextStyle(color: Colors.grey, fontSize: 12),
|
style: TextStyle(color: Colors.grey, fontSize: 12),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
],
|
],
|
||||||
if (task.scheduleDate != null) ...[
|
if (task.scheduleDate != null) ...[
|
||||||
const Icon(FluentIcons.clock, size: 12, color: Colors.grey),
|
Icon(FluentIcons.clock, size: 12, color: Colors.grey),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
'提醒日期: ${_formatDate(task.scheduleDate!)}',
|
'提醒日期: ${_formatDate(task.scheduleDate!)}',
|
||||||
style: const TextStyle(color: Colors.grey, fontSize: 12),
|
style: TextStyle(color: Colors.grey, fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
10
pubspec.lock
10
pubspec.lock
@@ -453,6 +453,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
window_size:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: window_size
|
||||||
|
sha256: "8ba77a3df7bd686e60b21e699e60e1b103e6515950954b46c4fb6f513586e278"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -470,5 +478,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "6.6.1"
|
version: "6.6.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.8.0 <4.0.0"
|
dart: ">=3.10.0 <4.0.0"
|
||||||
flutter: ">=3.32.0"
|
flutter: ">=3.32.0"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
name: task_hub
|
name: task_hub
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <window_size/window_size_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
WindowSizePluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("WindowSizePlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
window_size
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
@@ -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.Create(L"task_hub", origin, size)) {
|
if (!window.Create(L"TaskHub", origin, size)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
window.SetQuitOnClose(true);
|
window.SetQuitOnClose(true);
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 168 KiB |
Reference in New Issue
Block a user