gravel_frontend_fltk/
config.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use fltk::enums::Color;
use gravel_ffi::PluginConfigAdapter;
use serde::Deserialize;

pub const DEFAULT_CONFIG: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/config.yml"));

pub fn get(adapter: &PluginConfigAdapter<'_>) -> Config {
	let config = adapter.get::<Config>(DEFAULT_CONFIG);

	if config.behaviour.start_hidden && config.behaviour.exit_on_hide {
		log::warn!("frontend is configured to both start hidden and hide on exit, that doesn't make sense");
	}

	config
}

#[derive(Deserialize, Debug)]
pub struct Behaviour {
	pub start_hidden: bool,
	pub auto_hide: bool,
	pub exit_on_hide: bool,
	pub window_hide_debounce: Option<u64>,
	pub auto_center_window: bool,
	pub show_scores: bool,
}

#[derive(Deserialize, Debug)]
#[serde(from = "deserialize::Layout")]
pub struct Layout {
	pub max_hits: i32,
	pub hit_width: i32,
	pub hit_height: i32,
	pub query_width: i32,
	pub query_height: i32,
	pub scrollbar_x: i32,
	pub scrollbar_y: i32,
	pub scrollbar_height: i32,
	pub hit_start_y: i32,
	pub window_min_height: i32,
	pub hit_title_height: i32,
	pub hit_title_font_size: i32,
	pub hit_subtitle_height: i32,
	pub hit_subtitle_font_size: i32,
	pub query_font_size: i32,
	pub scrollbar_width: i32,
	pub scrollbar_padding: i32,
	pub padding: i32,
	pub window_width: i32,
	pub window_border: bool,
	pub window_decorations: bool,
}

#[derive(Deserialize, Debug)]
pub struct Config {
	pub layout: Layout,
	pub colors: Colors,
	pub behaviour: Behaviour,
}

#[derive(Deserialize, Debug)]
pub struct Colors {
	#[serde(deserialize_with = "deserialize::color")]
	pub background: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub query_text: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub query_cursor: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub query_highlight: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub query_background: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub hit_title: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub hit_subtitle: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub hit_highlight: Color,
	#[serde(deserialize_with = "deserialize::color")]
	pub scrollbar: Color,
}

pub mod deserialize {
	use fltk::enums::Color;
	use serde::{Deserialize, Deserializer};

	pub fn color<'de, D: Deserializer<'de>>(de: D) -> Result<Color, D::Error> {
		u32::deserialize(de).map(Color::from_hex)
	}

	#[derive(Deserialize, Debug)]
	pub struct Layout {
		pub scale: f32,
		pub max_hits: i32,
		pub hit_title_height: i32,
		pub hit_title_font_size: i32,
		pub hit_subtitle_height: i32,
		pub hit_subtitle_font_size: i32,
		pub query_font_size: i32,
		pub scrollbar_width: i32,
		pub scrollbar_padding: i32,
		pub padding: i32,
		pub window_width: i32,
		pub window_border: bool,
		pub window_decorations: bool,
	}

	impl From<Layout> for super::Layout {
		fn from(value: Layout) -> Self {
			let hit_title_height = (value.hit_title_height as f32 * value.scale) as i32;
			let hit_title_font_size = (value.hit_title_font_size as f32 * value.scale) as i32;
			let hit_subtitle_height = (value.hit_subtitle_height as f32 * value.scale) as i32;
			let hit_subtitle_font_size = (value.hit_subtitle_font_size as f32 * value.scale) as i32;
			let query_font_size = (value.query_font_size as f32 * value.scale) as i32;
			let scrollbar_width = (value.scrollbar_width as f32 * value.scale) as i32;
			let scrollbar_padding = (value.scrollbar_padding as f32 * value.scale) as i32;
			let padding = (value.padding as f32 * value.scale) as i32;
			let window_width = (value.window_width as f32 * value.scale) as i32;
			let max_hits = value.max_hits;

			let hit_width = window_width - padding * 2;
			let hit_height = hit_title_height + hit_subtitle_height;

			let query_width = hit_width;
			let query_height = hit_height;

			let scrollbar_x = window_width - padding - scrollbar_width;
			let scrollbar_y = padding * 2 + query_height;
			let scrollbar_height = hit_height * max_hits;

			let hit_start_y = padding * 2 + query_height;
			let window_min_height = query_height + padding * 2;

			let window_border = value.window_border;
			let window_decorations = value.window_decorations;

			Self {
				max_hits,
				hit_width,
				hit_height,
				query_width,
				query_height,
				scrollbar_x,
				scrollbar_y,
				scrollbar_height,
				hit_start_y,
				window_min_height,
				hit_title_height,
				hit_title_font_size,
				hit_subtitle_height,
				hit_subtitle_font_size,
				query_font_size,
				scrollbar_width,
				scrollbar_padding,
				padding,
				window_width,
				window_border,
				window_decorations,
			}
		}
	}
}