Compare commits

..
4 Commits
Author SHA1 Message Date
haraldandClaude Opus 5.5 7c69edab12 chore(release): bump version to 0.45.0
Build & Publish Release / Android APK (push) Successful in 9m7s
Build & Publish Release / Build Packages & Publish to Gitea (push) Successful in 23m24s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 11:02:47 +01:00
haraldandClaude Opus 5.5 6f52d4801f docs: describe saved colors (Issue #56)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 10:52:22 +01:00
haraldandClaude Opus 5.5 bb9bb58790 feat(colors): save own colors under the presets of the color popovers (Issue #56)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 10:52:16 +01:00
haraldandClaude Opus 5.5 9dbe625eef fix(text): copy and paste in text fields through the system clipboard (Issue #57)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 10:52:16 +01:00
12 changed files with 132 additions and 9 deletions

No files matched your search

Generated
+1 -1
View File
@@ -1540,7 +1540,7 @@ dependencies = [
[[package]] [[package]]
name = "ink-notes" name = "ink-notes"
version = "0.44.0" version = "0.45.0"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"android_logger", "android_logger",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "ink-notes" name = "ink-notes"
version = "0.44.0" version = "0.45.0"
edition = "2021" edition = "2021"
description = "Notizbuch-App für Stift, Touch und Maus unter Linux" description = "Notizbuch-App für Stift, Touch und Maus unter Linux"
repository = "https://gitea.pansi.eu/harald/ink-notes" repository = "https://gitea.pansi.eu/harald/ink-notes"
+1 -1
View File
@@ -23,7 +23,7 @@ Die Oberfläche gibt es auf Deutsch und Englisch; ink-notes folgt der Systemspra
### Schreiben und Zeichnen ### Schreiben und Zeichnen
- **Sieben Stifte** in der Werkzeugleiste, jeder mit eigener Farbe und Stärke (0,15–5 mm, mit Druckstärke). Ändert man Farbe oder Stärke, merkt sich der gewählte Stift das – auch über einen Neustart hinweg. **Textmarker** (halbtransparent, 4–8 mm) in vier Farben; innerhalb eines Strichs wird er nicht dunkler, erst ein neuer Strich deckt stärker. - **Sieben Stifte** in der Werkzeugleiste, jeder mit eigener Farbe und Stärke (0,15–5 mm, mit Druckstärke). Ändert man Farbe oder Stärke, merkt sich der gewählte Stift das – auch über einen Neustart hinweg. **Textmarker** (halbtransparent, 4–8 mm) in vier Farben; innerhalb eines Strichs wird er nicht dunkler, erst ein neuer Strich deckt stärker.
- **Eigene Farben:** Jede Farbe in der Werkzeugleiste (Stifte, Textmarker, Text) lässt sich anpassen – gewählte Farbe erneut antippen, eine Vorgabe oder mit 🎨 einen freien Farbton wählen. Die Leiste merkt sich die Farben. Am Bildschirm erscheinen sie genauso wie im PDF- und Bildexport. - **Eigene Farben:** Jede Farbe in der Werkzeugleiste (Stifte, Textmarker, Text) lässt sich anpassen – gewählte Farbe erneut antippen, eine Vorgabe oder mit 🎨 einen freien Farbton wählen. Die Leiste merkt sich die Farben. Unter den Vorgaben legt „➕ Farbe merken“ den aktuellen Farbton in „Meine Farben“ ab (bis zu 12, gemeinsam für Stifte, Textmarker und Text; 🗑 entfernt die gewählte). Am Bildschirm erscheinen sie genauso wie im PDF- und Bildexport.
- **Glättung in zwei Stufen:** Während des Schreibens glättet ein 1€-Filter das Zittern, die Linie erscheint sofort. Beim Absetzen wird der Strich nachbearbeitet: Ecken (Knicke über 65°) bleiben erhalten und werden rund verbunden, der Druckverlauf wird geglättet, überflüssige Punkte entfallen, die Enden werden rund. - **Glättung in zwei Stufen:** Während des Schreibens glättet ein 1€-Filter das Zittern, die Linie erscheint sofort. Beim Absetzen wird der Strich nachbearbeitet: Ecken (Knicke über 65°) bleiben erhalten und werden rund verbunden, der Druckverlauf wird geglättet, überflüssige Punkte entfallen, die Enden werden rund.
- **Druckkurve** im ☰-Menü an den eigenen Stift anpassen (weicher/härter, Schwelle gegen Grundrauschen). - **Druckkurve** im ☰-Menü an den eigenen Stift anpassen (weicher/härter, Schwelle gegen Grundrauschen).
- **Tasten am Stift** im ☰-Menü belegen: Radieren (Standard), Auswählen, Textmarker, Stift oder nichts – gilt, solange die Taste gedrückt ist. Jede Taste erscheint dort nach dem ersten Drücken. - **Tasten am Stift** im ☰-Menü belegen: Radieren (Standard), Auswählen, Textmarker, Stift oder nichts – gilt, solange die Taste gedrückt ist. Jede Taste erscheint dort nach dem ersten Drücken.
+1 -1
View File
@@ -23,7 +23,7 @@ The interface is available in English and German; ink-notes follows the system l
### Writing and drawing ### Writing and drawing
- **Seven pens** in the toolbar, each with its own color and width (0.15–5 mm, pressure-sensitive). When you change a pen's color or width, it remembers that – also across restarts. **Highlighter** (semi-transparent, 4–8 mm) in four colors; it does not get darker within one stroke, only a new stroke covers more strongly. - **Seven pens** in the toolbar, each with its own color and width (0.15–5 mm, pressure-sensitive). When you change a pen's color or width, it remembers that – also across restarts. **Highlighter** (semi-transparent, 4–8 mm) in four colors; it does not get darker within one stroke, only a new stroke covers more strongly.
- **Custom colors:** Every color in the toolbar (pens, highlighter, text) can be changed – tap the selected color again and pick a preset or any shade with 🎨. The toolbar remembers the colors. They look the same on screen as in PDF and image exports. - **Custom colors:** Every color in the toolbar (pens, highlighter, text) can be changed – tap the selected color again and pick a preset or any shade with 🎨. The toolbar remembers the colors. Under the presets, “➕ Save color” keeps the current shade in “My colors” (up to 12, shared by pens, highlighter and text; 🗑 removes the selected one). They look the same on screen as in PDF and image exports.
- **Two-stage smoothing:** While you write, a 1€ filter removes jitter and the line appears immediately. When you lift the pen, the stroke is refined: corners (bends over 65°) are kept and drawn round, the pressure curve is smoothed, redundant points are dropped and the ends become round. - **Two-stage smoothing:** While you write, a 1€ filter removes jitter and the line appears immediately. When you lift the pen, the stroke is refined: corners (bends over 65°) are kept and drawn round, the pressure curve is smoothed, redundant points are dropped and the ends become round.
- **Pressure curve** adjustable to your pen in the ☰ menu (softer/harder, threshold against base noise). - **Pressure curve** adjustable to your pen in the ☰ menu (softer/harder, threshold against base noise).
- **Pen buttons** can be assigned in the ☰ menu: erase (default), select, highlighter, pen or nothing – active while the button is held. Each button appears there after it is pressed for the first time. - **Pen buttons** can be assigned in the ☰ menu: erase (default), select, highlighter, pen or nothing – active while the button is held. Each button appears there after it is pressed for the first time.
@@ -84,6 +84,11 @@
</branding> </branding>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="0.45.0" date="2026-11-14">
<description>
<p>Own colors can be saved under the presets of the color menus, and copy and paste in text fields works with other apps.</p>
</description>
</release>
<release version="0.44.0" date="2026-11-09"> <release version="0.44.0" date="2026-11-09">
<description> <description>
<p>Seven pens in the toolbar, dialogs that fit on phones, and touch lifts that arrive right away on GNOME, so the page glides after a swipe and the ruler no longer follows the hovering pen.</p> <p>Seven pens in the toolbar, dialogs that fit on phones, and touch lifts that arrive right away on GNOME, so the page glides after a swipe and the ruler no longer follows the hovering pen.</p>
+5
View File
@@ -84,6 +84,11 @@
</branding> </branding>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="0.45.0" date="2026-11-14">
<description>
<p>Own colors can be saved under the presets of the color menus, and copy and paste in text fields works with other apps.</p>
</description>
</release>
<release version="0.44.0" date="2026-11-09"> <release version="0.44.0" date="2026-11-09">
<description> <description>
<p>Seven pens in the toolbar, dialogs that fit on phones, and touch lifts that arrive right away on GNOME, so the page glides after a swipe and the ruler no longer follows the hovering pen.</p> <p>Seven pens in the toolbar, dialogs that fit on phones, and touch lifts that arrive right away on GNOME, so the page glides after a swipe and the ruler no longer follows the hovering pen.</p>
+2
View File
@@ -3,6 +3,8 @@
Notebook app for pen, touch and mouse on Linux (tested on Zorin OS 18 / Ubuntu 24.04). Notebook app for pen, touch and mouse on Linux (tested on Zorin OS 18 / Ubuntu 24.04).
### Highlights: ### Highlights:
- **My colors**: Under the presets of the color menus (pen, highlighter, text), "➕ Save color" keeps the current shade in a row of your own colors – up to 12, shared by all three tools and kept across restarts; 🗑 removes the selected one (Issue #56)
- **Copy and paste in text fields**: Ctrl+C, Ctrl+X and Ctrl+V in a text field now use the system clipboard, so text moves between ink-notes and other apps. Before, they only worked within the app (Issue #57)
- **Seven pens**: The toolbar now has seven pens instead of four (new: violet, orange, gray). Each remembers its color and width; tap the selected pen again to change them. Older versions keep reading the first four pens (Issue #56) - **Seven pens**: The toolbar now has seven pens instead of four (new: violet, orange, gray). Each remembers its color and width; tap the selected pen again to change them. Older versions keep reading the first four pens (Issue #56)
- **Momentum scrolling on GNOME, second try**: GNOME could deliver the lift of a swipe only together with the next touch, because the library under winit held it back until the next touch frame. Lifts are now handed on right away, so the page glides on after a quick swipe (Issue #28) - **Momentum scrolling on GNOME, second try**: GNOME could deliver the lift of a swipe only together with the next touch, because the library under winit held it back until the next touch frame. Lifts are now handed on right away, so the page glides on after a quick swipe (Issue #28)
- **Ruler stays put**: After moving the ruler with a finger, it could follow the hovering pen (same cause as above). In addition, a finger drag of the ruler now ends as soon as the pen comes near (Issue #55) - **Ruler stays put**: After moving the ruler with a finger, it could follow the hovering pen (same cause as above). In addition, a finger drag of the ruler now ends as soon as the pen comes near (Issue #55)
+41
View File
@@ -573,6 +573,19 @@ impl ClipboardBridge {
(!text.trim().is_empty()).then_some(text) (!text.trim().is_empty()).then_some(text)
} }
/// Text copied or cut in a text field goes to the system clipboard, so it can be pasted
/// into other apps (Issue #57).
fn set_system_text(&mut self, text: String) {
if self.system.is_none() {
self.system = platform::clipboard::Clipboard::new().ok();
}
if let Some(system) = self.system.as_mut() {
if let Err(err) = system.set_text(text) {
eprintln!("[Zwischenablage] Text nicht gesetzt: {err}");
}
}
}
/// Merkt sich beim internen Kopieren das aktuelle Systembild, den Text und das /// Merkt sich beim internen Kopieren das aktuelle Systembild, den Text und das
/// Quell-Notizbuch. /// Quell-Notizbuch.
fn note_internal_copy(&mut self, storage_dir: &Path) { fn note_internal_copy(&mut self, storage_dir: &Path) {
@@ -1472,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);
@@ -2531,6 +2545,28 @@ pub fn run_with(
consumed: false, consumed: false,
} }
} else { } else {
// Ctrl+V in a text field: egui-winit is built without its own clipboard
// access and would only paste what was copied inside the app, so it gets the
// text of the system clipboard first (Issue #57)
if let WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Character(c),
state: ElementState::Pressed,
..
},
..
} = &event
{
if c.eq_ignore_ascii_case("v")
&& egui_winit_state.egui_input().modifiers.command
&& egui_ctx.wants_keyboard_input()
{
if let Some(text) = clipboard.system_text() {
egui_winit_state.set_clipboard_text(text);
}
}
}
egui_winit_state.on_window_event(&window, &event) egui_winit_state.on_window_event(&window, &event)
}; };
// egui-winit asks for a repaint after every RedrawRequested as well; following // egui-winit asks for a repaint after every RedrawRequested as well; following
@@ -5601,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(
@@ -5638,6 +5675,10 @@ pub fn run_with(
// 4. egui Frame beenden & Primitives tessellieren // 4. egui Frame beenden & Primitives tessellieren
let full_output = egui_ctx.end_frame(); let full_output = egui_ctx.end_frame();
let ime_active = full_output.platform_output.ime.is_some(); let ime_active = full_output.platform_output.ime.is_some();
if !full_output.platform_output.copied_text.is_empty() {
clipboard
.set_system_text(full_output.platform_output.copied_text.clone());
}
egui_winit_state egui_winit_state
.handle_platform_output(&window, full_output.platform_output); .handle_platform_output(&window, full_output.platform_output);
if let Some(requester) = keyboard_requester.as_mut() { if let Some(requester) = keyboard_requester.as_mut() {
+4
View File
@@ -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."),
+4
View File
@@ -400,6 +400,10 @@ pub mod clipboard {
pub fn set_image(&mut self, _image: ImageData) -> Result<(), &'static str> { pub fn set_image(&mut self, _image: ImageData) -> Result<(), &'static str> {
Err("not available on Android") Err("not available on Android")
} }
pub fn set_text(&mut self, _text: String) -> Result<(), &'static str> {
Err("not available on Android")
}
} }
} }
} }
+12
View File
@@ -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);
+55 -5
View File
@@ -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,
) { ) {