android: update to latest winit/egui/android-activity

so we can start fixing this shit

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2025-01-28 16:33:35 -08:00
parent 267f3c4527
commit 51457a0260
25 changed files with 474 additions and 424 deletions

641
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -62,10 +62,6 @@ bincode = "1.3.3"
mime_guess = "2.0.5"
pretty_assertions = "1.4.1"
[patch.crates-io]
egui = { git = "https://github.com/damus-io/egui", branch = "update_layouter_0.29.1" }
epaint = { git = "https://github.com/damus-io/egui", branch = "update_layouter_0.29.1" }
[profile.small]
inherits = 'release'
opt-level = 'z' # Optimize for size
@@ -73,3 +69,12 @@ lto = true # Enable link-time optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations
panic = 'abort' # Abort on panic
strip = true # Strip symbols from binary*
[patch.crates-io]
egui = { git = "https://github.com/jb55/egui", rev = "03c769a3576920d5e33e01c06167e7c67d296625" }
eframe = { git = "https://github.com/jb55/egui", rev = "03c769a3576920d5e33e01c06167e7c67d296625" }
egui-winit = { git = "https://github.com/jb55/egui", rev = "03c769a3576920d5e33e01c06167e7c67d296625" }
egui_extras = { git = "https://github.com/jb55/egui", rev = "03c769a3576920d5e33e01c06167e7c67d296625" }
# on master was git = "https://github.com/damus-io/egui", branch = "update_layouter_0.29.1"
epaint = { git = "https://github.com/jb55/egui", rev = "03c769a3576920d5e33e01c06167e7c67d296625" }

View File

