Skip to content

Commit eaa4359

Browse files
committed
Open with (C++ implementation on windows)
1 parent aa436ab commit eaa4359

File tree

4 files changed

+115
-69
lines changed

4 files changed

+115
-69
lines changed

lib/homepage.dart

Lines changed: 90 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ void touchFile(File file, CCSolution solution) {
2727
void loadSolution(CCSolution solution, BuildContext context) {
2828
Navigator.pushNamed(context, EditorPage.routeName, arguments: solution);
2929
}
30+
enum HistoryItemType{
31+
solution,
32+
singleFile
33+
}
34+
class HistoryItem{
35+
HistoryItemType type;
36+
CCSolution? solution;
37+
String? filePath;
38+
DateTime dateModified;
39+
String name;
40+
HistoryItem(this.type, {this.solution, this.filePath, required this.dateModified, required this.name});
41+
}
3042

3143
class RecentProjectsManager {
3244
static RecentProjectsManager? _instance;
@@ -36,13 +48,16 @@ class RecentProjectsManager {
3648
return _instance!;
3749
}
3850

39-
List<CCSolution> projects = List.empty(growable: true);
51+
List<HistoryItem> projects = List.empty(growable: true);
4052

4153
/// Commit the recent projects to the pref
4254
Future<void> commit(Future<SharedPreferences> _pref) async {
4355
List<String> list = List.empty(growable: true);
44-
for (CCSolution p in projects) {
45-
list.add(p.slnPath);
56+
for (HistoryItem p in projects) {
57+
if(p.type == HistoryItemType.solution) {
58+
list.add(p.solution!.slnPath);
59+
}
60+
//TODO: support single file
4661
}
4762
(await _pref).setStringList("recentProjectsSln", list).then((bool success) {
4863
debugPrint("Success: $success");
@@ -57,12 +72,14 @@ class RecentProjectsManager {
5772
Future<CCSolution?> addSolution(String slnPath) async {
5873
// Prevent project with same solution to be loaded
5974
for (var p in projects) {
60-
if (p.slnPath == slnPath) return null;
75+
if (p.solution?.slnPath == slnPath) return null;
6176
}
6277

6378
var sln = await CCSolution.loadFromFile(slnPath);
79+
6480
if (sln != null) {
65-
projects.add(sln);
81+
var item = HistoryItem(HistoryItemType.solution, solution: sln, dateModified: sln.dateModified, name: sln.name);
82+
projects.add(item);
6683
}
6784
return sln;
6885
}
@@ -283,7 +300,7 @@ class _HomePageState extends State<HomePage> {
283300
await loadPrefs();
284301
setState(() {
285302
projectsWidgets.clear();
286-
RecentProjectsManager.instance.projects.sort((CCSolution a, CCSolution b) {
303+
RecentProjectsManager.instance.projects.sort((HistoryItem a, HistoryItem b) {
287304
return b.dateModified.compareTo(a.dateModified);
288305
});
289306
if (RecentProjectsManager.instance.projects.isEmpty) {
@@ -294,75 +311,88 @@ class _HomePageState extends State<HomePage> {
294311
);
295312
}
296313
else {
297-
for (CCSolution p in RecentProjectsManager.instance.projects) {
298-
if (p.name == "") {
299-
continue;
300-
} // TODO: add better way to check if project is corrupt
314+
for (HistoryItem p in RecentProjectsManager.instance.projects) {
315+
// if (p.name == "") {
316+
// continue;
317+
// } // TODO: add better way to check if project is corrupt
301318
//debugPrint(p.name);
302319
projectsWidgets.add(Card( //TODO: refactor this as a widget elsewhere, then reference that widget from here
303320
child: ListTile(
304321
onTap: () {
305-
touchFile(File(p.slnPath), p);
306-
refreshRecentProjects();
307-
loadSolution(p, context);
322+
if(p.type == HistoryItemType.solution) {
323+
touchFile(File(p.solution!.slnPath), p.solution!);
324+
refreshRecentProjects();
325+
loadSolution(p.solution!, context);
326+
}
327+
//TODO: Handle single file
308328
},
309-
leading: p.image ??
329+
leading: p.type == HistoryItemType.solution? p.solution!.image ??
310330
const Icon(
311331
Icons.insert_drive_file,
312332
size: 48,
313-
),
333+
):
334+
const Icon(
335+
Icons.insert_drive_file,
336+
size: 48,
337+
),
314338
title: Text(p.name),
315339
subtitle: Text(
316-
p.desc + " Last Modified: " + p.dateModified.toString()),
340+
(p.type == HistoryItemType.solution? p.solution!.desc : "")
341+
+ " Last Modified: " + p.dateModified.toString()),
317342
trailing: PopupMenuButton<String>(
318343
onSelected: (String result) {
319344
switch (result) {
320345
case "delete":
321-
showDialog(
322-
context: context,
323-
builder: (BuildContext context) {
324-
return AlertDialog(
325-
title: Text("Delete ${p.name}?"),
326-
content: Text(
327-
"This action cannot be undone!\n folders will be deleted: ${() {
328-
String result = "";
329-
for (var folder in p.folders.keys) {
330-
result +=
331-
(p.folders[folder] as String) + ", \n";
332-
}
333-
return result;
334-
}()}"),
335-
actions: [
336-
TextButton(
337-
onPressed: () {
338-
Navigator.pop(context);
339-
},
340-
child: const Text("No")),
341-
TextButton(
342-
onPressed: () {
343-
var folders = <String>[];
344-
for (var folder in p.folders.keys) {
345-
folders.add(p.slnFolderPath +
346-
Platform.pathSeparator +
347-
p.folders[folder]!);
346+
if(p.type == HistoryItemType.solution) {
347+
showDialog(
348+
context: context,
349+
builder: (BuildContext context) {
350+
return AlertDialog(
351+
title: Text("Delete ${p.name}?"),
352+
content: Text(
353+
"This action cannot be undone!\n folders will be deleted: ${() {
354+
String result = "";
355+
for (var folder in p.solution!.folders.keys) {
356+
result +=
357+
(p.solution!.folders[folder] as String) +
358+
", \n";
348359
}
349-
deleteFolderWithIndicator(
350-
context, folders);
351-
// Delete the solution file too
352-
File(p.slnPath).deleteSync();
353-
354-
// Quit and refresh
355-
Navigator.pop(context);
356-
refreshRecentProjects();
357-
},
358-
child: const Text(
359-
"Delete",
360-
style:
361-
TextStyle(color: Colors.redAccent),
362-
)),
363-
],
364-
);
365-
});
360+
return result;
361+
}()}"),
362+
actions: [
363+
TextButton(
364+
onPressed: () {
365+
Navigator.pop(context);
366+
},
367+
child: const Text("No")),
368+
TextButton(
369+
onPressed: () {
370+
var folders = <String>[];
371+
for (var folder in p.solution!.folders.keys) {
372+
folders.add(p.solution!.slnFolderPath +
373+
Platform.pathSeparator +
374+
p.solution!.folders[folder]!);
375+
}
376+
deleteFolderWithIndicator(
377+
context, folders);
378+
// Delete the solution file too
379+
File(p.solution!.slnPath).deleteSync();
380+
381+
// Quit and refresh
382+
Navigator.pop(context);
383+
refreshRecentProjects();
384+
},
385+
child: const Text(
386+
"Delete",
387+
style:
388+
TextStyle(color: Colors.redAccent),
389+
)),
390+
],
391+
);
392+
});
393+
}else{
394+
//TODO: Handle single file delete
395+
}
366396
break;
367397
}
368398
},

lib/main.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import 'dart:io';
2+
13
import 'package:corecoder_develop/editor.dart';
24
import 'package:corecoder_develop/plugins_browser.dart';
35
import 'package:corecoder_develop/settings.dart';
46
import 'package:corecoder_develop/util/theme_manager.dart';
57
import 'package:flutter/material.dart';
8+
import 'package:flutter/services.dart';
69
import 'package:provider/provider.dart';
710
import 'package:provider/single_child_widget.dart';
811
import 'homepage.dart';
@@ -25,13 +28,23 @@ class CoreCoderApp extends StatefulWidget {
2528
class CoreCoderAppState extends State<CoreCoderApp>{
2629
String themeName = "core-coder-dark";
2730
@override
28-
void initState(){
31+
void initState() {
2932
super.initState();
3033
ThemeManager.currentTheme.addListener(() {
3134
setState(() {
3235
themeName = ThemeManager.currentTheme.value;
3336
});
3437
});
38+
if(Platform.isWindows) {
39+
/// On windows, get the runtime arguments
40+
/// this is provided by windows when you "Open with" CoreCoder
41+
/// the result is a string to the absolute path of the file
42+
/// then handle the filepath to open
43+
MethodChannel channel = const MethodChannel('corecoder_develop');
44+
channel.invokeMethod('getRunArgs').then((result) async {
45+
debugPrint(result as String);
46+
});
47+
}
3548
}
3649

3750
@override

windows/runner/flutter_window.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
#include "flutter/generated_plugin_registrant.h"
66
using namespace std;
7+
8+
using flutter::EncodableList;
9+
using flutter::EncodableMap;
10+
using flutter::EncodableValue;
11+
712
FlutterWindow::FlutterWindow(const flutter::DartProject& project, std::string run_args)
813
: project_(project), run_argument(run_args) {}
914

1015
FlutterWindow::~FlutterWindow() {}
11-
void initMethodChannel(flutter::FlutterEngine* flutter_instance);
1216
bool FlutterWindow::OnCreate() {
1317
if (!Win32Window::OnCreate()) {
1418
return false;
@@ -62,24 +66,22 @@ FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
6266
}
6367

6468

65-
void initMethodChannel(flutter::FlutterEngine* flutter_instance) {
69+
void FlutterWindow::initMethodChannel(flutter::FlutterEngine* flutter_instance) {
6670
// name your channel
67-
const static std::string channel_name("test_channel");
71+
const static std::string channel_name("corecoder_develop");
6872

6973
auto channel =
7074
std::make_unique<flutter::MethodChannel<>>(
7175
flutter_instance->messenger(), channel_name,
7276
&flutter::StandardMethodCodec::GetInstance());
73-
7477
channel->SetMethodCallHandler(
75-
[](const flutter::MethodCall<>& call,
78+
[this](const flutter::MethodCall<>& call,
7679
std::unique_ptr<flutter::MethodResult<>> result) {
7780

7881
// cheack method name called from dart
79-
if (call.method_name().compare("test") == 0) {
82+
if (call.method_name().compare("getRunArgs") == 0) {
8083
// do whate ever you want
81-
82-
result->Success("pass result here");
84+
result->Success(EncodableValue(run_argument.c_str()));
8385
}
8486
else {
8587
result->NotImplemented();

windows/runner/flutter_window.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class FlutterWindow : public Win32Window {
2525
// Win32Window:
2626
bool OnCreate() override;
2727
void OnDestroy() override;
28+
void initMethodChannel(flutter::FlutterEngine* flutter_instance);
2829
LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
2930
LPARAM const lparam) noexcept override;
3031

0 commit comments

Comments
 (0)