Merge branch 'main' into feat/workspaces
commit
40dad9e212
|
@ -20,12 +20,6 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.14.7"
|
||||
|
@ -68,12 +62,6 @@ dependencies = [
|
|||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "echidna"
|
||||
version = "0.1.0"
|
||||
|
@ -87,7 +75,6 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sourceview5",
|
||||
"webbrowser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -438,36 +425,12 @@ version = "0.4.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
|
@ -843,87 +806,6 @@ version = "0.9.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webbrowser"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a"
|
||||
dependencies = [
|
||||
"web-sys",
|
||||
"widestring",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "echidna"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
@ -14,5 +14,4 @@ serde = { version = "^1.0.130", features = ["derive"] }
|
|||
relative-path = "^1.5.0"
|
||||
gdk = { version = "^0.3.0", package = "gdk4"}
|
||||
sourceview = { package = "sourceview5", version = "^0.1.0", git = "https://github.com/EchidnaHQ/sourceview" }
|
||||
webbrowser = { version = "^0.5.5" }
|
||||
once_cell = "1"
|
|
@ -67,7 +67,7 @@ impl EchidnaCoreEditor {
|
|||
|_, _| {},
|
||||
|result| {
|
||||
if result.is_err() {
|
||||
panic!(result.err());
|
||||
panic!("Found an error when loading the file into the text editor's buffer. {:#?}", result.err());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
pub mod app;
|
||||
pub mod editor;
|
||||
pub mod sidebar;
|
||||
pub mod tab_label;
|
||||
pub mod window;
|
||||
|
||||
pub use app::EchidnaEditor;
|
||||
pub use editor::EchidnaCoreEditor;
|
||||
pub use sidebar::EchidnaSidebar;
|
||||
pub use tab_label::TabLabel;
|
||||
pub use window::EchidnaWindow;
|
||||
|
||||
pub mod prelude {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::CompositeTemplate;
|
||||
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
#[template(file = "./tab-label.ui")]
|
||||
pub struct TabLabel {
|
||||
#[template_child]
|
||||
pub button: TemplateChild<gtk::Button>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for TabLabel {
|
||||
const NAME: &'static str = "TabLabel";
|
||||
type Type = super::TabLabel;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
Self::bind_template(klass);
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for TabLabel {}
|
||||
impl WidgetImpl for TabLabel {}
|
||||
impl BoxImpl for TabLabel {}
|
||||
|
||||
impl BuildableImpl for TabLabel {
|
||||
fn add_child(
|
||||
&self,
|
||||
buildable: &Self::Type,
|
||||
builder: >k::Builder,
|
||||
child: &glib::Object,
|
||||
type_: Option<&str>,
|
||||
) {
|
||||
buildable.prepend(child.downcast_ref::<gtk::Widget>().unwrap());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pub mod imp;
|
||||
use glib::IsA;
|
||||
use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::*;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct TabLabel(ObjectSubclass<imp::TabLabel>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||
}
|
||||
|
||||
impl TabLabel {
|
||||
pub fn new<U: IsA<gtk::Widget>>(tab_label: Option<&U>) -> Self {
|
||||
let this: Self = glib::Object::new(&[]).expect("Failed to create 'TabLabel' component.");
|
||||
|
||||
if tab_label.is_some() {
|
||||
this.prepend(tab_label.unwrap());
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
pub fn to_imp(&self) -> &imp::TabLabel {
|
||||
imp::TabLabel::from_instance(self)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="4.5.0" />
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
<template class="TabLabel">
|
||||
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="has-frame">0</property>
|
||||
<property name="icon-name">window-close-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
|
@ -8,7 +8,7 @@ use crate::components::editor::EchidnaCoreEditor;
|
|||
use gio::Cancellable;
|
||||
use glib::{clone, Priority};
|
||||
use gtk::{
|
||||
prelude::*, subclass::prelude::*, FileChooserAction, FileChooserDialog, Label, ResponseType,
|
||||
prelude::*, subclass::prelude::*, FileChooserAction, FileChooserNative, Label, ResponseType,
|
||||
};
|
||||
use sourceview::{prelude::*, Buffer, File, FileSaver};
|
||||
|
||||
|
@ -36,14 +36,12 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files.
|
||||
*/
|
||||
fn action_open_file(&self) {
|
||||
let dialog: FileChooserDialog = FileChooserDialog::new(
|
||||
let dialog = FileChooserNative::new(
|
||||
Some("Open a file"),
|
||||
Some(self),
|
||||
FileChooserAction::Open,
|
||||
&[
|
||||
("Cancel", ResponseType::Cancel),
|
||||
("Open", ResponseType::Accept),
|
||||
],
|
||||
Some("Open"),
|
||||
Some("Cancel"),
|
||||
);
|
||||
|
||||
dialog.set_visible(true);
|
||||
|
@ -81,14 +79,12 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
}
|
||||
|
||||
fn action_save_file_as(&self) {
|
||||
let dialog = FileChooserDialog::new(
|
||||
let dialog = FileChooserNative::new(
|
||||
Some("Save File As"),
|
||||
Some(self),
|
||||
FileChooserAction::Save,
|
||||
&[
|
||||
("Cancel", ResponseType::Cancel),
|
||||
("Save", ResponseType::Accept),
|
||||
],
|
||||
Some("Open"),
|
||||
Some("Cancel"),
|
||||
);
|
||||
|
||||
dialog.set_current_name("untitled");
|
||||
|
@ -114,7 +110,7 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
"Couldn't get the page of the current index. Try again."
|
||||
).downcast::<EchidnaCoreEditor>() {
|
||||
Ok(res) => page = res,
|
||||
Err(e) => panic!(format!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e))
|
||||
Err(e) => panic!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)
|
||||
}
|
||||
|
||||
let buffer: Buffer = page.to_imp().sourceview.buffer().downcast().expect("Could not downcast the editor's buffer to GtkSourceBuffer.");
|
||||
|
@ -129,7 +125,7 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
|_, _| {},
|
||||
|result| {
|
||||
if result.is_err() {
|
||||
panic!(format!("Found an error while saving the file:\n{}", result.err().expect("No error")))
|
||||
panic!("Found an error while saving the file:\n{}", result.err().expect("No error"))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ impl MenubarImplementedEditor for EchidnaWindow {
|
|||
|
||||
about_dialog.set_license_type(gtk::License::Mpl20);
|
||||
about_dialog.set_program_name(Some("Echidna Code Editor"));
|
||||
about_dialog.set_website(Some("https://github.com/EchidnaHQ/Echidna"));
|
||||
about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna"));
|
||||
about_dialog.set_authors(&["FortressValkriye"]);
|
||||
about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors"));
|
||||
about_dialog.set_visible(true);
|
||||
|
@ -78,18 +78,20 @@ impl MenubarImplementedEditor for EchidnaWindow {
|
|||
|
||||
app.add_action(&act_report_issue);
|
||||
|
||||
act_report_issue.connect_activate(|_action, _variant| {
|
||||
webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues/new");
|
||||
});
|
||||
act_report_issue.connect_activate(clone!(@weak self as win =>
|
||||
move |_action, _variant| {
|
||||
gtk::show_uri(Some(&win), "https://github.com/EchidnaHQ/Echidna/issues/new", gdk::CURRENT_TIME);
|
||||
}));
|
||||
}
|
||||
{
|
||||
let act_search_feature_requests = SimpleAction::new("search-feature-requests", None);
|
||||
|
||||
app.add_action(&act_search_feature_requests);
|
||||
|
||||
act_search_feature_requests.connect_activate(|_action, _variant| {
|
||||
webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement");
|
||||
});
|
||||
act_search_feature_requests.connect_activate(clone!(@weak self as win =>
|
||||
move |_action, _variant| {
|
||||
gtk::show_uri(Some(&win), "https://github.com/EchidnaHQ/Echidna/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement", gdk::CURRENT_TIME);
|
||||
}));
|
||||
}
|
||||
{
|
||||
let act_window_close = SimpleAction::new("close", None);
|
||||
|
|
|
@ -7,10 +7,7 @@ use gio::{File, FileQueryInfoFlags, FileType, SimpleAction};
|
|||
use glib::clone;
|
||||
use glib::types::Type;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{
|
||||
Application, ApplicationWindow, FileChooserAction, FileChooserDialog, ResponseType, TreeStore,
|
||||
TreeView,
|
||||
};
|
||||
use gtk::{ApplicationWindow, FileChooserAction, FileChooserNative, ResponseType, TreeStore};
|
||||
use relative_path::RelativePath;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
|
@ -47,14 +44,12 @@ impl WorkspaceImplementedEditor for EchidnaWindow {
|
|||
_action: &SimpleAction,
|
||||
_variant: Option<&glib::Variant>,
|
||||
) {
|
||||
let dialog: FileChooserDialog = FileChooserDialog::new(
|
||||
let dialog = FileChooserNative::new(
|
||||
Some("Open a file"),
|
||||
Some(&window),
|
||||
FileChooserAction::Open,
|
||||
&[
|
||||
("Cancel", ResponseType::Cancel),
|
||||
("Open", ResponseType::Accept),
|
||||
],
|
||||
Some("Open"),
|
||||
Some("Cancel"),
|
||||
);
|
||||
dialog.set_visible(true);
|
||||
dialog.connect_response(clone!(@weak self as win =>
|
||||
|
@ -79,7 +74,7 @@ impl WorkspaceImplementedEditor for EchidnaWindow {
|
|||
*
|
||||
* Basically, this is just the same as Open Folder, but it's many folders.
|
||||
*
|
||||
* - Open a FileChooserDialog, set to only view .code-workspace files.
|
||||
* - Open a FileChooserNative, set to only view .code-workspace files.
|
||||
* - If the user pressed cancel, destroy the dialog. If the user opened a .code-workspace file:
|
||||
* - Get the workspace file, load and parse its content, .code-workspace files are in JSON with comments. But JSON only should be fine, for now.
|
||||
* - Iterate over folders listed in the workspace file.
|
||||
|
@ -127,7 +122,6 @@ impl WorkspaceImplementedEditor for EchidnaWindow {
|
|||
*/
|
||||
fn recursive_add_files_into_tree_store(&self, parent_file: File, tree: &TreeStore) {
|
||||
let child_enumerate_cancellable = Cancellable::new();
|
||||
|
||||
let child_files = parent_file
|
||||
.enumerate_children(
|
||||
"*",
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::components::tab_label::TabLabel;
|
||||
use glib::IsA;
|
||||
use gtk::{prelude::*, Box, Button, Widget};
|
||||
|
||||
|
@ -16,39 +17,24 @@ pub trait ClosableTabImplementedNotebook {
|
|||
child: &T,
|
||||
tab_label: Option<&U>,
|
||||
) -> u32;
|
||||
|
||||
fn create_closable_tab<U: IsA<Widget>>(tab_label: Option<&U>) -> (Box, Button);
|
||||
}
|
||||
|
||||
impl ClosableTabImplementedNotebook for gtk::Notebook {
|
||||
fn create_closable_tab<U: IsA<Widget>>(tab_label: Option<&U>) -> (Box, Button) {
|
||||
let tab = Box::new(gtk::Orientation::Horizontal, 5);
|
||||
if tab_label.is_some() {
|
||||
tab.append(tab_label.unwrap());
|
||||
}
|
||||
|
||||
let button = gtk::Button::new();
|
||||
|
||||
button.set_icon_name("window-close-symbolic");
|
||||
button.set_has_frame(false);
|
||||
|
||||
tab.append(&button);
|
||||
|
||||
(tab, button)
|
||||
}
|
||||
|
||||
fn prepend_closable_page<T: IsA<Widget>, U: IsA<Widget>>(
|
||||
&self,
|
||||
child: &T,
|
||||
tab_label: Option<&U>,
|
||||
) -> u32 {
|
||||
let (tab, button) = &Self::create_closable_tab(tab_label);
|
||||
let page = self.prepend_page(child, Some(tab));
|
||||
let tab_label_widget = TabLabel::new(tab_label);
|
||||
let page = self.prepend_page(child, Some(&tab_label_widget));
|
||||
|
||||
button.connect_clicked(glib::clone!(@weak self as notebook =>
|
||||
move |_| {
|
||||
notebook.remove_page(Some(page));
|
||||
}));
|
||||
tab_label_widget
|
||||
.to_imp()
|
||||
.button
|
||||
.connect_clicked(glib::clone!(@weak self as notebook =>
|
||||
move |_| {
|
||||
notebook.remove_page(Some(page));
|
||||
}));
|
||||
|
||||
page
|
||||
}
|
||||
|
@ -58,13 +44,16 @@ impl ClosableTabImplementedNotebook for gtk::Notebook {
|
|||
child: &T,
|
||||
tab_label: Option<&U>,
|
||||
) -> u32 {
|
||||
let (tab, button) = &Self::create_closable_tab(tab_label);
|
||||
let page = self.append_page(child, Some(tab));
|
||||
let tab_label_widget = TabLabel::new(tab_label);
|
||||
let page = self.append_page(child, Some(&tab_label_widget));
|
||||
|
||||
button.connect_clicked(glib::clone!(@weak self as notebook =>
|
||||
move |_| {
|
||||
notebook.remove_page(Some(page));
|
||||
}));
|
||||
tab_label_widget
|
||||
.to_imp()
|
||||
.button
|
||||
.connect_clicked(glib::clone!(@weak self as notebook =>
|
||||
move |_| {
|
||||
notebook.remove_page(Some(page));
|
||||
}));
|
||||
|
||||
page
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue