Skip to content

Commit

Permalink
chore!: make an initial commit
Browse files Browse the repository at this point in the history
BREAKING CHANGE: basically everything 🤏
  • Loading branch information
benthillerkus committed Mar 29, 2022
0 parents commit 2628331
Show file tree
Hide file tree
Showing 77 changed files with 4,158 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
.vs

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/
10 changes: 10 additions & 0 deletions .metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: 7e9793dee1b85a243edd0e06cb1658e98b077561
channel: stable

project_type: plugin
14 changes: 14 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"cSpell.words": [
"ARGB",
"autofocus",
"HICON",
"HWND",
"LPARAM",
"LRESULT",
"scrollbars",
"ulid",
"Ulid"
],
"dart.lineLength": 80
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

* TODO: Describe initial release.
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO: Add your license here.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# betrayal

A tray icon plugin for Windows.

## Getting Started

This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

## TBD
- FIXME Find out all possible errors and repackage / handle them
- TODO Write documentation
- TODO Support Windows default icons ([MAKEINTRESOURCE....](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadicona))
- TODO Support images
- TODO Find out, communicate and memoize the correct system metrics (icon resolution)
- TODO Support interaction
- TODO Support menus
- TODO Add function to configure a TrayIcon in one call (maybe via a dynamic map actually)
- FIXME Use OnWidgetUpdated or smth like that to diff changes between widget dependencies and flush them to the plugin
- TODO Add second example using the Widget API
- TODO Support setting titlebar / application icon

Use [https://www.conventionalcommits.org/en/v1.0.0/](https://www.conventionalcommits.org/en/v1.0.0/) for commits.
4 changes: 4 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
1 change: 1 addition & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Examples
46 changes: 46 additions & 0 deletions example/add_many/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
10 changes: 10 additions & 0 deletions example/add_many/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: 7e9793dee1b85a243edd0e06cb1658e98b077561
channel: stable

project_type: app
16 changes: 16 additions & 0 deletions example/add_many/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Add many example

Demonstrates how to use the betrayal plugin.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
29 changes: 29 additions & 0 deletions example/add_many/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
Binary file added example/add_many/assets/dart.ico
Binary file not shown.
Binary file added example/add_many/assets/flutter.ico
Binary file not shown.
172 changes: 172 additions & 0 deletions example/add_many/lib/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import 'dart:math';
import 'dart:ui';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:betrayal/betrayal.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
// // If the widget was removed from the tree while the asynchronous platform
// // message was in flight, we want to discard the reply rather than calling
// // setState to update our non-existent appearance.
// if (!mounted) return;

final _icons = List<TrayIcon>.empty(growable: true);

ui.Image? img;

void add() async {
var icon = TrayIcon(const TrayIconData());
_icons.add(icon);
icon.setTooltip("${_icons.length}");

await draw();

setState(() {});

icon.setIcon(
image: img,
// picture: picture,
// asset: "assets/flutter.ico",
freeResources: false,
winIcon: WinIcon.shield);
icon.show();
}

Future<void> draw() async {
final recorder = PictureRecorder();
final canvas = Canvas(recorder);
const center = Offset(16, 16);
final Paint paint = Paint()..color = const Color(0xFFF400BB);
canvas.drawRect(const Rect.fromLTWH(0, 0, 16, 16), paint);
canvas.drawRect(
const Rect.fromLTWH(16, 0, 16, 16), paint..color = Colors.green);
canvas.drawRect(
const Rect.fromLTWH(0, 16, 16, 16), paint..color = Colors.blue);
canvas.drawCircle(center, sqrt(_icons.length.ceilToDouble()),
paint..color = const Color.fromARGB(255, 211, 168, 202));
TextPainter(
text: TextSpan(text: "${_icons.length}"),
textAlign: TextAlign.center,
textDirection: TextDirection.ltr,
maxLines: 1)
..layout()
..paint(canvas, Offset.zero);
canvas.drawRect(
const Rect.fromLTWH(1, 0, 1, 1), paint..color = Colors.green);
canvas.drawRect(
const Rect.fromLTWH(2, 0, 1, 1), paint..color = Colors.blue);

final picture = recorder.endRecording();

img = await picture.toImage(32, 32);
}

void remove() async {
_icons.removeLast().dispose();
await draw();
setState(() {});
}

void removeAll() async {
for (var icon in _icons) {
icon.dispose();
}
_icons.clear();
await draw();
setState(() {});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: Colors.lime,
useMaterial3: true,
brightness: Brightness.light),
home: Scaffold(
appBar: AppBar(
title: const Text('Imperative System Tray Api Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
child: img == null
? null
: CustomPaint(
painter: Lol(img!),
),
width: 32,
height: 32,
),
const Text('Number of Icons:'),
SizedBox.fromSize(
size: const Size.fromHeight(20),
),
SizedBox(
width: 60,
height: 60,
child: AnimatedScale(
duration: const Duration(milliseconds: 200),
scale: sqrt(sqrt(_icons.length + 1)),
curve: Curves.easeOutBack,
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer,
shape: BoxShape.circle),
child: Transform.translate(
offset: const Offset(0, -2),
child: Center(
child: Text(
'${_icons.length}',
style: Theme.of(context).textTheme.headline4,
)),
),
),
),
),
],
),
),
persistentFooterButtons: [
TextButton.icon(
onPressed: add,
icon: const Icon(Icons.plus_one),
label: const Text("Add Icon")),
TextButton.icon(
onPressed: _icons.isEmpty ? null : remove,
icon: const Icon(Icons.remove),
label: const Text("Remove Icon"),
onLongPress: _icons.isEmpty ? null : removeAll),
],
),
);
}
}

class Lol extends CustomPainter {
Lol(this.img);

ui.Image img;

@override
void paint(Canvas canvas, Size size) {
canvas.drawImage(img, Offset.zero, Paint());
}

@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
Loading

0 comments on commit 2628331

Please sign in to comment.