feat(colors): save own colors under the presets of the color popovers (Issue #56)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9dbe625eef
commit
bb9bb58790
4 files changed
+73
-5
No files matched your search
@@ -1485,6 +1485,7 @@ pub fn run_with(
|
|||||||
ui_state.set_eraser_radius_mm(ui_settings.eraser_radius_mm);
|
ui_state.set_eraser_radius_mm(ui_settings.eraser_radius_mm);
|
||||||
ui_state.math.set_enabled(ui_settings.math_assist);
|
ui_state.math.set_enabled(ui_settings.math_assist);
|
||||||
ui_state.touch_draw_enabled = ui_settings.touch_draw;
|
ui_state.touch_draw_enabled = ui_settings.touch_draw;
|
||||||
|
ui_state.saved_colors = ui_settings.saved_colors.clone();
|
||||||
ui_state.select_pen(ui_settings.active_pen);
|
ui_state.select_pen(ui_settings.active_pen);
|
||||||
ui_state.highlighter_colors = ui_settings.highlighter_colors;
|
ui_state.highlighter_colors = ui_settings.highlighter_colors;
|
||||||
ui_state.select_highlighter_color(ui_settings.active_highlighter);
|
ui_state.select_highlighter_color(ui_settings.active_highlighter);
|
||||||
@@ -5636,6 +5637,7 @@ pub fn run_with(
|
|||||||
updated.text_colors = ui_state.text_colors;
|
updated.text_colors = ui_state.text_colors;
|
||||||
updated.active_text_color = ui_state.active_text_color;
|
updated.active_text_color = ui_state.active_text_color;
|
||||||
updated.eraser_radius_mm = ui_state.eraser_radius_mm;
|
updated.eraser_radius_mm = ui_state.eraser_radius_mm;
|
||||||
|
updated.saved_colors.clone_from(&ui_state.saved_colors);
|
||||||
if updated != ui_settings {
|
if updated != ui_settings {
|
||||||
ui_settings = updated;
|
ui_settings = updated;
|
||||||
save_ui_settings(
|
save_ui_settings(
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ pub const EN: &[(&str, &str)] = &[
|
|||||||
("Dunkelgrau", "Dark gray"),
|
("Dunkelgrau", "Dark gray"),
|
||||||
("Dunkle Stiftfarben aufhellen", "Lighten dark pen colors"),
|
("Dunkle Stiftfarben aufhellen", "Lighten dark pen colors"),
|
||||||
("Eigene Farbe wählen", "Choose a custom color"),
|
("Eigene Farbe wählen", "Choose a custom color"),
|
||||||
|
("Meine Farbe", "My color"),
|
||||||
|
("➕ Farbe merken", "➕ Save color"),
|
||||||
|
("Diese Farbe aus „Meine Farben“ entfernen", "Remove this color from “My colors”"),
|
||||||
|
("Die aktuelle Farbe zu „Meine Farben“ hinzufügen", "Add the current color to “My colors”"),
|
||||||
("Ein Ordner kann nicht in sich selbst verschoben werden", "A folder cannot be moved into itself"),
|
("Ein Ordner kann nicht in sich selbst verschoben werden", "A folder cannot be moved into itself"),
|
||||||
("Ein-/Ausgabefehler: {e}", "I/O error: {e}"),
|
("Ein-/Ausgabefehler: {e}", "I/O error: {e}"),
|
||||||
("Eine Fläche ohne Rand: in alle Richtungen schreiben, verschieben und zoomen. Wechsel nur bei einer einzigen Seite ohne PDF bzw. zurück, solange alles im Startausschnitt liegt.", "One surface without edges: write, pan and zoom in every direction. Switching only works for a single page without a PDF, and back only while everything lies in the starting area."),
|
("Eine Fläche ohne Rand: in alle Richtungen schreiben, verschieben und zoomen. Wechsel nur bei einer einzigen Seite ohne PDF bzw. zurück, solange alles im Startausschnitt liegt.", "One surface without edges: write, pan and zoom in every direction. Switching only works for a single page without a PDF, and back only while everything lies in the starting area."),
|
||||||
|
|||||||
@@ -217,6 +217,9 @@ pub struct StylusButton {
|
|||||||
/// Höchstens so viele Stifttasten werden gemerkt.
|
/// Höchstens so viele Stifttasten werden gemerkt.
|
||||||
pub const MAX_STYLUS_BUTTONS: usize = 4;
|
pub const MAX_STYLUS_BUTTONS: usize = 4;
|
||||||
|
|
||||||
|
/// How many own colors fit under the presets of the color popovers (two rows)
|
||||||
|
pub const MAX_SAVED_COLORS: usize = 12;
|
||||||
|
|
||||||
/// Benutzereinstellungen der Oberfläche.
|
/// Benutzereinstellungen der Oberfläche.
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -257,6 +260,8 @@ pub struct UiSettings {
|
|||||||
/// One finger draws instead of moving the page. On by default on Android, where phones
|
/// One finger draws instead of moving the page. On by default on Android, where phones
|
||||||
/// usually have no pen (Issue #50)
|
/// usually have no pen (Issue #50)
|
||||||
pub touch_draw: bool,
|
pub touch_draw: bool,
|
||||||
|
/// Own colors under the presets of the color popovers (Issue #56)
|
||||||
|
pub saved_colors: Vec<[f32; 3]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UiSettings {
|
impl Default for UiSettings {
|
||||||
@@ -286,6 +291,7 @@ impl Default for UiSettings {
|
|||||||
storage_dir: None,
|
storage_dir: None,
|
||||||
math_assist: false,
|
math_assist: false,
|
||||||
touch_draw: cfg!(target_os = "android"),
|
touch_draw: cfg!(target_os = "android"),
|
||||||
|
saved_colors: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,6 +339,11 @@ impl UiSettings {
|
|||||||
.active_text_color
|
.active_text_color
|
||||||
.min(settings.text_colors.len() - 1);
|
.min(settings.text_colors.len() - 1);
|
||||||
settings.stylus_buttons.truncate(MAX_STYLUS_BUTTONS);
|
settings.stylus_buttons.truncate(MAX_STYLUS_BUTTONS);
|
||||||
|
settings.saved_colors.truncate(MAX_SAVED_COLORS);
|
||||||
|
for rgb in &mut settings.saved_colors {
|
||||||
|
let [r, g, b, _] = sanitized_color([rgb[0], rgb[1], rgb[2], 1.0], [0.0, 0.0, 0.0, 1.0]);
|
||||||
|
*rgb = [r, g, b];
|
||||||
|
}
|
||||||
settings
|
settings
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,6 +423,7 @@ mod tests {
|
|||||||
storage_dir: Some(PathBuf::from("/home/pia/Nextcloud/ink-notes")),
|
storage_dir: Some(PathBuf::from("/home/pia/Nextcloud/ink-notes")),
|
||||||
math_assist: true,
|
math_assist: true,
|
||||||
touch_draw: true,
|
touch_draw: true,
|
||||||
|
saved_colors: vec![[0.2, 0.4, 0.6], [1.0, 0.5, 0.0]],
|
||||||
};
|
};
|
||||||
settings.save_to(&path).unwrap();
|
settings.save_to(&path).unwrap();
|
||||||
assert_eq!(UiSettings::load_from(&path), settings);
|
assert_eq!(UiSettings::load_from(&path), settings);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::file_picker::{FilePicker, PickerKind};
|
|||||||
use crate::ruler::{Ruler, RulerHit};
|
use crate::ruler::{Ruler, RulerHit};
|
||||||
use crate::settings::{
|
use crate::settings::{
|
||||||
PenPreset, PressureCurve, SidebarSide, DEFAULT_HIGHLIGHTER_COLORS, DEFAULT_PEN_PRESETS,
|
PenPreset, PressureCurve, SidebarSide, DEFAULT_HIGHLIGHTER_COLORS, DEFAULT_PEN_PRESETS,
|
||||||
DEFAULT_TEXT_COLORS, PEN_PRESET_COUNT,
|
DEFAULT_TEXT_COLORS, MAX_SAVED_COLORS, PEN_PRESET_COUNT,
|
||||||
};
|
};
|
||||||
use crate::storage::{NotebookLayout, NotebookSummary};
|
use crate::storage::{NotebookLayout, NotebookSummary};
|
||||||
use crate::text::{TextEditing, TextFont, TEXT_SIZES_PT};
|
use crate::text::{TextEditing, TextFont, TEXT_SIZES_PT};
|
||||||
@@ -446,6 +446,8 @@ pub struct UiState {
|
|||||||
pub is_text_color_menu_open: bool,
|
pub is_text_color_menu_open: bool,
|
||||||
/// Farbwähler in den Farb-Popovern aufgeklappt
|
/// Farbwähler in den Farb-Popovern aufgeklappt
|
||||||
pub show_color_picker: bool,
|
pub show_color_picker: bool,
|
||||||
|
/// „Meine Farben“ in the color popovers (Issue #56)
|
||||||
|
pub saved_colors: Vec<[f32; 3]>,
|
||||||
/// Kontextmenü nach langem Drücken (Einfügen an dieser Stelle)
|
/// Kontextmenü nach langem Drücken (Einfügen an dieser Stelle)
|
||||||
pub context_menu: Option<ContextMenu>,
|
pub context_menu: Option<ContextMenu>,
|
||||||
/// Laufendes Platzschaffen (Vorschau)
|
/// Laufendes Platzschaffen (Vorschau)
|
||||||
@@ -575,6 +577,7 @@ impl Default for UiState {
|
|||||||
active_text_color: 0,
|
active_text_color: 0,
|
||||||
is_text_color_menu_open: false,
|
is_text_color_menu_open: false,
|
||||||
show_color_picker: false,
|
show_color_picker: false,
|
||||||
|
saved_colors: Vec::new(),
|
||||||
context_menu: None,
|
context_menu: None,
|
||||||
space_drag: None,
|
space_drag: None,
|
||||||
stylus_buttons: Vec::new(),
|
stylus_buttons: Vec::new(),
|
||||||
@@ -1304,17 +1307,21 @@ fn autosave_status_style(status: AutosaveStatus) -> (egui::Color32, &'static str
|
|||||||
fn color_editor(
|
fn color_editor(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
presets: &[ColorPreset],
|
presets: &[ColorPreset],
|
||||||
|
saved: &mut Vec<[f32; 3]>,
|
||||||
color: &mut [f32; 4],
|
color: &mut [f32; 4],
|
||||||
picker_open: &mut bool,
|
picker_open: &mut bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
let same_rgb = |a: &[f32], b: &[f32]| {
|
||||||
|
a[..3]
|
||||||
|
.iter()
|
||||||
|
.zip(&b[..3])
|
||||||
|
.all(|(a, b)| (a - b).abs() < 0.01)
|
||||||
|
};
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.spacing_mut().item_spacing = egui::vec2(8.0, 0.0);
|
ui.spacing_mut().item_spacing = egui::vec2(8.0, 0.0);
|
||||||
for &(preset, label) in presets {
|
for &(preset, label) in presets {
|
||||||
let is_sel = preset[..3]
|
let is_sel = same_rgb(&preset, color);
|
||||||
.iter()
|
|
||||||
.zip(&color[..3])
|
|
||||||
.all(|(a, b)| (a - b).abs() < 0.01);
|
|
||||||
if color_circle_swatch(ui, preset, is_sel, crate::i18n::tr(label), 30.0).clicked() {
|
if color_circle_swatch(ui, preset, is_sel, crate::i18n::tr(label), 30.0).clicked() {
|
||||||
*color = [preset[0], preset[1], preset[2], color[3]];
|
*color = [preset[0], preset[1], preset[2], color[3]];
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -1331,6 +1338,46 @@ fn color_editor(
|
|||||||
*picker_open = !*picker_open;
|
*picker_open = !*picker_open;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// My colors (Issue #56): kept for pen, highlighter and text alike
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.horizontal_wrapped(|ui| {
|
||||||
|
ui.spacing_mut().item_spacing = egui::vec2(8.0, 6.0);
|
||||||
|
let mut remove = None;
|
||||||
|
for (i, rgb) in saved.iter().enumerate() {
|
||||||
|
let swatch = [rgb[0], rgb[1], rgb[2], 1.0];
|
||||||
|
let is_sel = same_rgb(rgb, color);
|
||||||
|
if color_circle_swatch(ui, swatch, is_sel, t!("Meine Farbe"), 30.0).clicked() {
|
||||||
|
*color = [rgb[0], rgb[1], rgb[2], color[3]];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if is_sel {
|
||||||
|
remove = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(i) = remove {
|
||||||
|
if ui
|
||||||
|
.button(egui::RichText::new("🗑").size(16.0))
|
||||||
|
.on_hover_text(t!("Diese Farbe aus „Meine Farben“ entfernen"))
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
saved.remove(i);
|
||||||
|
}
|
||||||
|
} else if saved.len() < MAX_SAVED_COLORS {
|
||||||
|
let label = if saved.is_empty() {
|
||||||
|
t!("➕ Farbe merken")
|
||||||
|
} else {
|
||||||
|
"➕"
|
||||||
|
};
|
||||||
|
if ui
|
||||||
|
.button(label)
|
||||||
|
.on_hover_text(t!("Die aktuelle Farbe zu „Meine Farben“ hinzufügen"))
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
saved.push([color[0], color[1], color[2]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
if *picker_open {
|
if *picker_open {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
let [r, g, b] = [0, 1, 2].map(|i| (color[i].clamp(0.0, 1.0) * 255.0).round() as u8);
|
let [r, g, b] = [0, 1, 2].map(|i| (color[i].clamp(0.0, 1.0) * 255.0).round() as u8);
|
||||||
@@ -4093,6 +4140,7 @@ pub fn render_ui(
|
|||||||
if color_editor(
|
if color_editor(
|
||||||
ui,
|
ui,
|
||||||
&PEN_COLOR_PRESETS,
|
&PEN_COLOR_PRESETS,
|
||||||
|
&mut state.saved_colors,
|
||||||
&mut state.pen_color,
|
&mut state.pen_color,
|
||||||
&mut state.show_color_picker,
|
&mut state.show_color_picker,
|
||||||
) {
|
) {
|
||||||
@@ -4274,6 +4322,7 @@ pub fn render_ui(
|
|||||||
if color_editor(
|
if color_editor(
|
||||||
ui,
|
ui,
|
||||||
&HIGHLIGHTER_COLOR_PRESETS,
|
&HIGHLIGHTER_COLOR_PRESETS,
|
||||||
|
&mut state.saved_colors,
|
||||||
&mut state.highlighter_color,
|
&mut state.highlighter_color,
|
||||||
&mut state.show_color_picker,
|
&mut state.show_color_picker,
|
||||||
) {
|
) {
|
||||||
@@ -4380,6 +4429,7 @@ pub fn render_ui(
|
|||||||
if color_editor(
|
if color_editor(
|
||||||
ui,
|
ui,
|
||||||
&PEN_COLOR_PRESETS,
|
&PEN_COLOR_PRESETS,
|
||||||
|
&mut state.saved_colors,
|
||||||
&mut color,
|
&mut color,
|
||||||
&mut state.show_color_picker,
|
&mut state.show_color_picker,
|
||||||
) {
|
) {
|
||||||
|
|||||||
Reference in new issue
Block a user