Custom Window Titlebar support

This commit is contained in:
Kingkor Roy Tirtho 2022-01-05 19:17:11 +06:00
parent 619aa4af1a
commit 4d41b037e4
12 changed files with 219 additions and 110 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,3 +1,4 @@
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart' hide Page; import 'package:flutter/material.dart' hide Page;
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
@ -122,6 +123,27 @@ class _HomeState extends State<Home> {
return Scaffold( return Scaffold(
body: Column( body: Column(
children: [ children: [
WindowTitleBarBox(
child: Row(
children: [
Expanded(
child: Row(
children: [
Container(
constraints: const BoxConstraints(maxWidth: 256),
color:
Theme.of(context).navigationRailTheme.backgroundColor,
child: MoveWindow(),
),
Expanded(child: MoveWindow())
],
)),
MinimizeWindowButton(animate: true),
MaximizeWindowButton(animate: true),
CloseWindowButton(animate: true),
],
),
),
Expanded( Expanded(
child: Row( child: Row(
children: [ children: [
@ -165,22 +187,26 @@ class _HomeState extends State<Home> {
builder: (context, snapshot) { builder: (context, snapshot) {
var avatarImg = snapshot.data?.images?.last.url; var avatarImg = snapshot.data?.images?.last.url;
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(16),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [ children: [
if (avatarImg != null) if (avatarImg != null)
CircleAvatar( CircleAvatar(
child: CachedNetworkImage( backgroundImage:
imageUrl: avatarImg, CachedNetworkImageProvider(avatarImg),
),
), ),
const SizedBox(width: 10),
Text( Text(
snapshot.data?.displayName ?? "User's name", snapshot.data?.displayName ?? "User's name",
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
],
),
IconButton( IconButton(
icon: const Icon(Icons.settings_outlined), icon: const Icon(Icons.settings_outlined),
onPressed: () { onPressed: () {
@ -202,6 +228,8 @@ class _HomeState extends State<Home> {
if (_selectedIndex == 0) if (_selectedIndex == 0)
Expanded( Expanded(
child: Scrollbar( child: Scrollbar(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: PagedListView( child: PagedListView(
pagingController: _pagingController, pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Category>( builderDelegate: PagedChildBuilderDelegate<Category>(
@ -212,6 +240,7 @@ class _HomeState extends State<Home> {
), ),
), ),
), ),
),
if (_selectedIndex == 2) const UserLibrary(), if (_selectedIndex == 2) const UserLibrary(),
// player itself // player itself
], ],

View File

@ -0,0 +1,23 @@
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter/material.dart';
class PageWindowTitleBar extends StatelessWidget {
final Widget? leading;
final Widget? center;
const PageWindowTitleBar({Key? key, this.leading, this.center})
: super(key: key);
@override
Widget build(BuildContext context) {
return WindowTitleBarBox(
child: Row(
children: [
if (leading != null) leading!,
Expanded(child: MoveWindow(child: Center(child: center))),
MinimizeWindowButton(animate: true),
MaximizeWindowButton(animate: true),
CloseWindowButton(animate: true),
],
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/PageWindowTitleBar.dart';
import 'package:spotube/components/PlaylistCard.dart'; import 'package:spotube/components/PlaylistCard.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
@ -24,20 +25,14 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
return Scaffold( return Scaffold(
body: Column( body: Column(
children: [ children: [
Row( const PageWindowTitleBar(
// mainAxisAlignment: MainAxisAlignment.center, leading: BackButton(),
children: [ ),
const BackButton(), Text(
// genre name
Expanded(
child: Text(
widget.genreName, widget.genreName,
style: Theme.of(context).textTheme.headline4, style: Theme.of(context).textTheme.headline4,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
),
],
),
Consumer<SpotifyDI>( Consumer<SpotifyDI>(
builder: (context, data, child) => Expanded( builder: (context, data, child) => Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(

View File

@ -1,6 +1,5 @@
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:spotube/components/PageWindowTitleBar.dart';
import 'package:spotube/helpers/zero-pad-num-str.dart'; import 'package:spotube/helpers/zero-pad-num-str.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -98,7 +97,8 @@ class _PlaylistViewState extends State<PlaylistView> {
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16); const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
return Column( return Column(
children: [ children: [
Row( PageWindowTitleBar(
leading: Row(
children: [ children: [
// nav back // nav back
const BackButton(), const BackButton(),
@ -108,8 +108,10 @@ class _PlaylistViewState extends State<PlaylistView> {
onPressed: () {}, onPressed: () {},
), ),
// play playlist // play playlist
Consumer<Playback>(builder: (context, playback, widget) { Consumer<Playback>(
var isPlaylistPlaying = playback.currentPlaylist?.id == builder: (context, playback, widget) {
var isPlaylistPlaying =
playback.currentPlaylist?.id ==
this.widget.playlist.id; this.widget.playlist.id;
return IconButton( return IconButton(
icon: Icon( icon: Icon(
@ -125,8 +127,11 @@ class _PlaylistViewState extends State<PlaylistView> {
tracks: tracks, tracks: tracks,
id: this.widget.playlist.id!, id: this.widget.playlist.id!,
name: this.widget.playlist.name!, name: this.widget.playlist.name!,
thumbnail: thumbnail: this
this.widget.playlist.images![0].url!, .widget
.playlist
.images![0]
.url!,
); );
} }
} }
@ -135,6 +140,7 @@ class _PlaylistViewState extends State<PlaylistView> {
}), }),
], ],
), ),
),
Center( Center(
child: Text(widget.playlist.name!, child: Text(widget.playlist.name!,
style: Theme.of(context).textTheme.headline4), style: Theme.of(context).textTheme.headline4),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/components/PageWindowTitleBar.dart';
import 'package:spotube/provider/Auth.dart'; import 'package:spotube/provider/Auth.dart';
class Settings extends StatefulWidget { class Settings extends StatefulWidget {
@ -14,18 +15,16 @@ class _SettingsState extends State<Settings> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
iconTheme: Theme.of(context).iconTheme,
title: const Text(
"Settings",
),
centerTitle: true,
titleTextStyle: Theme.of(context).textTheme.headline4,
),
body: Column( body: Column(
children: [ children: [
PageWindowTitleBar(
leading: const BackButton(),
center: Text(
"Settings",
style: Theme.of(context).textTheme.headline5,
),
),
const SizedBox(height: 10),
Builder(builder: (context) { Builder(builder: (context) {
var auth = context.read<Auth>(); var auth = context.read<Auth>();
return ElevatedButton( return ElevatedButton(

View File

@ -1,3 +1,4 @@
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -10,6 +11,12 @@ import 'package:spotube/provider/SpotifyDI.dart';
void main() { void main() {
runApp(MyApp()); runApp(MyApp());
doWhenWindowReady(() {
appWindow.minSize = const Size(900, 700);
appWindow.alignment = Alignment.center;
appWindow.maximize();
appWindow.show();
});
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
@ -90,7 +97,13 @@ class MyApp extends StatelessWidget {
), ),
navigationRailTheme: NavigationRailThemeData( navigationRailTheme: NavigationRailThemeData(
backgroundColor: Colors.blueGrey[50], backgroundColor: Colors.blueGrey[50],
)), unselectedIconTheme:
IconThemeData(color: Colors.grey[850], opacity: 1),
unselectedLabelTextStyle: TextStyle(
color: Colors.grey[850],
),
),
),
home: const Home(), home: const Home(),
), ),
); );

View File

@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
bitsdojo_window_linux
url_launcher_linux url_launcher_linux
) )

View File

@ -1,3 +1,4 @@
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
#include "my_application.h" #include "my_application.h"
#include <flutter_linux/flutter_linux.h> #include <flutter_linux/flutter_linux.h>
@ -47,7 +48,9 @@ static void my_application_activate(GApplication* application) {
gtk_window_set_title(window, "spotube"); gtk_window_set_title(window, "spotube");
} }
gtk_window_set_default_size(window, 1280, 720); auto bdw = bitsdojo_window_from(window);
bdw->setCustomFrame(true);
// gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window)); gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlDartProject) project = fl_dart_project_new();

View File

@ -8,6 +8,41 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.8.2"
bitsdojo_window:
dependency: "direct main"
description:
name: bitsdojo_window
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+1"
bitsdojo_window_linux:
dependency: transitive
description:
name: bitsdojo_window_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1"
bitsdojo_window_macos:
dependency: transitive
description:
name: bitsdojo_window_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
bitsdojo_window_platform_interface:
dependency: transitive
description:
name: bitsdojo_window_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
bitsdojo_window_windows:
dependency: transitive
description:
name: bitsdojo_window_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:

View File

@ -44,6 +44,7 @@ dependencies:
youtube_explode_dart: ^1.10.8 youtube_explode_dart: ^1.10.8
mpv_dart: ^0.0.1 mpv_dart: ^0.0.1
infinite_scroll_pagination: ^3.1.0 infinite_scroll_pagination: ^3.1.0
bitsdojo_window: ^0.1.1+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: