Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/lib/src/models/colors.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:dart_leap/dart_leap.dart';

class BasicColors {
static const light = SRGBColor(0xFFD9D9D9);
static const dark = SRGBColor(0xFF1A1A1A);
static const light = SRGBColor(0xFF9E9E9E);
static const dark = SRGBColor(0xFF3A3A3A);
static const red = SRGBColor(0xFFF44336);
static const blue = SRGBColor(0xFF2196F3);
static const whiteTransparent = SRGBColor(0x00FFFFFF);
Expand Down
113 changes: 94 additions & 19 deletions api/lib/src/models/texture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,142 @@ import 'colors.dart';
part 'texture.g.dart';
part 'texture.freezed.dart';

enum PatternBackground { light, dark }

enum PatternTemplate {
plain,
ruled,
quad,
music,
plainDark,
ruled,
ruledDark,
ruledSimple,
ruledSimpleDark,
quad,
quadDark,
quadSimple,
quadSimpleDark,
music,
musicDark,
dotted,
dottedDark,
}

const templateDirectory = 'templates/';

extension PatternTemplateExtension on PatternTemplate {
// camelCase to snake_case
String get asset =>
'templates/${name.replaceAllMapped(RegExp(r'([A-Z])'), (match) => '_${match.group(1)?.toLowerCase()}')}.png';
String get asset => '$templateDirectory$assetName';
String get assetName =>
'${name.replaceAllMapped(RegExp(r'([A-Z])'), (match) => '_${match.group(1)?.toLowerCase()}')}.png';

bool get dark => [
PatternTemplate.plainDark,
PatternTemplate.ruledDark,
PatternTemplate.quadDark,
PatternTemplate.musicDark,
].contains(this);
PatternBackground get background => switch (this) {
PatternTemplate.plain ||
PatternTemplate.ruled ||
PatternTemplate.ruledSimple ||
PatternTemplate.quad ||
PatternTemplate.quadSimple ||
PatternTemplate.music ||
PatternTemplate.dotted => PatternBackground.light,
PatternTemplate.plainDark ||
PatternTemplate.ruledDark ||
PatternTemplate.ruledSimpleDark ||
PatternTemplate.quadDark ||
PatternTemplate.quadSimpleDark ||
PatternTemplate.musicDark ||
PatternTemplate.dottedDark => PatternBackground.dark,
};

PatternTexture create() {
switch (this) {
case PatternTemplate.plain:
return const PatternTexture(boxColor: BasicColors.light);
return const PatternTexture(boxColor: SRGBColor.white);
case PatternTemplate.ruled:
return const PatternTexture(boxColor: BasicColors.light, boxHeight: 40);
return const PatternTexture(boxColor: SRGBColor.white, boxHeight: 40);
case PatternTemplate.ruledSimple:
return const PatternTexture(
boxColor: SRGBColor.white,
boxHeight: 40,
boxXColor: BasicColors.dark,
boxYColor: BasicColors.dark,
);
case PatternTemplate.quad:
return const PatternTexture(
boxColor: BasicColors.light,
boxColor: SRGBColor.white,
boxHeight: 40,
boxWidth: 40,
);
case PatternTemplate.quadSimple:
return const PatternTexture(
boxColor: SRGBColor.white,
boxHeight: 40,
boxWidth: 40,
boxXColor: BasicColors.dark,
boxYColor: BasicColors.dark,
);
case PatternTemplate.music:
return const PatternTexture(
boxColor: BasicColors.light,
boxColor: SRGBColor.white,
boxHeight: 40,
boxYColor: SRGBColor.black,
boxYSpace: 80,
boxYCount: 5,
);
case PatternTemplate.dotted:
return const PatternTexture(
boxColor: SRGBColor.white,
boxWidth: 40,
boxHeight: 40,
boxXCount: 1,
boxYCount: 2,
boxXStroke: 5,
boxYStroke: 35,
boxXColor: BasicColors.light,
boxYColor: SRGBColor.white,
);
case PatternTemplate.plainDark:
return const PatternTexture(boxColor: BasicColors.dark);
return const PatternTexture(boxColor: SRGBColor.black);
case PatternTemplate.ruledDark:
return const PatternTexture(boxColor: BasicColors.dark, boxHeight: 40);
return const PatternTexture(boxColor: SRGBColor.black, boxHeight: 40);
case PatternTemplate.ruledSimpleDark:
return const PatternTexture(
boxColor: SRGBColor.black,
boxHeight: 40,
boxXColor: BasicColors.dark,
boxYColor: BasicColors.dark,
);
case PatternTemplate.quadDark:
return const PatternTexture(
boxColor: BasicColors.dark,
boxColor: SRGBColor.black,
boxWidth: 40,
boxHeight: 40,
);
case PatternTemplate.quadSimpleDark:
return const PatternTexture(
boxColor: SRGBColor.black,
boxWidth: 40,
boxHeight: 40,
boxXColor: BasicColors.dark,
boxYColor: BasicColors.dark,
);
case PatternTemplate.musicDark:
return const PatternTexture(
boxColor: BasicColors.dark,
boxColor: SRGBColor.black,
boxYColor: SRGBColor.white,
boxHeight: 40,
boxYSpace: 80,
boxYCount: 5,
);
case PatternTemplate.dottedDark:
return const PatternTexture(
boxColor: SRGBColor.black,
boxWidth: 40,
boxHeight: 40,
boxXCount: 1,
boxYCount: 2,
boxXStroke: 5,
boxYStroke: 35,
boxXColor: BasicColors.dark,
boxYColor: SRGBColor.black,
);
}
}
}
Expand Down
8 changes: 0 additions & 8 deletions app/lib/api/file_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,6 @@ class ButterflyFileSystem {
}
}

Future<void> _createDefaultTemplates(TemplateFileSystem fs) async =>
Future.wait(
(await DocumentDefaults.getDefaults(
context,
)).map((e) => fs.createFile('${e.name}.bfly', e)),
);

Future<void> _createDefaultPacks(PackFileSystem fs) async {
final pack = await DocumentDefaults.getCorePack();
await fs.createFile('${pack.name}.bfly', pack);
Expand Down Expand Up @@ -240,7 +233,6 @@ class ButterflyFileSystem {
onEncode: _encode,
onDecode: _decode,
storage: storage,
createDefault: _createDefaultTemplates,
);
_templateCache[key] = system;
return system;
Expand Down
52 changes: 51 additions & 1 deletion app/lib/cubits/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ enum StartupBehavior { openHomeScreen, openLastNote, openNewNote }

enum InputMappingCategory { activeTool, handTool, toolOnToolbar }

@freezed
sealed class FavoriteLocation with _$FavoriteLocation {
const FavoriteLocation._();

const factory FavoriteLocation({String? remote, required String path}) =
_FavoriteLocation;

factory FavoriteLocation.fromJson(Map<String, dynamic> json) =>
_$FavoriteLocationFromJson(json);

factory FavoriteLocation.fromLocation(AssetLocation location) {
return FavoriteLocation(remote: location.remote, path: location.path);
}

AssetLocation toLocation([String defaultRemote = '']) {
return AssetLocation(path: path, remote: remote ?? defaultRemote);
}
}

class InputMappingDefault {
static const InputMapping leftMouse = InputMapping(
InputMapping.activeToolValue,
Expand Down Expand Up @@ -311,6 +330,9 @@ sealed class ButterflySettings with _$ButterflySettings, LeapSettings {
@Default(InputConfiguration()) InputConfiguration inputConfiguration,
@Default('') String fallbackPack,
@Default([]) List<String> starred,
@Default([])
@JsonKey(includeFromJson: false, includeToJson: false)
List<FavoriteLocation> favoriteTemplates,
@Default('') String defaultTemplate,
@Default(NavigatorPosition.left) NavigatorPosition navigatorPosition,
@Default(ToolbarPosition.inline) ToolbarPosition toolbarPosition,
Expand Down Expand Up @@ -386,7 +408,7 @@ sealed class ButterflySettings with _$ButterflySettings, LeapSettings {
return null;
}
})
.whereType<AssetLocation>()
.nonNulls
.toList() ??
[],
zoomEnabled: prefs.getBool('zoom_enabled') ?? true,
Expand All @@ -403,6 +425,19 @@ sealed class ButterflySettings with _$ButterflySettings, LeapSettings {
),
fallbackPack: prefs.getString('fallback_pack') ?? '',
starred: prefs.getStringList('starred') ?? [],
favoriteTemplates:
prefs
.getStringList('favorite_templates')
?.map((e) {
try {
return FavoriteLocation.fromJson(json.decode(e));
} catch (e) {
return null;
}
})
.nonNulls
.toList() ??
[],
defaultTemplate: prefs.getString('default_template') ?? '',
toolbarPosition: prefs.containsKey('toolbar_position')
? ToolbarPosition.values.byName(prefs.getString('toolbar_position')!)
Expand Down Expand Up @@ -536,6 +571,10 @@ sealed class ButterflySettings with _$ButterflySettings, LeapSettings {
);
await prefs.setString('fallback_pack', fallbackPack);
await prefs.setStringList('starred', starred);
await prefs.setStringList(
'favorite_templates',
favoriteTemplates.map((e) => json.encode(e.toJson())).toList(),
);
await prefs.setInt('version', 0);
await prefs.setString('default_template', defaultTemplate);
await prefs.setString('toolbar_position', toolbarPosition.name);
Expand Down Expand Up @@ -984,6 +1023,17 @@ class SettingsCubit extends Cubit<ButterflySettings>
return save();
}

Future<void> toggleFavoriteTemplate(FavoriteLocation template) {
final favorites = state.favoriteTemplates.toList();
if (favorites.contains(template)) {
favorites.remove(template);
} else {
favorites.add(template);
}
emit(state.copyWith(favoriteTemplates: favorites));
return save();
}

Future<void> changeNavigationRail(bool value) {
emit(state.copyWith(navigationRail: value));
return save();
Expand Down
Loading
Loading