feat:增加主题色

This commit is contained in:
2026-04-26 17:22:14 +08:00
parent 8f6e4cc23e
commit db52de7b56
11 changed files with 108 additions and 93 deletions

View File

@@ -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: [

View File

@@ -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),
), ),
); );
}, },

View File

@@ -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(

View File

@@ -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(

View File

@@ -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),
), ),
], ],
], ],

View File

@@ -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"

View File

@@ -1 +1 @@
name: task_hub name: task_hub

View File

@@ -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"));
} }

View File

@@ -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

View File

@@ -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