Init.
This commit is contained in:
commit
4d092d56a5
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
/.debug
|
||||
/.vscode
|
||||
4338
Cargo.lock
generated
Normal file
4338
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "poe2-loot-filter-iced"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
config = "0.15.4"
|
||||
iced = "0.13.1"
|
||||
itertools = "0.13.0"
|
||||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
serde_json = "1.0.134"
|
||||
strum_macros = "0.26.4"
|
||||
8
config/settings.json
Normal file
8
config/settings.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"base_types": [],
|
||||
"classes": ["Bows"],
|
||||
"rarities": ["Normal", "Magic", "Rare", "Unique"],
|
||||
"minimap_icon_shapes": ["Red", "Green", "Blue", "Brown", "White", "Yellow", "Cyan", "Grey", "Orange", "Pink", "Purple"],
|
||||
"game_colors": ["Circle", "Diamond", "Hexagon", "Square", "Star", "Triangle", "Cross", "Moon", "Raindrop", "Kite", "Pentagon", "UpsideDownHouse"],
|
||||
"ops": ["=", "!=", "<", "<=", ">", ">="]
|
||||
}
|
||||
23
src/components/app.rs
Normal file
23
src/components/app.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use iced::widget::{container, text, Container, column};
|
||||
|
||||
use crate::models::{FilterConfig, FilterText, Settings};
|
||||
|
||||
pub struct App {
|
||||
pub settings: Settings,
|
||||
pub filter_config: FilterConfig
|
||||
}
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
}
|
||||
impl App {
|
||||
pub fn view(&self) -> Container<Message> {
|
||||
container(column![
|
||||
text(format!("{:?}", &self.settings)),
|
||||
text(format!("{:?}", &self.filter_config.to_filter_text()))
|
||||
]).padding(8)
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) {
|
||||
|
||||
}
|
||||
}
|
||||
3
src/components/mod.rs
Normal file
3
src/components/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod app;
|
||||
|
||||
pub use app::*;
|
||||
21
src/main.rs
Normal file
21
src/main.rs
Normal file
@ -0,0 +1,21 @@
|
||||
mod models;
|
||||
mod components;
|
||||
|
||||
use components::App;
|
||||
use iced::{Size, Task, Theme};
|
||||
use models::Settings;
|
||||
use config::Config;
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
let settings = Config::builder()
|
||||
.add_source(config::File::with_name("config/settings.json"))
|
||||
.build().unwrap().try_deserialize::<Settings>().unwrap();
|
||||
iced::application("POE2 Loot Filter Config Tools", App::update, App::view)
|
||||
.theme(|_| Theme::GruvboxDark)
|
||||
.window_size(Size::new(1920.0 / 2., 1080.0 / 2.))
|
||||
.centered()
|
||||
.run_with(|| (App {
|
||||
settings: settings,
|
||||
filter_config: vec![]
|
||||
}, Task::none()))
|
||||
}
|
||||
19
src/models/base.rs
Normal file
19
src/models/base.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct RangedNumber<const MIN: u32, const MAX: u32>(u32);
|
||||
|
||||
impl<const MIN: u32, const MAX: u32> RangedNumber<MIN, MAX> {
|
||||
pub fn new(value: u32) -> Result<Self, String> {
|
||||
if value < MIN || value > MAX {
|
||||
Err(format!("Value {} is out of range ({} - {})", value, MIN, MAX))
|
||||
} else {
|
||||
Ok(RangedNumber(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn min() -> u32 {MIN}
|
||||
pub fn max() -> u32 {MAX}
|
||||
|
||||
pub fn value(&self) -> u32 {self.0}
|
||||
}
|
||||
51
src/models/filter_text.rs
Normal file
51
src/models/filter_text.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use super::{Color, Filter, FilterConfig, Line};
|
||||
|
||||
pub trait FilterText {
|
||||
fn to_filter_text(&self) -> String;
|
||||
}
|
||||
|
||||
impl FilterText for FilterConfig {
|
||||
fn to_filter_text(&self) -> String {
|
||||
self.filters.iter().rev()
|
||||
.map(|filter| {filter.to_filter_text()})
|
||||
.collect::<Vec<_>>().join("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Filter {
|
||||
fn to_filter_text(&self) -> String {
|
||||
let head = if self.show {"Show"} else {"Hide"};
|
||||
head.to_owned() + "\n" + &self.lines.iter().map(|line| {line.to_filter_text()})
|
||||
.collect::<Vec<_>>().join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Line {
|
||||
fn to_filter_text(&self) -> String {
|
||||
match self {
|
||||
Line::Class(item_class) => format!("Class {}", item_class.iter().map(|item| format!(r#""{}""#, item.value())).collect::<Vec<_>>().join(" ")),
|
||||
Line::BaseType(item_base_type) => format!("BaseType {}", item_base_type.iter().map(|item| format!(r#""{}""#, item.value())).collect::<Vec<_>>().join(" ")),
|
||||
Line::AreaLevel(op, level) => format!("AreaLevel {} {}", op.value(), level.value()),
|
||||
Line::DropLevel(op, level) => format!("DropLevel {} {}", op.value(), level.value()),
|
||||
Line::ItemLevel(op, level) => format!("ItemLevel {} {}", op.value(), level.value()),
|
||||
Line::Rarity(op, item_rarity) => format!("Rarity {} {}", op.value(), item_rarity.value()),
|
||||
Line::Sockets(op, i) => format!("Sockets {} {}", op.value(), i),
|
||||
Line::Quality(op, i) => format!("Quality {} {}", op.value(), i),
|
||||
Line::StackSize(op, i) => format!("StackSize {} {}", op.value(), i),
|
||||
Line::WaystoneTier(op, waystone_tier) => format!("WaystoneTier {} {}", op.value(), waystone_tier.value()),
|
||||
Line::SetFontSize(font_size) => format!("SetFontSize {}", font_size.value()),
|
||||
Line::SetTextColor(color) => format!("SetTextColor {}", color.to_filter_text()),
|
||||
Line::SetBorderColor(color) => format!("SetBorderColor {}", color.to_filter_text()),
|
||||
Line::SetBackgroundColor(color) => format!("SetBackgroundColor {}", color.to_filter_text()),
|
||||
Line::PlayAlertSound(alert_sound_id, alert_sound_volume) => format!("PlayAlertSound {} {}", alert_sound_id.value(), alert_sound_volume.value()),
|
||||
Line::PlayEffect(game_color) => format!("PlayEffect {}", game_color.value()),
|
||||
Line::MinimapIcon(minimap_icon_size, game_color, minimap_icon_shape) => format!("MinimapIcon {} {} {}", minimap_icon_size.value(), game_color.value(), minimap_icon_shape.value()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Color {
|
||||
fn to_filter_text(&self) -> String {
|
||||
format!("{} {} {} {}", self.r, self.g, self.b, self.a)
|
||||
}
|
||||
}
|
||||
152
src/models/loot_filter.rs
Normal file
152
src/models/loot_filter.rs
Normal file
@ -0,0 +1,152 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::base::RangedNumber;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FilterConfig {
|
||||
pub filters: Vec<Filter>,
|
||||
test: dyn Test
|
||||
}
|
||||
|
||||
trait Test: std::fmt::Debug {}
|
||||
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Filter {
|
||||
pub show: bool,
|
||||
pub lines: Vec<Line>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Color {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
pub b: u8,
|
||||
pub a: u8,
|
||||
}
|
||||
|
||||
pub type Level = RangedNumber<1, 100>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum Line {
|
||||
Class(Vec<ItemClass>),
|
||||
BaseType(Vec<ItemBaseType>),
|
||||
AreaLevel(Op, Level),
|
||||
DropLevel(Op, Level),
|
||||
ItemLevel(Op, Level),
|
||||
Rarity(Op, ItemRarity),
|
||||
Sockets(Op, u32),
|
||||
Quality(Op, u32),
|
||||
StackSize(Op, u32),
|
||||
|
||||
// waystones
|
||||
WaystoneTier(Op, RangedNumber<1, 16>),
|
||||
|
||||
// effects
|
||||
SetFontSize(RangedNumber<1, 45>),
|
||||
SetTextColor(Color),
|
||||
SetBorderColor(Color),
|
||||
SetBackgroundColor(Color),
|
||||
PlayAlertSound(RangedNumber<1, 16>, RangedNumber<0, 300>),
|
||||
PlayEffect(GameColor),
|
||||
MinimapIcon(RangedNumber<0, 2>, GameColor, MinimapIconShape),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Debug)]
|
||||
pub struct Settings {
|
||||
base_types: Vec<String>,
|
||||
classes: Vec<String>,
|
||||
rarities: Vec<String>,
|
||||
minimap_icon_shapes: Vec<String>,
|
||||
game_colors: Vec<String>,
|
||||
ops: Vec<String>,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
fn format_err(value: &str, category: &str, options: &Vec<String>) -> String {
|
||||
format!("{} is not a valid {}, options are: {}", value, category, options.iter().join(" "))
|
||||
}
|
||||
pub fn base_type(&self, s: &String) -> Result<ItemBaseType, String> {
|
||||
if self.base_types.contains(s) {
|
||||
Err(Self::format_err(s, "BaseType", &self.base_types))
|
||||
} else {
|
||||
Ok(ItemBaseType(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn class(&self, s: &String) -> Result<ItemClass, String> {
|
||||
if self.classes.contains(s) {
|
||||
Err(Self::format_err(s, "Class", &self.classes))
|
||||
} else {
|
||||
Ok(ItemClass(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn rarity(&self, s: &String) -> Result<ItemRarity, String> {
|
||||
if self.rarities.contains(s) {
|
||||
Err(Self::format_err(s, "Rarity", &self.rarities))
|
||||
} else {
|
||||
Ok(ItemRarity(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn op(&self, s: &String) -> Result<Op, String> {
|
||||
if self.ops.contains(s) {
|
||||
Err(Self::format_err(s, "Operator", &self.ops))
|
||||
} else {
|
||||
Ok(Op(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn minimap_icon_shape(&self, s: &String) -> Result<MinimapIconShape, String> {
|
||||
if self.minimap_icon_shapes.contains(s) {
|
||||
Err(Self::format_err(s, "MinimapIconShape", &self.minimap_icon_shapes))
|
||||
} else {
|
||||
Ok(MinimapIconShape(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn game_color(&self, s: &String) -> Result<GameColor, String> {
|
||||
if self.game_colors.contains(s) {
|
||||
Err(Self::format_err(s, "GameColor", &self.game_colors))
|
||||
} else {
|
||||
Ok(GameColor(s.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ItemBaseType(String);
|
||||
impl ItemBaseType {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ItemClass(String);
|
||||
impl ItemClass {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct ItemRarity(String);
|
||||
impl ItemRarity {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct MinimapIconShape(String);
|
||||
impl MinimapIconShape {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GameColor(String);
|
||||
impl GameColor {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Op(String);
|
||||
|
||||
impl Op {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
}
|
||||
7
src/models/mod.rs
Normal file
7
src/models/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
mod loot_filter;
|
||||
mod filter_text;
|
||||
mod base;
|
||||
|
||||
pub use loot_filter::*;
|
||||
pub use filter_text::*;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user