Skip to content

Commit

Permalink
Implement secondary progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Zerthox committed Dec 23, 2024
1 parent 609e12c commit 8bfa658
Show file tree
Hide file tree
Showing 12 changed files with 454 additions and 197 deletions.
13 changes: 7 additions & 6 deletions reffect/src/addon/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ impl Addon {
pub fn unload() {
log::info!("Reffect v{VERSION} unload");

{
let plugin = Self::lock();
AddonSettings::new(&plugin.context).save();
if plugin.context.settings.save_on_unload {
plugin.save_packs();
}
let plugin = Self::lock();
AddonSettings::new(&plugin.context).save();
if plugin.context.settings.save_on_unload {
plugin.save_packs();
}
drop(plugin);

Internal::deinit();

TextureManager::unload();
}
Expand Down
19 changes: 15 additions & 4 deletions reffect/src/elements/bar/progress.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{context::Context, trigger::ProgressActive};
use crate::{
context::Context,
trigger::{ProgressActive, ProgressValue},
};
use serde::{Deserialize, Serialize};
use strum::{AsRefStr, EnumIter, VariantArray};

Expand All @@ -19,29 +22,37 @@ use strum::{AsRefStr, EnumIter, VariantArray};
Deserialize,
)]
pub enum Progress {
Intensity,

#[default]
Duration,
Intensity,

#[strum(serialize = "Secondary Duration")]
SecondaryDuration,
}