@@ -33,30 +33,13 @@ pub struct Notedeck {
unrecognized_args: BTreeSet<String>,
}
fn margin_top(narrow: bool) -> f32 {
#[cfg(target_os = "android")]
{
// FIXME - query the system bar height and adjust more precisely
let _ = narrow; // suppress compiler warning on android
40.0
}
#[cfg(not(target_os = "android"))]
{
if narrow {
50.0
} else {
0.0
}
}
}
/// Our chrome, which is basically nothing
fn main_panel(style: &egui::Style, narrow: bool) -> egui::CentralPanel {
fn main_panel(style: &egui::Style) -> egui::CentralPanel {
let inner_margin = egui::Margin {
top: margin_top(narrow),
left: 0.0,
right: 0.0,
bottom: 0.0,
top: 0,
left: 0,
right: 0,
bottom: 0,
};
egui::CentralPanel::default().frame(egui::Frame {
inner_margin,
@@ -73,7 +56,7 @@ impl eframe::App for Notedeck {
// handle account updates
self.accounts.update(&mut self.ndb, &mut self.pool, ctx);
main_panel(&ctx.style(), crate::ui::is_narrow(ctx)).show(ctx, |ui| {
main_panel(&ctx.style()).show(ctx, |ui| {
// render app
if let Some(app) = &self.app {
let app = app.clone();

View File

@@ -29,7 +29,7 @@ pub struct ColorTheme {
pub inactive_weak_bg_fill: Color32,
}
const WIDGET_ROUNDING: Rounding = Rounding::same(8.0);
const WIDGET_ROUNDING: Rounding = Rounding::same(8);
pub fn create_themed_visuals(theme: ColorTheme, default: Visuals) -> Visuals {
Visuals {
@@ -83,12 +83,12 @@ pub fn create_themed_visuals(theme: ColorTheme, default: Visuals) -> Visuals {
},
extreme_bg_color: theme.extreme_bg_color,
error_fg_color: theme.err_fg_color,
window_rounding: Rounding::same(8.0),
window_rounding: Rounding::same(8),
window_fill: theme.window_fill,
window_shadow: Shadow {
offset: [0.0, 8.0].into(),
blur: 24.0,
spread: 0.0,
offset: [0, 8],
blur: 24,
spread: 0,
color: egui::Color32::from_rgba_unmultiplied(0x6D, 0x6D, 0x6D, 0x14),
},
window_stroke: Stroke {

View File

@@ -23,7 +23,6 @@ public class MainActivity extends GameActivity {
protected void onCreate(Bundle savedInstanceState) {
// Shrink view so it does not get covered by insets.
/*
View content = getWindow().getDecorView().findViewById(android.R.id.content);
ViewCompat.setOnApplyWindowInsetsListener(content, (v, windowInsets) -> {
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
@@ -39,7 +38,6 @@ public class MainActivity extends GameActivity {
});
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
*/
super.onCreate(savedInstanceState);
}
@@ -48,11 +46,10 @@ public class MainActivity extends GameActivity {
public boolean onTouchEvent(MotionEvent event) {
// Offset the location so it fits the view with margins caused by insets.
/*
int[] location = new int[2];
findViewById(android.R.id.content).getLocationOnScreen(location);
event.offsetLocation(-location[0], -location[1]);
*/
return super.onTouchEvent(event);
}
}

View File

@@ -17,7 +17,7 @@ pub async fn android_main(app: AndroidApp) {
use tracing_subscriber::{prelude::*, EnvFilter};
std::env::set_var("RUST_BACKTRACE", "full");
std::env::set_var("RUST_LOG", "egui=trace");
std::env::set_var("RUST_LOG", "egui=trace,android_activity=debug");
//std::env::set_var(
// "RUST_LOG",

View File

@@ -23,9 +23,7 @@ impl<'a> AccountLoginView<'a> {
}
pub fn ui(&mut self, ui: &mut egui::Ui) -> InnerResponse<Option<AccountLoginResponse>> {
Frame::none()
.outer_margin(12.0)
.show(ui, |ui| self.show(ui))
Frame::new().outer_margin(12.0).show(ui, |ui| self.show(ui))
}
fn show(&mut self, ui: &mut egui::Ui) -> Option<AccountLoginResponse> {
@@ -123,7 +121,7 @@ fn login_textedit(manager: &mut AcquireKeyState) -> TextEdit {
)
.vertical_align(Align::Center)
.min_size(Vec2::new(0.0, 40.0))
.margin(Margin::same(12.0))
.margin(Margin::same(12))
};
let is_visible = manager.password_visible();

View File

@@ -36,7 +36,7 @@ impl<'a> AccountsView<'a> {
}
pub fn ui(&mut self, ui: &mut Ui) -> InnerResponse<Option<AccountsViewResponse>> {
Frame::none().outer_margin(12.0).show(ui, |ui| {
Frame::new().outer_margin(12.0).show(ui, |ui| {
if let Some(resp) = Self::top_section_buttons_widget(ui).inner {
return Some(resp);
}
@@ -135,7 +135,7 @@ fn show_profile_card(
let mut op: Option<ProfilePreviewAction> = None;
ui.add_sized(max_size, |ui: &mut egui::Ui| {
let mut frame = Frame::none();
let mut frame = Frame::new();
if is_selected || card_resp.hovered() {
frame = frame.fill(ui.visuals().noninteractive().weak_bg_fill);
}

View File

@@ -295,7 +295,7 @@ impl<'a> AddColumnView<'a> {
.vertical_align(Align::Center)
.desired_width(f32::INFINITY)
.min_size(Vec2::new(0.0, 40.0))
.margin(Margin::same(12.0))
.margin(Margin::same(12))
});
ui.add(text_edit);
@@ -315,10 +315,10 @@ impl<'a> AddColumnView<'a> {
{
egui::Frame::window(ui.style())
.outer_margin(Margin {
left: 4.0,
right: 4.0,
top: 12.0,
bottom: 32.0,
left: 4,
right: 4,
top: 12,
bottom: 32,
})
.show(ui, |ui| {
ProfilePreview::new(&profile, self.img_cache).ui(ui);
@@ -754,7 +754,7 @@ pub fn hashtag_ui(
.vertical_align(Align::Center)
.desired_width(f32::INFINITY)
.min_size(Vec2::new(0.0, 40.0))
.margin(Margin::same(12.0));
.margin(Margin::same(12));
ui.add(text_edit);
ui.add_space(8.0);

View File

@@ -252,7 +252,7 @@ impl<'a> NavTitle<'a> {
let x_range = ui.available_rect_before_wrap().x_range();
let is_dragging = egui::DragAndDrop::payload::<usize>(ui.ctx()).is_some(); // must be outside ui.dnd_drop_zone to capture properly
let (_, _) = ui.dnd_drop_zone::<usize, ()>(
egui::Frame::none().inner_margin(Margin::same(8.0)),
egui::Frame::new().inner_margin(Margin::same(8)),
|ui| {
let distances: Vec<(egui::Response, f32)> =
self.collect_column_distances(ui, id);
@@ -291,10 +291,10 @@ impl<'a> NavTitle<'a> {
ui: &mut egui::Ui,
id: egui::Id,
) -> Vec<(egui::Response, f32)> {
let y_margin = 4.0;
let item_frame = egui::Frame::none()
.rounding(egui::Rounding::same(8.0))
.inner_margin(Margin::symmetric(8.0, y_margin));
let y_margin: i8 = 4;
let item_frame = egui::Frame::new()
.rounding(egui::Rounding::same(8))
.inner_margin(Margin::symmetric(8, y_margin));
(0..self.columns.num_columns())
.filter_map(|col| {

View File

@@ -27,7 +27,7 @@ impl<'a> EditDeckView<'a> {
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<EditDeckResponse> {
let mut edit_deck_resp = None;
padding(egui::Margin::symmetric(16.0, 4.0), ui, |ui| {
padding(egui::Margin::symmetric(16, 4), ui, |ui| {
if ui.add(delete_button()).clicked() {
edit_deck_resp = Some(EditDeckResponse::Delete);
}

View File

@@ -50,7 +50,7 @@ pub fn padding<R>(
ui: &mut egui::Ui,
add_contents: impl FnOnce(&mut egui::Ui) -> R,
) -> egui::InnerResponse<R> {
egui::Frame::none()
egui::Frame::new()
.inner_margin(amount)
.show(ui, add_contents)
}

View File

@@ -94,11 +94,11 @@ pub fn render_note_preview(
*/
};
egui::Frame::none()
egui::Frame::new()
.fill(ui.visuals().noninteractive().weak_bg_fill)
.inner_margin(egui::Margin::same(8.0))
.outer_margin(egui::Margin::symmetric(0.0, 8.0))
.rounding(egui::Rounding::same(10.0))
.inner_margin(egui::Margin::same(8))
.outer_margin(egui::Margin::symmetric(0, 8))
.rounding(egui::Rounding::same(10))
.stroke(egui::Stroke::new(
1.0,
ui.visuals().noninteractive().bg_stroke.color,

View File

@@ -16,30 +16,22 @@ impl NoteContextSelection {
pub fn process(&self, ui: &mut egui::Ui, note: &Note<'_>) {
match self {
NoteContextSelection::CopyText => {
ui.output_mut(|w| {
w.copied_text = note.content().to_string();
});
ui.ctx().copy_text(note.content().to_string());
}
NoteContextSelection::CopyPubkey => {
ui.output_mut(|w| {
if let Some(bech) = Pubkey::new(*note.pubkey()).to_bech() {
w.copied_text = bech;
ui.ctx().copy_text(bech);
}
});
}
NoteContextSelection::CopyNoteId => {
ui.output_mut(|w| {
if let Some(bech) = NoteId::new(*note.id()).to_bech() {
w.copied_text = bech;
ui.ctx().copy_text(bech);
}
});
}
NoteContextSelection::CopyNoteJSON => {
ui.output_mut(|w| match note.json() {
Ok(json) => w.copied_text = json,
NoteContextSelection::CopyNoteJSON => match note.json() {
Ok(json) => ui.ctx().copy_text(json),
Err(err) => error!("error copying note json: {err}"),
});
}
},
}
}
}

View File

@@ -189,8 +189,8 @@ impl<'a, 'd> NoteView<'a, 'd> {
.response
}
pub fn expand_size() -> f32 {
5.0
pub fn expand_size() -> i8 {
5
}
fn pfp(
@@ -223,8 +223,8 @@ impl<'a, 'd> NoteView<'a, 'd> {
let (rect, size, resp) = ui::anim::hover_expand(
ui,
egui::Id::new((profile_key, note_key)),
pfp_size,
ui::NoteView::expand_size(),
pfp_size as f32,
ui::NoteView::expand_size() as f32,
anim_speed,
);
@@ -246,6 +246,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
resp
}
None => {
// This has to match the expand size from the above case to
// prevent bounciness
@@ -255,7 +256,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
ui.put(
rect,
ui::ProfilePic::new(self.note_context.img_cache, ui::ProfilePic::no_pfp_url())
.size(pfp_size),
.size(pfp_size as f32),
)
.interact(sense)
}
@@ -354,7 +355,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
let size = ui.available_size();
ui.vertical(|ui| {
ui.add_sized([size.x, self.options().pfp_size()], |ui: &mut egui::Ui| {
ui.add_sized([size.x, self.options().pfp_size() as f32], |ui: &mut egui::Ui| {
ui.horizontal_centered(|ui| {
NoteView::note_header(
ui,

View File

@@ -67,7 +67,7 @@ impl NoteOptions {
options
}
pub fn pfp_size(&self) -> f32 {
pub fn pfp_size(&self) -> i8 {
if self.has_small_pfp() {
ProfilePic::small_size()
} else if self.has_medium_pfp() {

View File

@@ -283,12 +283,12 @@ impl<'a, 'd> PostView<'a, 'd> {
self.id_source.unwrap_or_else(|| egui::Id::new("post"))
}
pub fn outer_margin() -> f32 {
16.0
pub fn outer_margin() -> i8 {
16
}
pub fn inner_margin() -> f32 {
12.0
pub fn inner_margin() -> i8 {
12
}
pub fn ui(&mut self, txn: &nostrdb::Transaction, ui: &mut egui::Ui) -> PostResponse {
@@ -308,9 +308,9 @@ impl<'a, 'd> PostView<'a, 'd> {
if focused {
frame = frame.shadow(egui::epaint::Shadow {
offset: egui::vec2(0.0, 0.0),
blur: 8.0,
spread: 0.0,
offset: [0, 0],
blur: 8,
spread: 0,
color: stroke.color,
});
}
@@ -327,8 +327,7 @@ impl<'a, 'd> PostView<'a, 'd> {
context_selection = Frame::none()
.show(ui, |ui| {
ui.vertical(|ui| {
let set_width = avail_size.x * 0.8;
ui.set_max_width(set_width);
ui.set_max_width(avail_size.x * 0.8);
let resp = render_note_preview(
ui,
self.note_context,
@@ -346,8 +345,8 @@ impl<'a, 'd> PostView<'a, 'd> {
});
}
Frame::none()
.inner_margin(Margin::symmetric(0.0, 8.0))
Frame::new()
.inner_margin(Margin::symmetric(0, 8))
.show(ui, |ui| {
ScrollArea::horizontal().show(ui, |ui| {
ui.with_layout(Layout::left_to_right(egui::Align::Min), |ui| {

View File

@@ -54,13 +54,12 @@ impl<'a, 'd> PostReplyView<'a, 'd> {
// This is the offset of the post view's pfp. We use this
// to indent things so that the reply line is aligned
let pfp_offset = ui::PostView::outer_margin()
let pfp_offset: i8 = ui::PostView::outer_margin()
+ ui::PostView::inner_margin()
+ ui::ProfilePic::small_size() / 2.0;
+ ui::ProfilePic::small_size() / 2;
let note_offset = pfp_offset
- ui::ProfilePic::medium_size() / 2.0
- ui::NoteView::expand_size() / 2.0;
let note_offset: i8 =
pfp_offset - ui::ProfilePic::medium_size() / 2 - ui::NoteView::expand_size() / 2;
let selection = egui::Frame::none()
.outer_margin(egui::Margin::same(note_offset))
@@ -103,14 +102,14 @@ impl<'a, 'd> PostReplyView<'a, 'd> {
// Position the line right above the poster's profile pic in
// the post box. Use the PostView's margin values to
// determine this offset.
rect.min.x = avail_rect.min.x + pfp_offset;
rect.min.x = avail_rect.min.x + pfp_offset as f32;
// honestly don't know what the fuck I'm doing here. just trying
// to get the line under the profile picture
rect.min.y = avail_rect.min.y
+ (ui::ProfilePic::medium_size() / 2.0
+ ui::ProfilePic::medium_size()
+ ui::NoteView::expand_size() * 2.0)
+ (ui::ProfilePic::medium_size() as f32 / 2.0
+ ui::ProfilePic::medium_size() as f32
+ ui::NoteView::expand_size() as f32 * 2.0)
+ 1.0;
// For some reason we need to nudge the reply line's height a
@@ -125,7 +124,7 @@ impl<'a, 'd> PostReplyView<'a, 'd> {
3.0
};
rect.max.y = rect_before_post.max.y + ui::PostView::outer_margin() + nudge;
rect.max.y = rect_before_post.max.y + ui::PostView::outer_margin() as f32 + nudge;
ui.painter().vline(
rect.left(),

View File

@@ -142,7 +142,7 @@ fn singleline_textedit(data: &mut String) -> impl egui::Widget + '_ {
TextEdit::singleline(data)
.min_size(vec2(0.0, 40.0))
.vertical_align(egui::Align::Center)
.margin(Margin::symmetric(12.0, 10.0))
.margin(Margin::symmetric(12, 10))
.desired_width(f32::INFINITY)
}
@@ -150,13 +150,13 @@ fn multiline_textedit(data: &mut String) -> impl egui::Widget + '_ {
TextEdit::multiline(data)
// .min_size(vec2(0.0, 40.0))
.vertical_align(egui::Align::TOP)
.margin(Margin::symmetric(12.0, 10.0))
.margin(Margin::symmetric(12, 10))
.desired_width(f32::INFINITY)
.desired_rows(1)
}
fn in_frame(ui: &mut egui::Ui, contents: impl FnOnce(&mut egui::Ui)) {
egui::Frame::none().show(ui, |ui| {
egui::Frame::new().show(ui, |ui| {
ui.spacing_mut().item_spacing = egui::vec2(0.0, 8.0);
contents(ui);
});
@@ -164,7 +164,7 @@ fn in_frame(ui: &mut egui::Ui, contents: impl FnOnce(&mut egui::Ui)) {
fn button(text: &str, width: f32) -> egui::Button<'static> {
Button::new(text)
.rounding(Rounding::same(8.0))
.rounding(Rounding::same(8))
.min_size(vec2(width, 40.0))
}

View File

@@ -154,14 +154,13 @@ impl<'a, 'd> ProfileView<'a, 'd> {
);
if ui.add(copy_key_widget(&pfp_rect)).clicked() {
ui.output_mut(|w| {
w.copied_text = if let Some(bech) = self.pubkey.to_bech() {
let to_copy = if let Some(bech) = self.pubkey.to_bech() {
bech
} else {
error!("Could not convert Pubkey to bech");
String::new()
}
});
};
ui.ctx().copy_text(to_copy)
}
if self.accounts.contains_full_kp(self.pubkey) {
@@ -244,7 +243,7 @@ fn copy_key_widget(pfp_rect: &egui::Rect) -> impl egui::Widget + '_ {
Sense::click(),
);
let copy_key_rounding = Rounding::same(100.0);
let copy_key_rounding = Rounding::same(100);
let fill_color = if resp.hovered() {
ui.visuals().widgets.inactive.weak_bg_fill
} else {
@@ -281,7 +280,7 @@ fn edit_profile_button() -> impl egui::Widget + 'static {
painter.rect_filled(
rect,
Rounding::same(8.0),
Rounding::same(8),
if resp.hovered() {
ui.visuals().widgets.active.bg_fill
} else {
@@ -290,7 +289,7 @@ fn edit_profile_button() -> impl egui::Widget + 'static {
);
painter.rect_stroke(
rect.shrink(1.0),
Rounding::same(8.0),
Rounding::same(8),
if resp.hovered() {
ui.visuals().widgets.active.bg_stroke
} else {

View File

@@ -23,7 +23,7 @@ impl egui::Widget for ProfilePic<'_, '_> {
impl<'cache, 'url> ProfilePic<'cache, 'url> {
pub fn new(cache: &'cache mut Images, url: &'url str) -> Self {
let size = Self::default_size();
let size = Self::default_size() as f32;
ProfilePic {
cache,
url,
@@ -48,18 +48,18 @@ impl<'cache, 'url> ProfilePic<'cache, 'url> {
}
#[inline]
pub fn default_size() -> f32 {
38.0
pub fn default_size() -> i8 {
38
}
#[inline]
pub fn medium_size() -> f32 {
32.0
pub fn medium_size() -> i8 {
32
}
#[inline]
pub fn small_size() -> f32 {
24.0
pub fn small_size() -> i8 {
24
}
#[inline]
@@ -194,7 +194,7 @@ mod preview {
let (rect, size, _resp) = ui::anim::hover_expand(
ui,
egui::Id::new(profile.key().unwrap()),
ui::ProfilePic::default_size(),
ui::ProfilePic::default_size() as f32,
expand_size,
anim_speed,
);

View File

@@ -89,7 +89,7 @@ impl<'a, 'cache> SimpleProfilePreview<'a, 'cache> {
impl egui::Widget for SimpleProfilePreview<'_, '_> {
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
Frame::none()
Frame::new()
.show(ui, |ui| {
ui.add(ProfilePic::new(self.cache, get_profile_url(self.profile)).size(48.0));
ui.vertical(|ui| {

View File

@@ -76,10 +76,10 @@ impl<'a> RelayView<'a> {
relay_frame(ui).show(ui, |ui| {
ui.horizontal(|ui| {
ui.with_layout(Layout::left_to_right(Align::Center), |ui| {
Frame::none()
Frame::new()
// This frame is needed to add margin because the label will be added to the outer frame first and centered vertically before the connection status is added so the vertical centering isn't accurate.
// TODO: remove this hack and actually center the url & status at the same time
.inner_margin(Margin::symmetric(0.0, 4.0))
.inner_margin(Margin::symmetric(0, 4))
.show(ui, |ui| {
egui::ScrollArea::horizontal()
.id_salt(index)
@@ -159,7 +159,7 @@ impl<'a> RelayView<'a> {
.vertical_align(Align::Center)
.desired_width(f32::INFINITY)
.min_size(Vec2::new(0.0, 40.0))
.margin(Margin::same(12.0));
.margin(Margin::same(12));
ui.add(text_edit);
ui.add_space(8.0);
if ui
@@ -218,8 +218,8 @@ fn delete_button(_dark_mode: bool) -> egui::Button<'static> {
}
fn relay_frame(ui: &mut Ui) -> Frame {
Frame::none()
.inner_margin(Margin::same(8.0))
Frame::new()
.inner_margin(Margin::same(8))
.rounding(ui.style().noninteractive().rounding)
.stroke(ui.style().visuals.noninteractive().bg_stroke)
}
@@ -238,10 +238,10 @@ fn show_connection_status(ui: &mut Ui, status: RelayStatus) {
RelayStatus::Disconnected => "Not Connected",
};
let frame = Frame::none()
.rounding(Rounding::same(100.0))
let frame = Frame::new()
.rounding(Rounding::same(100))
.fill(bg_color)
.inner_margin(Margin::symmetric(12.0, 4.0));
.inner_margin(Margin::symmetric(12, 4));
frame.show(ui, |ui| {
ui.label(RichText::new(label_text).color(fg_color));

View File

@@ -83,7 +83,7 @@ impl<'a> DesktopSidePanel<'a> {
}
pub fn show(&mut self, ui: &mut egui::Ui) -> SidePanelResponse {
let mut frame = egui::Frame::none().inner_margin(Margin::same(8.0));
let mut frame = egui::Frame::new().inner_margin(Margin::same(8));
if !ui.visuals().dark_mode {
frame = frame.fill(colors::ALMOST_WHITE);

View File

@@ -60,9 +60,7 @@ impl<'a> SupportView<'a> {
ui.add(Label::new("Press the button below to copy your most recent logs to your system's clipboard. Then paste it into your email.").wrap());
ui.allocate_ui_with_layout(size, Layout::top_down(egui::Align::Center), |ui| {
if ui.add(copy_button).clicked() {
ui.output_mut(|w| {
w.copied_text = logs.to_string();
});
ui.ctx().copy_text(logs.to_string());
}
});
});