ApplicationSupportDirectoryで読み書き

https://qiita.com/yoyo-misc/items/ac5e8057a66035b62463

前回の記事の続きです。

https://qiita.com/yoyo-misc/items/0dcf3a1a6f6efff02833

途中でcsvからJSONの読み書きに変更しています。

# JSONの保存先をローカルパスからApplicationSupportDirectoryに変更

## Windowsパス読み取りパッケージのインストール

https://pub.dev/packages/path_provider_windows

今まではローカルパス`D:/app.json`にJSONを保存して読み書きしていましたが、Windowsの流儀に従ってApplicationSupportDirectoryに保存するように修正します。`flutter.dev`のリポジトリには共通パッケージ版の https://pub.dev/packages/path_provider がありますが、今回はこちらのwindows専用パッケージを導入します。

## パスの設定例

``` :dart
final _provider = PathProviderWindows();
late File _appSetting;
late File _appPosition;

Future<void> initDirectories() async {
  final basePath = await _provider.getApplicationSupportPath();
  _appSetting = File("$basePath\\AppSetting.json");
  _appPosition = File("$basePath\\AppPosition.json");
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initDirectories();
```

FutureクラスでinitDirectories()メソッドを作成し、エントリーポイントのmain()で呼び出してグローバル変数に値をセットします。
※私はFlutterの流儀がまだ把握できていないので、ご自身のやり方で設定してみてください。

WindowsにおいてgetApplicationSupportPath()を参照すると以下のパスが取得されます。
`C:\Users\{youre-accountname}\AppData\Roaming\{company-name}\{app-name}`

{youre-accountname} = yoyo（Windowsのアカウント名）
{company-name} = com.yoyo（会社名）
{app-name} = flutter_sticky（アプリ名）

置きかえるとこうなる**はず**ですが、規定値ではcom.exapmleに出力されます。
`C:\Users\yoyo\AppData\Roaming\com.yoyo\flutter_sticky`

:::note warn
規定値ではCompanyNameはcom.exapmleのままなのでcom.exapmle/app-nameとして格納されます。CompanyNameを変更することで上記のパスにて読み書きされるようになります、
:::

## Windowsでcom.exampleを変更する

AndroidやiOSはみなさん慣れたものだと思いますが、Windowはどこで指定しているか調べてみたら`Runner.rc`に記述されていました。

``` :{applicationName}\windows\runner\Runner.rc
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904e4"
        BEGIN
            VALUE "CompanyName", "com.yoyo" "\0"
            VALUE "FileDescription", "flutter_sticky" "\0"
            VALUE "FileVersion", VERSION_AS_STRING "\0"
            VALUE "InternalName", "flutter_sticky" "\0"
            VALUE "LegalCopyright", "Copyright (C) 2024 com.yoyo. All rights reserved." "\0"
```
com.exampleとなっているところを修正していきます。

変更した箇所
CompanyName： com.example => com.yoyo
LegalCopyRight： com.example => com.yoyo

## 出力結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/b31eb312-5aa3-b0ca-7e60-d890b6058af7.png)

`C:\Users\yoyo\AppData\Roaming\com.yoyo\flutter_sticky`

期待通りのパスに出力されました。

# おまけ：付箋アプリを作りました

## 編集画面

![edit.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/8840b40a-214c-0d27-8eb5-456e9d81dc71.png)

編集画面ではアプリケーションウィンドウのタイトルバーを表示し、掴んでウィンドウを移動できるようにしています。

## タスクトレイに格納（常駐）

![hide.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/6ed7b7b2-6e15-fa4e-6d6f-aa10f8350fbe.png)

ウィンドウのバツボタンをクリックするとタスクトレイに格納されます。アプリケーションを終了するにはタスクトレイアイコンを右クリックしExitボタンを押します。

## 付箋として表示

![fix.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/ed6077bc-3e7a-e128-cd31-9cdeac94c429.png)

付箋として固定表示させるにはFloating ButtonでFixします。Fixするとウィンドウタイトルが非表示となり移動ができなくなります。再び移動する場合は付箋の文字にカーソルをあてるとアクティブ（編集画面）になります。

## 困った点

`onWindowBlur()`で`await windowManager.setTitleBarStyle(TitleBarStyle.normal)`を実行すると、ウィンドウから離れたさいにイベントが実行されますが、タスクトレイで右クリックをすると`onWindowBlur()`を通過してしまうため処理がループしてしまいExitすることが出来なくなります。これを回避するために付箋内にFloating Buttonを配置してFix処理をするようにしています。

FixボタンはでMouseRegionクラスの`onHover`と`onExit`でボタンの透過率を可変にしています。マウスを当てていない場合は透過率を0.3にしているため邪魔に感じません。

## おわり

これでおしまいではなく、まだ機能を追加したいと思っています。

* 付箋を前面に表示
* アラーム機能の追加
* Croud Firestore(Database)と連携
* Androidアプリ（このアプリflutter_sticky）と連携

続く（かもしれまません）