Theme switching with ChangeProvider
This commit is contained in:
parent
5cbc0814f6
commit
d45ac78e64
|
@ -0,0 +1,12 @@
|
||||||
|
# State Management
|
||||||
|
|
||||||
|
We use a MultiProvider to distribute state to the underlying widgets. Right now there are 2 top
|
||||||
|
level Providers: FlwtchState (the app) and OpaqueTheme.
|
||||||
|
|
||||||
|
## Theme
|
||||||
|
|
||||||
|
OpaqueTheme extends ChangeProvider. SetLight and SetDark are functions that call notifyListeners()
|
||||||
|
|
||||||
|
ChangeNotiferProvider is used to package OpaqueTheme into a provider which is a top level
|
||||||
|
provider (as every widget in the app needs to be re-rendered on a theme switch).
|
||||||
|
|
|
@ -32,17 +32,17 @@ class FlwtchState extends State<Flwtch> {
|
||||||
// mergenotes: ui stuff
|
// mergenotes: ui stuff
|
||||||
ProfileModel selectedProfile;
|
ProfileModel selectedProfile;
|
||||||
String selectedConversation = "";
|
String selectedConversation = "";
|
||||||
var columns = [1];// default or 'single column' mode
|
var columns = [1]; // default or 'single column' mode
|
||||||
//var columns = [1, 1, 2];
|
//var columns = [1, 1, 2];
|
||||||
|
|
||||||
AppModel appStatus;
|
AppModel appStatus;
|
||||||
HashMap<String, ProfileModel> profiles;
|
HashMap<String, ProfileModel> profiles;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
cwtchInit = false;
|
cwtchInit = false;
|
||||||
|
|
||||||
profiles = new HashMap<String, ProfileModel>();
|
profiles = new HashMap<String, ProfileModel>();
|
||||||
|
|
||||||
print("FlwtchState.initState()");
|
print("FlwtchState.initState()");
|
||||||
|
@ -80,32 +80,55 @@ class FlwtchState extends State<Flwtch> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChangeNotifierProvider<OpaqueTheme> getOpaqueProvider() {
|
||||||
|
return ChangeNotifierProvider(create: (context) => OpaqueTheme(Opaque.dark));
|
||||||
|
}
|
||||||
|
|
||||||
|
Provider<FlwtchState> getFlwtchStateProvider() {
|
||||||
|
return Provider<FlwtchState>(
|
||||||
|
create: (_) => this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
appStatus = AppModel(cwtch: cwtch);
|
appStatus = AppModel(cwtch: cwtch);
|
||||||
|
|
||||||
final newTextTheme = Theme.of(context).textTheme.apply(
|
final newTextTheme = Theme.of(context).textTheme.apply(
|
||||||
bodyColor: Opaque.current().mainTextColor(),
|
bodyColor: Opaque.current().mainTextColor(),
|
||||||
displayColor: Opaque.current().mainTextColor(),
|
displayColor: Opaque.current().mainTextColor(),
|
||||||
);
|
);
|
||||||
|
|
||||||
print("FlwtchState.build() cwtchInit: $cwtchInit");
|
print("FlwtchState.build() cwtchInit: $cwtchInit");
|
||||||
return Provider<FlwtchState>(
|
return MultiProvider(
|
||||||
create: (_) => this,
|
providers: [getFlwtchStateProvider(), getOpaqueProvider()],
|
||||||
child: MaterialApp(
|
builder: (context, widget) { return MaterialApp(
|
||||||
title: 'Cwtch',
|
title: 'Cwtch',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
primarySwatch: Colors.red,
|
primarySwatch: Colors.red,
|
||||||
primaryColor: Opaque.current().backgroundMainColor(),
|
primaryColor: Provider.of<OpaqueTheme>(context)
|
||||||
canvasColor: Opaque.current().backgroundPaneColor(),
|
.current()
|
||||||
accentColor: Opaque.current().defaultButtonColor(),
|
.backgroundMainColor(),
|
||||||
buttonColor: Opaque.current().defaultButtonColor(),
|
canvasColor: Provider.of<OpaqueTheme>(context)
|
||||||
textTheme: newTextTheme,
|
.current()
|
||||||
),
|
.backgroundPaneColor(),
|
||||||
// from dan: home: cwtchInit == true ? ProfileMgrView(cwtch) : SplashView(),
|
accentColor: Provider.of<OpaqueTheme>(context)
|
||||||
// from erinn: home: columns.length == 3 ? TripleColumnView() : ProfileMgrView(),
|
.current()
|
||||||
home: cwtchInit == true ? (columns.length == 3 ? TripleColumnView() : ProfileMgrView()) : SplashView(),
|
.defaultButtonColor(),
|
||||||
));
|
buttonColor: Provider.of<OpaqueTheme>(context)
|
||||||
|
.current()
|
||||||
|
.defaultButtonColor(),
|
||||||
|
textTheme: newTextTheme,
|
||||||
|
),
|
||||||
|
// from dan: home: cwtchInit == true ? ProfileMgrView(cwtch) : SplashView(),
|
||||||
|
// from erinn: home: columns.length == 3 ? TripleColumnView() : ProfileMgrView(),
|
||||||
|
home: cwtchInit == true
|
||||||
|
? (columns.length == 3
|
||||||
|
? TripleColumnView()
|
||||||
|
: ProfileMgrView())
|
||||||
|
: SplashView(),
|
||||||
|
);},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
abstract class OpaqueThemeType {
|
abstract class OpaqueThemeType {
|
||||||
static final Color red = Color(0xFFFF0000);
|
static final Color red = Color(0xFFFF0000);
|
||||||
Color backgroundMainColor(){return red;}
|
Color backgroundMainColor(){return red;}
|
||||||
|
@ -421,9 +423,12 @@ class Opaque extends OpaqueThemeType {
|
||||||
int chatPaneMinSize() { return chatPaneMinSizeBase[p[scale]]; }
|
int chatPaneMinSize() { return chatPaneMinSizeBase[p[scale]]; }
|
||||||
int doublePaneMinSize() { return sidePaneMinSize() + chatPaneMinSize(); }
|
int doublePaneMinSize() { return sidePaneMinSize() + chatPaneMinSize(); }
|
||||||
|
|
||||||
|
static OpaqueThemeType _current;
|
||||||
static final OpaqueThemeType dark = CwtchDark();
|
static final OpaqueThemeType dark = CwtchDark();
|
||||||
static final OpaqueThemeType light = CwtchLight();
|
static final OpaqueThemeType light = CwtchLight();
|
||||||
static OpaqueThemeType current() { return dark; }
|
static void setDark() { _current = dark; }
|
||||||
|
static void setLight() { _current = light; }
|
||||||
|
static OpaqueThemeType current() { if (_current == null) {setDark();} return _current; }
|
||||||
|
|
||||||
|
|
||||||
int scale = 2;
|
int scale = 2;
|
||||||
|
@ -507,3 +512,15 @@ int scale = 2;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// TODO: Wire into libCwtch saveSettings / updateTheme etc...
|
||||||
|
class OpaqueTheme extends ChangeNotifier {
|
||||||
|
OpaqueThemeType theme;
|
||||||
|
void setDark() { theme = Opaque.dark; notifyListeners();}
|
||||||
|
void setLight() { theme = Opaque.light; notifyListeners();}
|
||||||
|
OpaqueThemeType current() { return theme; }
|
||||||
|
|
||||||
|
OpaqueTheme(this.theme);
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_app/main.dart';
|
||||||
|
import 'package:flutter_app/opaque.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class GlobalSettingsView extends StatefulWidget {
|
class GlobalSettingsView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
@ -35,7 +38,18 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Text("Zoom"),
|
Text("Zoom"),
|
||||||
Text("Theme"),
|
SwitchListTile(
|
||||||
|
title: const Text('Theme'),
|
||||||
|
value: Provider.of<OpaqueTheme>(context).current() == Opaque.light,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
if (value) {
|
||||||
|
Provider.of<OpaqueTheme>(context, listen: false).setLight();
|
||||||
|
} else {
|
||||||
|
Provider.of<OpaqueTheme>(context, listen: false).setDark();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
secondary: const Icon(Icons.lightbulb_outline),
|
||||||
|
),
|
||||||
Text("Experiments enabled"),
|
Text("Experiments enabled"),
|
||||||
Text("Text magnification reference"),
|
Text("Text magnification reference"),
|
||||||
Text("Acknowledgements"),
|
Text("Acknowledgements"),
|
||||||
|
|
Loading…
Reference in New Issue