Skip to content

Commit

Permalink
make gui more awesome
Browse files Browse the repository at this point in the history
  • Loading branch information
tbillington committed Mar 6, 2020
1 parent 2eafa34 commit d9c62cf
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 70 deletions.
4 changes: 1 addition & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions kondo-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,19 +245,19 @@ pub fn pretty_size(size: u64) -> String {
}

pub fn clean(project_path: &str) -> Result<(), Box<dyn error::Error>> {
for p in match project_type_from_dir(project_path.into()) {
Some(p) => p,
None => return Ok(()),
} {
for ad in p
.artifact_dirs()
.map(|ad| path::PathBuf::from(project_path).join(ad))
.filter(|ad| ad.exists())
{
if let Err(e) = fs::remove_dir_all(&ad) {
eprintln!("error removing directory {:?}: {:?}", ad, e);
}
}
}
// for p in match project_type_from_dir(project_path.into()) {
// Some(p) => p,
// None => return Ok(()),
// } {
// for ad in p
// .artifact_dirs()
// .map(|ad| path::PathBuf::from(project_path).join(ad))
// .filter(|ad| ad.exists())
// {
// if let Err(e) = fs::remove_dir_all(&ad) {
// eprintln!("error removing directory {:?}: {:?}", ad, e);
// }
// }
// }
Ok(())
}
7 changes: 6 additions & 1 deletion kondo-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
druid = { git = "https://github.com/xi-editor/druid.git", branch = "controller", version = "0.5" }
#druid = { git = "https://github.com/xi-editor/druid.git", branch = "controller", version = "0.5" }
quote = "=1.0.2" # temporary for https://users.rust-lang.org/t/failure-derive-compilation-error/39062

[dependencies.druid]
path = "../../druid/druid"
version = "*"

[dependencies.kondo-lib]
path = "../kondo-lib"
Expand Down
158 changes: 106 additions & 52 deletions kondo-ui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use std::{env, sync::Arc, thread};