impl Progress {
pub fn calc_progress(&self, ctx: &Context, active: &ProgressActive, max: u32) -> f32 {
match self {
Self::Duration => active.progress_or_default(ctx.now),
Self::Intensity => {
if max > 0 {
active.intensity() as f32 / max as f32
} else {
0.0
}
}
Self::Duration => active.progress_or_default(ProgressValue::Primary, ctx.now),
Self::SecondaryDuration => {
active.progress_or_default(ProgressValue::Secondary, ctx.now)
}
}
}

pub fn progress_max(&self, active: &ProgressActive, max: u32) -> u32 {
match self {
Self::Duration => active.max(),
Self::Intensity => max,
Self::Duration => active.max(ProgressValue::Primary),
Self::SecondaryDuration => active.max(ProgressValue::Secondary),
}
}
}
8 changes: 4 additions & 4 deletions reffect/src/elements/icon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
},
render_util::{debug_optional, draw_spinner_bg, draw_text_bg, Rect},
settings::icon::{DurationBarSettings, DurationTextSettings, StackTextSettings},
trigger::ProgressActive,
trigger::{ProgressActive, ProgressValue},
};
use nexus::imgui::Ui;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Icon {

// render duration bar
if self.duration_bar {
if let Some(progress) = active.progress(ctx.now) {
if let Some(progress) = active.progress(ProgressValue::Secondary, ctx.now) {
let DurationBarSettings { height, color } = ctx.settings.icon.duration_bar;

let [start_x, _] = start;
Expand Down Expand Up @@ -146,7 +146,7 @@ impl Icon {

// render duration text
if self.duration_text {
if let Some(remain) = active.current(ctx.now) {
if let Some(remain) = active.current(ProgressValue::Primary, ctx.now) {
let DurationTextSettings {
max_remain,
scale,
Expand All @@ -157,7 +157,7 @@ impl Icon {
} = ctx.settings.icon.duration_text;

if remain < max_remain {
let text = active.current_text(ctx.now, false);
let text = active.current_text(ProgressValue::Primary, ctx.now, false);

let font_size = scale * small_size;
let font_scale = font_size / ui.current_font_size();
Expand Down
143 changes: 95 additions & 48 deletions reffect/src/elements/text/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
mod decoration;
mod props;

pub use self::{decoration::*, props::*};

use super::{align::AlignHorizontal, Props, RenderState};
use crate::{
context::{Context, ContextUpdate},
Expand All @@ -12,10 +10,13 @@ use crate::{
debug_optional, draw_text_bg, helper, input_text_multi_with_menu, LoadedFont, Rect,
},
tree::TreeNode,
trigger::ProgressActive,
trigger::{ProgressActive, ProgressValue},
};
use nexus::imgui::{InputTextFlags, Ui};
use serde::{Deserialize, Serialize};
use std::{iter::Peekable, str::Chars};

pub use self::{decoration::*, props::*};

#[derive(Debug, Serialize, Deserialize)]
#[serde(default)]
Expand Down Expand Up @@ -47,6 +48,10 @@ impl Text {
}
}

pub fn load(&mut self) {
self.font.reload();
}

fn process_text(
&mut self,
active: &ProgressActive,
Expand All @@ -57,55 +62,105 @@ impl Text {

let mut result = String::with_capacity(self.text.len()); // always same or larger size

let mut prefix = false;
let is_timed = active.is_timed();
for el in self.text.chars() {
if prefix {
prefix = false;
match el {
'n' => result.push_str(&state.common.name),
'i' | 's' => result.push_str(&active.intensity().to_string()),
'I' => result.push_str(&Pretty(active.intensity()).to_string()),
'c' | 'r' => {
result.push_str(&active.current_text(ctx.now, false));
self.frequent = is_timed;
}
'C' => {
result.push_str(&active.current_text(ctx.now, true));
self.frequent = is_timed;
}
'f' => result.push_str(&active.max_text(false)),
'F' => result.push_str(&active.max_text(true)),
'p' | 'P' => {
let progress = active.progress_or_default(ctx.now);
result.push_str(&format!("{:.1}", (100.0 * progress)));
self.frequent = is_timed;
}
PREFIX => result.push(PREFIX),
other => {
result.push(PREFIX);
result.push(other);
let mut iter = self.text.chars().peekable();
while let Some(el) = iter.next() {
if el == PREFIX {
if let Some(next) = iter.peek() {
match next {
'n' => {
iter.next();
result.push_str(&state.common.name);
}
'i' | 's' => {
iter.next();
result.push_str(&active.intensity().to_string());
}
'I' => {
iter.next();
result.push_str(&Pretty(active.intensity()).to_string());
}
'c' | 'r' => {
iter.next();
result.push_str(&active.current_text(
Self::parse_value(&mut iter),
ctx.now,
false,
));
self.frequent = is_timed;
}
'C' => {
iter.next();
result.push_str(&active.current_text(
Self::parse_value(&mut iter),
ctx.now,
true,
));
self.frequent = is_timed;
}
'f' => {
iter.next();
result.push_str(&active.max_text(Self::parse_value(&mut iter), false));
}
'F' => {
iter.next();
result.push_str(&active.max_text(Self::parse_value(&mut iter), true));
}
'p' | 'P' => {
iter.next();
let progress =
active.progress_or_default(Self::parse_value(&mut iter), ctx.now);
result.push_str(&format!("{:.1}", (100.0 * progress)));
self.frequent = is_timed;
}
&PREFIX => {
iter.next();
result.push(PREFIX);
}
_ => {
result.push(PREFIX);
}
}
} else {
result.push(el);
}
} else if el == PREFIX {
prefix = true;
} else {
result.push(el);
}
}
if prefix {
result.push(PREFIX); // handle ending prefix
}

result
}

fn calc_offset(&self, ui: &Ui, text: &str) -> [f32; 2] {
self.align.text_offset(ui, text, self.props.scale)
fn parse_value(iter: &mut Peekable<Chars>) -> ProgressValue {
match iter.peek() {
Some('1') => {
iter.next();
ProgressValue::Primary
}
Some('2') => {
iter.next();
ProgressValue::Secondary
}
_ => ProgressValue::Primary,
}
}

pub fn load(&mut self) {
self.font.reload();
fn helper(ui: &Ui) {
helper(ui, || {
ui.text("Uppercase for pretty format");
ui.text("Suffix 1 or 2 for primary/secondary");
ui.text("%n for name");
ui.text("%i for intensity");
ui.text("%c for current amount");
ui.text("%f for full/max amount");
ui.text("%p for progress percent");
ui.text("%% for % sign");
});
}

fn calc_offset(&self, ui: &Ui, text: &str) -> [f32; 2] {
self.align.text_offset(ui, text, self.props.scale)
}
}

Expand Down Expand Up @@ -158,15 +213,7 @@ impl RenderOptions for Text {

ui.same_line();
ui.text("Text"); // own label to fix helper position
helper(ui, || {
ui.text("Uppercase for pretty format");
ui.text("%n for name");
ui.text("%i for intensity");
ui.text("%c for current amount");
ui.text("%f for full/max amount");
ui.text("%p for progress percent");
ui.text("%% for % sign");
});
Self::helper(ui);

self.align.render_combo(ui);

Expand Down
Loading

0 comments on commit 8bfa658

Please sign in to comment.