1
- using Flow . Launcher . Core . Resource ;
1
+ using Accessibility ;
2
+ using Flow . Launcher . Core . Resource ;
3
+ using Flow . Launcher . Infrastructure ;
2
4
using System ;
3
5
using System . Collections . Generic ;
4
6
using System . Diagnostics ;
8
10
using System . Text . Json ;
9
11
using System . Threading ;
10
12
using System . Threading . Tasks ;
11
- using System . Windows . Forms ;
12
13
using Flow . Launcher . Infrastructure . Logger ;
14
+ using Flow . Launcher . Infrastructure . UserSettings ;
13
15
using Flow . Launcher . Plugin ;
14
16
using ICSharpCode . SharpZipLib . Zip ;
15
17
using JetBrains . Annotations ;
16
18
using Microsoft . IO ;
19
+ using System . Text . Json . Serialization ;
20
+ using System . Windows ;
21
+ using System . Windows . Controls ;
22
+ using System . Windows . Forms ;
23
+ using CheckBox = System . Windows . Controls . CheckBox ;
24
+ using Control = System . Windows . Controls . Control ;
25
+ using Label = System . Windows . Controls . Label ;
26
+ using Orientation = System . Windows . Controls . Orientation ;
27
+ using TextBox = System . Windows . Controls . TextBox ;
28
+ using UserControl = System . Windows . Controls . UserControl ;
17
29
18
30
namespace Flow . Launcher . Core . Plugin
19
31
{
20
32
/// <summary>
21
33
/// Represent the plugin that using JsonPRC
22
34
/// every JsonRPC plugin should has its own plugin instance
23
35
/// </summary>
24
- internal abstract class JsonRPCPlugin : IAsyncPlugin , IContextMenu
36
+ internal abstract class JsonRPCPlugin : IAsyncPlugin , IContextMenu , ISettingProvider , ISavable
25
37
{
26
38
protected PluginInitContext context ;
27
39
public const string JsonRPC = "JsonRPC" ;
@@ -35,6 +47,8 @@ internal abstract class JsonRPCPlugin : IAsyncPlugin, IContextMenu
35
47
36
48
private static readonly RecyclableMemoryStreamManager BufferManager = new ( ) ;
37
49
50
+ private string SettingPath => Path . Combine ( DataLocation . PluginSettingsDirectory , context . CurrentPluginMetadata . Name , "Setting.json" ) ;
51
+
38
52
public List < Result > LoadContextMenus ( Result selectedResult )
39
53
{
40
54
var request = new JsonRPCRequestModel
@@ -58,6 +72,7 @@ public List<Result> LoadContextMenus(Result selectedResult)
58
72
new JsonObjectConverter ( )
59
73
}
60
74
} ;
75
+ private Dictionary < string , object > Settings { get ; set ; }
61
76
62
77
private async Task < List < Result > > DeserializedResultAsync ( Stream output )
63
78
{
@@ -292,10 +307,115 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
292
307
return await DeserializedResultAsync ( output ) ;
293
308
}
294
309
295
- public virtual Task InitAsync ( PluginInitContext context )
310
+ public async Task InitSettingAsync ( )
311
+ {
312
+ if ( File . Exists ( SettingPath ) )
313
+ Settings = await JsonSerializer . DeserializeAsync < Dictionary < string , object > > ( File . OpenRead ( SettingPath ) , options ) ;
314
+
315
+ var request = new JsonRPCRequestModel ( )
316
+ {
317
+ Method = "get_setting_template"
318
+ } ;
319
+ await using var result = await RequestAsync ( request ) ;
320
+ if ( result . Length == 0 )
321
+ return ;
322
+ var settingsTemplate = await JsonSerializer . DeserializeAsync < Dictionary < string , JsonElement > > ( result , options ) ??
323
+ new ( ) ;
324
+
325
+ Settings ??= new ( ) ;
326
+
327
+ foreach ( var ( key , element ) in settingsTemplate )
328
+ {
329
+ if ( ! Settings . ContainsKey ( key ) )
330
+ {
331
+ Settings [ key ] = element . ValueKind switch
332
+ {
333
+ JsonValueKind . True or JsonValueKind . False => element . GetBoolean ( ) ,
334
+ JsonValueKind . String or JsonValueKind . Number => element . GetString ( ) ,
335
+ JsonValueKind . Null => throw new ArgumentNullException ( ) ,
336
+ _ => throw new ArgumentOutOfRangeException ( )
337
+ } ;
338
+ }
339
+ }
340
+ }
341
+
342
+ public virtual async Task InitAsync ( PluginInitContext context )
296
343
{
297
344
this . context = context ;
298
- return Task . CompletedTask ;
345
+ await InitSettingAsync ( ) ;
346
+ }
347
+ private static Thickness settingControlMargin = new ( 10 ) ;
348
+ public Control CreateSettingPanel ( )
349
+ {
350
+ if ( Settings == null )
351
+ return new ( ) ;
352
+ var settingWindow = new UserControl ( ) ;
353
+ var mainPanel = new StackPanel
354
+ {
355
+ Margin = settingControlMargin ,
356
+ Orientation = Orientation . Vertical
357
+ } ;
358
+ settingWindow . Content = mainPanel ;
359
+ foreach ( var ( key , value ) in Settings )
360
+ {
361
+ var panel = new StackPanel
362
+ {
363
+ Orientation = Orientation . Horizontal ,
364
+ Margin = settingControlMargin
365
+ } ;
366
+ var name = new Label
367
+ {
368
+ Content = key ,
369
+ VerticalAlignment = VerticalAlignment . Center
370
+ } ;
371
+ UIElement content = null ;
372
+ switch ( value )
373
+ {
374
+ case int i :
375
+ case double d :
376
+ throw new TypeAccessException ( ) ;
377
+ case string s :
378
+ var textBox = new TextBox
379
+ {
380
+ Text = s ,
381
+ Margin = settingControlMargin ,
382
+ VerticalAlignment = VerticalAlignment . Center
383
+ } ;
384
+ textBox . TextChanged += ( _ , _ ) =>
385
+ {
386
+ Settings [ key ] = textBox . Text ;
387
+ } ;
388
+ content = textBox ;
389
+ break ;
390
+ case bool b :
391
+ var checkBox = new CheckBox
392
+ {
393
+ IsChecked = b ,
394
+ Margin = settingControlMargin ,
395
+ VerticalAlignment = VerticalAlignment . Center
396
+ } ;
397
+ checkBox . Click += ( _ , _ ) =>
398
+ {
399
+ Settings [ key ] = checkBox . IsChecked ;
400
+ } ;
401
+ content = checkBox ;
402
+ break ;
403
+ default :
404
+ throw new ArgumentOutOfRangeException ( ) ;
405
+ }
406
+ panel . Children . Add ( name ) ;
407
+ panel . Children . Add ( content ) ;
408
+ mainPanel . Children . Add ( panel ) ;
409
+ }
410
+ return settingWindow ;
411
+ }
412
+ public void Save ( )
413
+ {
414
+ if ( Settings != null )
415
+ {
416
+ Helper . ValidateDirectory ( Path . Combine ( DataLocation . PluginSettingsDirectory , context . CurrentPluginMetadata . Name ) ) ;
417
+ File . WriteAllText ( SettingPath , JsonSerializer . Serialize ( Settings ) ) ;
418
+ }
299
419
}
300
420
}
301
421
}
0 commit comments