Skip to content

Commit aa5b80b

Browse files
committed
app: Update egui to 0.33, replace clipboard_win with egui copy_image
1 parent 8d5fdfb commit aa5b80b

File tree

18 files changed

+1127
-778
lines changed

18 files changed

+1127
-778
lines changed

Cargo.lock

Lines changed: 963 additions & 578 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ members = ["crates/core", "crates/scanner", "crates/strings", "crates/xg"]
44
[workspace.dependencies]
55
anyhow = "1"
66
binrw = "0.13.3"
7-
epaint = "0.28.1"
7+
epaint = "0.33.0"
88
itertools = "0.14"
99
log = "0.4"
1010
parking_lot = "0.12"
@@ -42,25 +42,25 @@ profiling.workspace = true
4242
rustc-hash.workspace = true
4343

4444
# UI
45-
eframe = { version = "0.28.1", default-features = false, features = [
45+
eframe = { version = "0.33.0", default-features = false, features = [
4646
"default_fonts",
4747
"wayland",
4848
"x11",
4949
"persistence",
5050
"wgpu",
5151
] }
52-
egui_extras = { version = "0.28.1", features = ["syntect"] }
53-
egui-notify = "0.15.0"
52+
egui_extras = { version = "0.33.0", features = ["syntect"] }
53+
egui-notify = "0.21.0"
5454
native-dialog = "0.7.0"
5555
opener = "0.7.0"
5656
poll-promise = { version = "0.3.0", features = ["tokio"] }
5757
rayon = "1.8.0"
58+
wgpu = { version = "27.0.1", default-features = false, features = ["std", "vulkan"] }
5859

5960
# (de)serialization
6061
base64 = "0.22.0"
6162
bincode = "2.0.0-rc.3"
6263
binrw = "0.13.3"
63-
clipboard-win = "5.3.1"
6464
either = "1.10.0"
6565
image = { version = "0.25.1", features = ["png"], default-features = false }
6666
regex = "1.10.4"

src/gui/audio_events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl View for AudioEventView {
193193
egui::RichText::new(fancy_tag).color(Color32::from_rgb(191, 106, 247));
194194

195195
if ui
196-
.add(egui::SelectableLabel::new(false, tag_label))
196+
.add(egui::Button::selectable(false, tag_label))
197197
.tag_context_with_preview(*tag, None, false)
198198
.clicked()
199199
{

src/gui/common.rs

Lines changed: 30 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,16 @@ use std::fs::File;
22

33
use eframe::egui::RichText;
44
use eframe::egui::{self};
5-
use image::{DynamicImage, GenericImage, ImageFormat};
6-
use lazy_static::lazy_static;
5+
use image::{DynamicImage, GenericImage};
76
use log::{error, info, warn};
87
use quicktag_core::tagtypes::TagType;
9-
use std::io::{Cursor, Write};
10-
use std::num::NonZeroU32;
8+
use std::io::Write;
119
use tiger_pkg::{TagHash, package_manager};
1210

1311
use crate::texture::{Texture, cache::TextureCache};
1412

1513
use super::TOASTS;
1614

17-
lazy_static! {
18-
static ref CF_PNG: NonZeroU32 = clipboard_win::register_format("PNG").unwrap();
19-
static ref CF_FILENAME: NonZeroU32 = clipboard_win::register_format("FileNameW").unwrap();
20-
}
21-
2215
pub trait ResponseExt {
2316
fn tag_context(self, tag: TagHash) -> Self;
2417

@@ -49,38 +42,19 @@ impl ResponseExt for egui::Response {
4942
match Texture::load(&texture_cache.render_state, tag, false) {
5043
Ok(o) => {
5144
let image = o.to_image(&texture_cache.render_state, 0).unwrap();
52-
let mut png_data = vec![];
53-
let mut png_writer = Cursor::new(&mut png_data);
54-
image.write_to(&mut png_writer, ImageFormat::Png).unwrap();
55-
56-
let _clipboard = clipboard_win::Clipboard::new();
57-
if let Err(e) = clipboard_win::raw::set(CF_PNG.get(), &png_data) {
58-
error!("Failed to copy texture to clipboard: {e}");
59-
}
60-
61-
// Save to temp
62-
let path = std::env::temp_dir().join(format!("{tag}.png"));
63-
let mut file = File::create(&path).unwrap();
64-
file.write_all(&png_data).unwrap();
65-
66-
let mut path_utf16 =
67-
path.to_string_lossy().encode_utf16().collect::<Vec<u16>>();
68-
path_utf16.push(0);
69-
70-
if let Err(e) = clipboard_win::raw::set_without_clear(
71-
CF_FILENAME.get(),
72-
bytemuck::cast_slice(&path_utf16),
73-
) {
74-
error!("Failed to copy texture path to clipboard: {e}");
75-
} else {
76-
TOASTS.lock().success("Texture copied to clipboard");
77-
}
45+
let rgba = image.to_rgba8().to_vec();
46+
let color_image = egui::ColorImage::from_rgba_unmultiplied(
47+
[image.width() as usize, image.height() as usize],
48+
&rgba,
49+
);
50+
51+
self.ctx.copy_image(color_image);
7852
}
7953
Err(e) => {
8054
error!("Failed to load texture: {e}");
8155
}
8256
}
83-
ui.close_menu();
57+
ui.close();
8458
}
8559

8660
if ui
@@ -89,7 +63,7 @@ impl ResponseExt for egui::Response {
8963
.clicked()
9064
{
9165
export_texture(texture_cache, tag);
92-
ui.close_menu();
66+
ui.close();
9367
}
9468
}
9569
tag_context(ui, tag);
@@ -215,29 +189,25 @@ pub fn tag_context(ui: &mut egui::Ui, tag: TagHash) {
215189
.selectable_label(false, format!("📋 Copy tag{flipped_postfix}"))
216190
.clicked()
217191
{
218-
ui.output_mut(|o| {
219-
o.copied_text = if copy_flipped {
220-
format!("{:08X}", tag.0.swap_bytes())
221-
} else {
222-
format!("{:08X}", tag.0)
223-
}
192+
ui.ctx().copy_text(if copy_flipped {
193+
format!("{:08X}", tag.0.swap_bytes())
194+
} else {
195+
format!("{:08X}", tag.0)
224196
});
225-
ui.close_menu();
197+
ui.close();
226198
}
227199

228200
if let Some(tag64) = package_manager().get_tag64_for_tag32(tag) {
229201
if ui
230202
.selectable_label(false, format!("📋 Copy 64-bit tag{flipped_postfix}"))
231203
.clicked()
232204
{
233-
ui.output_mut(|o| {
234-
o.copied_text = if copy_flipped {
235-
format!("{:016X}", tag64.0.swap_bytes())
236-
} else {
237-
format!("{:016X}", tag64.0)
238-
}
205+
ui.ctx().copy_text(if copy_flipped {
206+
format!("{:016X}", tag64.0.swap_bytes())
207+
} else {
208+
format!("{:016X}", tag64.0)
239209
});
240-
ui.close_menu();
210+
ui.close();
241211
}
242212
}
243213

@@ -246,37 +216,35 @@ pub fn tag_context(ui: &mut egui::Ui, tag: TagHash) {
246216
.selectable_label(false, format!("📋 Copy reference tag{flipped_postfix}"))
247217
.clicked()
248218
{
249-
ui.output_mut(|o| {
250-
o.copied_text = if copy_flipped {
251-
format!("{:08X}", entry.reference.swap_bytes())
252-
} else {
253-
format!("{:08X}", entry.reference)
254-
}
219+
ui.ctx().copy_text(if copy_flipped {
220+
format!("{:08X}", entry.reference.swap_bytes())
221+
} else {
222+
format!("{:08X}", entry.reference)
255223
});
256-
ui.close_menu();
224+
ui.close();
257225
}
258226

259227
let tt = TagType::from_type_subtype(entry.file_type, entry.file_subtype);
260228
if tt == TagType::WwiseStream && ui.selectable_label(false, "🎵 Play audio").clicked() {
261229
open_audio_file_in_default_application(tag, "wem");
262-
ui.close_menu();
230+
ui.close();
263231
}
264232
}
265233

266234
if ui
267235
.add_enabled(
268236
false,
269-
egui::SelectableLabel::new(false, "📤 Open in Alkahest"),
237+
egui::Button::selectable(false, "📤 Open in Alkahest"),
270238
)
271239
.clicked()
272240
{
273241
warn!("Alkahest IPC not implemented yet");
274-
ui.close_menu();
242+
ui.close();
275243
}
276244

277245
if ui.selectable_label(false, "📤 Open tag data").clicked() {
278246
open_tag_in_default_application(tag);
279-
ui.close_menu();
247+
ui.close();
280248
}
281249
}
282250

src/gui/external_file.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl ExternalFileScanView {
4343
}
4444
}
4545

46-
ui.output_mut(|o| o.copied_text = taglist);
46+
ui.ctx().copy_text(taglist);
4747
}
4848

4949
egui::ScrollArea::vertical().show_rows(ui, 22.0, self.file_hashes.len(), |ui, range| {

src/gui/hexview.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ impl TagHexView {
241241
0.0,
242242
Color32::from_white_alpha(30),
243243
Stroke::NONE,
244+
egui::StrokeKind::Middle,
244245
);
245246
}
246247

src/gui/mod.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ use std::rc::Rc;
2222
use std::sync::Arc;
2323
use std::sync::mpsc::Receiver;
2424

25-
use eframe::egui::{PointerButton, RichText, TextEdit, Widget};
25+
use eframe::egui::{CornerRadius, PointerButton, RichText, TextEdit, Widget};
2626
use eframe::egui_wgpu::RenderState;
2727
use eframe::{
2828
egui::{self},
2929
emath::Align2,
30-
epaint::{Color32, Rounding, Vec2},
30+
epaint::{Color32, Vec2},
3131
};
3232
use egui_notify::Toasts;
3333
use lazy_static::lazy_static;
@@ -130,10 +130,14 @@ pub struct QuickTagApp {
130130
impl QuickTagApp {
131131
/// Called once before the first frame.
132132
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
133+
cc.egui_ctx
134+
.options_mut(|o| o.theme_preference = egui::ThemePreference::Dark);
133135
let mut fonts = egui::FontDefinitions::default();
134136
fonts.font_data.insert(
135137
"Destiny_Keys".into(),
136-
egui::FontData::from_static(include_bytes!("../../Destiny_Keys.otf")),
138+
Arc::new(egui::FontData::from_static(include_bytes!(
139+
"../../Destiny_Keys.otf"
140+
))),
137141
);
138142

139143
fonts
@@ -230,7 +234,7 @@ impl eframe::App for QuickTagApp {
230234
let painter = ctx.layer_painter(egui::LayerId::background());
231235
painter.rect_filled(
232236
egui::Rect::EVERYTHING,
233-
Rounding::default(),
237+
CornerRadius::default(),
234238
Color32::from_black_alpha(127),
235239
);
236240
}
@@ -362,7 +366,7 @@ impl eframe::App for QuickTagApp {
362366

363367
egui::CentralPanel::default().show(ctx, |ui| {
364368
ui.add_enabled_ui(!is_loading_cache, |ui| {
365-
egui::menu::bar(ui, |ui| {
369+
egui::MenuBar::new().ui(ui, |ui| {
366370
ui.menu_button("File", |ui| {
367371
if ui.button("Scan file").clicked() {
368372
if let Ok(Some(selected_file)) = native_dialog::FileDialog::new()
@@ -384,12 +388,12 @@ impl eframe::App for QuickTagApp {
384388
self.open_panel = Panel::ExternalFile;
385389
}
386390

387-
ui.close_menu();
391+
ui.close();
388392
}
389393

390394
if ui.button("Regenerate Cache").clicked() {
391395
self.regenerate_cache();
392-
ui.close_menu();
396+
ui.close();
393397
}
394398
});
395399

src/gui/named_tags.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl View for NamedTagView {
7171
egui::RichText::new(fancy_tag).color(tagtype.display_color());
7272

7373
if ui
74-
.add(egui::SelectableLabel::new(false, tag_label))
74+
.add(egui::Button::selectable(false, tag_label))
7575
.tag_context(nt.hash)
7676
.clicked()
7777
{

src/gui/packages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl View for PackagesView {
177177
s.interaction.tooltip_delay = 0.0;
178178
});
179179
if ui
180-
.add(egui::SelectableLabel::new(
180+
.add(egui::Button::selectable(
181181
false,
182182
RichText::new(format!(
183183
"{i}: {label} ({})",

src/gui/raw_strings.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ impl View for RawStringsView {
131131

132132
response.on_hover_text(string).context_menu(|ui| {
133133
if ui.selectable_label(false, "Copy string").clicked() {
134-
ui.output_mut(|o| o.copied_text = string.clone());
135-
ui.close_menu();
134+
ui.ctx().copy_text(string.clone());
135+
ui.close();
136136
}
137137
});
138138
}
@@ -153,7 +153,7 @@ impl View for RawStringsView {
153153
let tag_type =
154154
TagType::from_type_subtype(e.file_type, e.file_subtype);
155155
if ui
156-
.add(egui::SelectableLabel::new(
156+
.add(egui::Button::selectable(
157157
false,
158158
RichText::new(label).color(tag_type.display_color()),
159159
))

0 commit comments

Comments
 (0)