use druid::{
commands::{OPEN_FILE, SHOW_OPEN_PANEL},
widget::{Button, Container, Controller, ControllerHost, Flex, Label, List, Scroll, WidgetExt},
lens::{self, LensExt},
widget::{
Button, Container, Controller, ControllerHost, Flex, Label, List, Scroll, ViewSwitcher,
WidgetExt,
},
AppLauncher, BoxConstraints, Color, Command, Data, Env, Event, EventCtx, FileDialogOptions,
FileInfo, LayoutCtx, Lens, LifeCycle, LifeCycleCtx, LocalizedString, PaintCtx, Selector, Size,
UpdateCtx, Widget, WidgetPod, WindowDesc,
Expand All @@ -16,14 +20,29 @@ const CLEAN_PATH: Selector = Selector::new("event.clean-path");

struct EventHandler {}

type ItemData = (String, u64);
#[derive(Debug, Clone, Data, Lens)]
struct Project {
display: String,
path: String,
p_type: String,
artifact_size: u64,
non_artifact_size: u64,
dirs: Arc<Vec<(String, u64, bool)>>,
}

impl PartialEq for Project {
fn eq(&self, other: &Project) -> bool {
self.path.eq(&other.path)
}
}

#[derive(Debug, Clone, Data, Lens)]
struct AppData {
items: Arc<Vec<ItemData>>,
active_item: Option<ItemData>,
items: Arc<Vec<Project>>,
active_item: Option<Project>,
scan_dir: String,
total: u64,
artifact_size: u64,
non_artifact_size: u64,
saved: u64,
}

Expand All @@ -44,18 +63,19 @@ impl<W: Widget<AppData>> Controller<AppData, W> for EventHandler {
) {
match event {
Event::Command(cmd) if cmd.selector == ADD_ITEM => {
let new_elem = cmd.get_object::<ItemData>().unwrap().clone();
data.total += new_elem.1;
let project = cmd.get_object::<Project>().unwrap().clone();
data.artifact_size += project.artifact_size;
data.non_artifact_size += project.non_artifact_size;
let items = Arc::make_mut(&mut data.items);
let pos = items
.binary_search_by(|probe| new_elem.1.cmp(&probe.1))
.binary_search_by(|probe| project.artifact_size.cmp(&probe.artifact_size))
.unwrap_or_else(|e| e);
items.insert(pos, new_elem);
items.insert(pos, project);
ctx.request_layout();
ctx.request_paint();
}
Event::Command(cmd) if cmd.selector == SET_ACTIVE_ITEM => {
let active_item = cmd.get_object::<ItemData>().unwrap().clone();
let active_item = cmd.get_object::<Project>().unwrap().clone();
data.active_item = Some(active_item);
ctx.request_layout();
ctx.request_paint();
Expand All @@ -66,12 +86,12 @@ impl<W: Widget<AppData>> Controller<AppData, W> for EventHandler {
// );
}
Event::Command(cmd) if cmd.selector == CLEAN_PATH => {
let active_item = cmd.get_object::<ItemData>().unwrap().clone();
clean(&active_item.0).unwrap();
data.total -= active_item.1;
data.saved += active_item.1;
let active_item = cmd.get_object::<Project>().unwrap().clone();
clean(&active_item.path).unwrap();
data.artifact_size -= active_item.artifact_size;
data.saved += active_item.artifact_size;
let items = Arc::make_mut(&mut data.items);
let pos = items.binary_search_by(|probe| active_item.1.cmp(&probe.1));
let pos = items.binary_search_by(|probe| active_item.path.cmp(&probe.path));
if let Ok(pos) = pos {
items.remove(pos);
}
Expand All @@ -87,24 +107,6 @@ impl<W: Widget<AppData>> Controller<AppData, W> for EventHandler {
}
_child.event(ctx, event, data, _env);
}

// fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &AppData, _: &Env) {
// }

// fn update(&mut self, ctx: &mut UpdateCtx, old_data: &AppData, data: &AppData, _: &Env) {
// if !old_data.same(data) {
// ctx.request_paint()
// }
// }

// fn layout(&mut self, _: &mut LayoutCtx, bc: &BoxConstraints, _: &AppData, _: &Env) -> Size {
// self.children.widget.layout()
// // bc.max()
// }

// fn paint(&mut self, _ctx: &mut PaintCtx, _data: &AppData, _env: &Env) {
// self.children.widget.paint_with_offset(_ctx, _data, _env);
// }
}

fn main() {
Expand All @@ -116,28 +118,38 @@ fn main() {

let event_sink = launcher.get_external_handle();

let scan_dir = String::from(env::current_dir().unwrap().to_str().unwrap());
let mut cd = env::current_dir().unwrap();
cd.pop();
let scan_dir = String::from(cd.to_str().unwrap());
let scan_dir_len = scan_dir.len();

let sd2 = scan_dir.clone();

thread::spawn(move || {
scan(&sd2)
.filter_map(|p| match p.size() {
0 => None,
size => Some((p.name(), size)),
})
.for_each(|p| {
event_sink.submit_command(ADD_ITEM, p, None).unwrap();
});
scan(&sd2).for_each(|project| {
let project_size = project.size_dirs();
let name = project.name();

let project = Project {
display: name[scan_dir_len + 1..].to_string(),
path: name,
p_type: project.type_name().into(),
artifact_size: project_size.artifact_size,
non_artifact_size: project_size.non_artifact_size,
dirs: Arc::new(project_size.dirs),
};
event_sink.submit_command(ADD_ITEM, project, None).unwrap();
});
});

launcher
.use_simple_logger()
.launch(AppData {
items: Arc::new(vec![]),
items: Arc::new(Vec::new()),
active_item: None,
scan_dir,
total: 0,
artifact_size: 0,
non_artifact_size: 0,
saved: 0,
})
.expect("launch failed");
Expand All @@ -155,8 +167,10 @@ fn make_ui() -> impl Widget<AppData> {
root.add_child(
Label::new(|data: &AppData, _env: &_| {
format!(
"total: {} recovered: {}",
pretty_size(data.total),
"artifacts {} non-artifacts {} total {} recovered {}",
pretty_size(data.artifact_size),
pretty_size(data.non_artifact_size),
pretty_size(data.artifact_size + data.non_artifact_size),
pretty_size(data.saved)
)
})
Expand All @@ -169,13 +183,18 @@ fn make_ui() -> impl Widget<AppData> {
let l = Scroll::new(
List::new(|| {
Button::new(
|item: &ItemData, _env: &_| format!("{}: {}", item.0, pretty_size(item.1)),
|_ctx, data, _env| {
_ctx.submit_command(
Command::new(SET_ACTIVE_ITEM, (data.0.clone(), data.1)),
None,
|item: &Project, _env: &_| {
format!(
"{} ({}) {} / {}",
item.display,
item.p_type,
pretty_size(item.artifact_size),
pretty_size(item.artifact_size + item.non_artifact_size)
)
},
|_ctx, data, _env| {
_ctx.submit_command(Command::new(SET_ACTIVE_ITEM, data.clone()), None)
},
)
})
.lens(AppData::items)
Expand All @@ -197,11 +216,46 @@ fn make_ui() -> impl Widget<AppData> {
);
vert.add_child(
Label::new(|data: &AppData, _env: &_| match data.active_item {
Some((ref name, size)) => format!("{} {}", name, pretty_size(size)),
Some(ref project) => format!(
"{} {} / {}",
project.display,
pretty_size(project.artifact_size),
pretty_size(project.artifact_size + project.non_artifact_size)
),
None => String::from("none selected"),
}),
0.0,
);

let view_switcher = ViewSwitcher::new(
|data: &AppData, _env| data.active_item.clone(),
|selector, _env| match selector {
None => Box::new(Label::new("None")),
Some(project) => {
let project: &Project = project;
let mut l = Flex::column();
for (i, (dir_name, size, artifact)) in project.dirs.iter().enumerate() {
l.add_child(
Label::new(format!(
" {}─ {}{} {}",
if i == project.dirs.len() - 1 {
"└"
} else {
"├"
},
dir_name,
if *artifact { "🗑️" } else { "" },
pretty_size(*size)
)),
0.0,
);
}
Box::new(l)
}
},
);
vert.add_child(view_switcher, 0.0);

vert.add_child(
Button::new(
"Clean project of artifacts",
Expand Down

0 comments on commit d9c62cf

Please sign in to comment.