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