Skip to content

Commit 625251b

Browse files
authored
Merge pull request #681 from kas-gui/push-rnuwvsmrnuzn
Fix text selection color when using UI theme
2 parents 5fb3e8f + 0477a1b commit 625251b

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

crates/kas-core/src/text/format.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,28 @@ pub struct Color(NonZeroU32);
2323
impl Default for Color {
2424
/// Use a theme-defined color (automatic)
2525
fn default() -> Self {
26-
let color = Rgba8Srgb::rgba(1, 0, 0, 0);
27-
Color(NonZeroU32::new(u32::from_ne_bytes(color.0)).unwrap())
26+
Self::DEFAULT
2827
}
2928
}
3029

3130
impl Color {
31+
/// Use the default theme-defined color
32+
///
33+
/// As a foreground color, this maps to [`ColorsLinear::text`] or
34+
/// [`ColorsLinear::text_invert`] depending on the background.
35+
///
36+
/// As a background color, this maps to [`ColorsLinear::edit_bg`].
37+
pub const DEFAULT: Self =
38+
Color(NonZeroU32::new(u32::from_ne_bytes(Rgba8Srgb::rgba(1, 0, 0, 0).0)).unwrap());
39+
40+
/// Use the text-selection color
41+
///
42+
/// As a foreground color this is identical to [`Self::DEFAULT`].
43+
///
44+
/// As a background color, this maps to [`ColorsLinear::text_sel_bg`].
45+
pub const SELECTION: Self =
46+
Color(NonZeroU32::new(u32::from_ne_bytes(Rgba8Srgb::rgba(1, 1, 0, 0).0)).unwrap());
47+
3248
/// Use an RGBA sRGB color
3349
///
3450
/// This will resolve to the default theme color if `color.a() == 0`.
@@ -64,13 +80,9 @@ impl Color {
6480
self.as_rgba_srgb().map(|c| c.into())
6581
}
6682

67-
/// Resolve color
68-
///
69-
/// If this represents a valid palette index, the palette's color will be
70-
/// used, otherwise the color will be inferred from the theme, using `bg`
71-
/// if provided.
83+
/// Resolve as (foreground) text color
7284
#[inline]
73-
pub fn resolve_color(self, theme: &ColorsLinear, bg: Option<Rgba>) -> Rgba {
85+
pub fn resolve_foreground(self, theme: &ColorsLinear, bg: Option<Rgba>) -> Rgba {
7486
if let Some(col) = self.as_rgba() {
7587
col
7688
} else if let Some(bg) = bg {
@@ -79,6 +91,18 @@ impl Color {
7991
theme.text
8092
}
8193
}
94+
95+
/// Resolve as background color
96+
#[inline]
97+
pub fn resolve_background(self, theme: &ColorsLinear) -> Rgba {
98+
if let Some(col) = self.as_rgba() {
99+
col
100+
} else if self == Self::SELECTION {
101+
theme.text_sel_bg
102+
} else {
103+
theme.edit_bg
104+
}
105+
}
82106
}
83107

84108
/// Effect formatting marker: text and background color
@@ -93,14 +117,6 @@ pub struct Colors {
93117
pub background: Option<Color>,
94118
}
95119

96-
impl Colors {
97-
/// Resolve the background color, if any
98-
pub fn resolve_background_color(self, theme: &ColorsLinear) -> Option<Rgba> {
99-
self.background
100-
.map(|bg| bg.as_rgba().unwrap_or(theme.edit_bg))
101-
}
102-
}
103-
104120
/// Decoration types
105121
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
106122
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

crates/kas-core/src/text/raster.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl State {
554554
.map(|e| e.1 == Default::default())
555555
.unwrap_or(true)
556556
{
557-
let col = Color::default().resolve_color(theme, None);
557+
let col = Color::default().resolve_foreground(theme, None);
558558
self.text_with_color(allocator, queue, pass, pos, bb, text, col);
559559
return;
560560
}
@@ -575,12 +575,12 @@ impl State {
575575
}
576576
};
577577

578-
let col = token.foreground.resolve_color(theme, None);
578+
let col = token.foreground.resolve_foreground(theme, None);
579579
queue.push_sprite(pass, glyph.position.into(), bb, col, sprite);
580580
};
581581

582582
let for_range = |p: kas_text::Vec2, x2, colors: Colors| {
583-
let Some(col) = colors.resolve_background_color(theme) else {
583+
let Some(col) = colors.background.map(|col| col.resolve_background(theme)) else {
584584
return;
585585
};
586586

@@ -634,7 +634,7 @@ impl State {
634634
};
635635

636636
// Known limitation: this cannot depend on the background color.
637-
let col = token.color.resolve_color(theme, None);
637+
let col = token.color.resolve_foreground(theme, None);
638638

639639
match token.style {
640640
LineStyle::Solid => draw_quad(quad, col),

crates/kas-widgets/src/edit/editor.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use kas::event::components::{TextInput, TextInputAction};
1111
use kas::event::{ElementState, FocusSource, Ime, ImePurpose, ImeSurroundingText, Scroll};
1212
use kas::geom::Vec2;
1313
use kas::prelude::*;
14-
use kas::text::format::FormattableText;
14+
use kas::text::format::{Color, FormattableText};
1515
use kas::text::{CursorRange, NotReady, SelectionHelper, format};
1616
use kas::theme::{Background, Text, TextClass};
1717
use kas::util::UndoStack;
@@ -199,6 +199,12 @@ impl<H: Highlighter> Component<H> {
199199
self.id = id;
200200
self.text.text_mut().configure(cx);
201201
self.0.colors = self.text.text().scheme_colors();
202+
if self.0.colors.selection_foreground == Color::default() {
203+
self.0.colors.selection_foreground = Color::SELECTION;
204+
}
205+
if self.0.colors.selection_background == Color::default() {
206+
self.0.colors.selection_background = Color::SELECTION;
207+
}
202208
self.text.configure(&mut cx.size_cx());
203209
}
204210

crates/kas-widgets/src/scroll_label.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ mod SelectableText {
7878
&[]
7979
} else {
8080
tokens[1].0 = range.start;
81-
tokens[1].1.background = Some(format::Color::default());
81+
tokens[1].1.foreground = format::Color::SELECTION;
82+
tokens[1].1.background = Some(format::Color::SELECTION);
8283
tokens[2].0 = range.end;
8384
let r0 = if range.start > 0 { 0 } else { 1 };
8485
&tokens[r0..]

0 commit comments

Comments
 (0)