mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
fix(client): ConnectScreen as 26.3 draws it, with Cancel
Joining a server showed a flat dark fill with the status and the address. ConnectScreen draws the menu background over the blurred panorama, the status centred at height / 2 - 50, and a 200-wide Cancel at height / 4 + 132 that aborts the connection and goes back; Escape does nothing there (shouldCloseOnEsc is false). Once logged in, the LevelLoadingScreen's Loading terrain takes over until the player is placed.
This commit is contained in:
1 parent
795490271d
commit
752fc2170a
3 files changed
+73
-20
No files matched your search
@@ -11634,7 +11634,8 @@ impl Game<'_> {
|
||||
let mut hud = horizon_client::spans::time("hud", || self.hud(size));
|
||||
// LevelLoadingScreen (Reason.OTHER) draws the title's panorama.
|
||||
let title = self.title.is_some()
|
||||
|| self.loading_reason() == Some(horizon_client::level_loading::Reason::Other);
|
||||
|| self.loading_reason() == Some(horizon_client::level_loading::Reason::Other)
|
||||
|| self.remote_loading();
|
||||
let (yaw, pitch) = if title {
|
||||
// PanoramaRenderer: the title cube spins at 0.1 degrees per tick, pitched 10 degrees.
|
||||
(
|
||||
@@ -11927,7 +11928,8 @@ impl Game<'_> {
|
||||
/// `Screen.extractBlurredBackground` over the panorama or the world and
|
||||
/// HUD, when `menuBackgroundBlurriness` is at least 1.
|
||||
fn menu_blur(&self) -> Option<f32> {
|
||||
let loading = self.loading_reason() == Some(horizon_client::level_loading::Reason::Other);
|
||||
let loading = self.loading_reason() == Some(horizon_client::level_loading::Reason::Other)
|
||||
|| self.remote_loading();
|
||||
let blurred = loading
|
||||
|| self.title.as_ref().is_some_and(|t| {
|
||||
matches!(self.screen, Screen::Options | Screen::Win)
|
||||
@@ -12800,6 +12802,12 @@ impl ApplicationHandler for Game<'_> {
|
||||
self.dialog_click()?;
|
||||
}
|
||||
}
|
||||
// ConnectScreen's Cancel, under the prompts and dialogs above.
|
||||
WindowEvent::MouseInput { state, button, .. } if self.remote_loading() => {
|
||||
if state == ElementState::Pressed && button == MouseButton::Left {
|
||||
self.connect_screen_click()?;
|
||||
}
|
||||
}
|
||||
WindowEvent::MouseInput { .. } if self.screen == Screen::Win => {}
|
||||
WindowEvent::MouseInput { state, button, .. } if self.screen == Screen::Options => {
|
||||
if self.options_waiting_for_key() && state == ElementState::Pressed {
|
||||
|
||||
@@ -14,7 +14,7 @@ use horizon_client::{
|
||||
chunk::Chunk,
|
||||
containers::{BlockEntity, Furnace, FurnaceKind},
|
||||
entities::{Experience, ExperienceOrb, ItemEntity},
|
||||
hud::{HudBatch, rgba},
|
||||
hud::HudBatch,
|
||||
items::ItemStack,
|
||||
menu::Input,
|
||||
mobs::{Mob, MobType, Who},
|
||||
@@ -5862,26 +5862,42 @@ impl Game<'_> {
|
||||
}
|
||||
let atlas = &self.gui.atlas;
|
||||
let (w, h) = (batch.width, batch.height);
|
||||
batch.fill(atlas, 0.0, 0.0, w, h, rgba(20, 20, 20, 255));
|
||||
let shown = horizon_client::net::shown_address(&r.session.address);
|
||||
for (i, line) in [r.status.as_str(), shown.as_str()].iter().enumerate() {
|
||||
let tw = HudBatch::text_width(atlas, line);
|
||||
batch.text(
|
||||
atlas,
|
||||
line,
|
||||
(w - tw) / 2.0,
|
||||
h / 2.0 - 12.0 + i as f32 * 12.0,
|
||||
if i == 0 {
|
||||
u32::MAX
|
||||
} else {
|
||||
rgba(160, 160, 160, 255)
|
||||
},
|
||||
true,
|
||||
);
|
||||
if r.joined {
|
||||
// LevelLoadingScreen: the world's terrain comes in.
|
||||
horizon_client::ui::menu_background(batch, atlas, 0.0, 0.0, w, h, false);
|
||||
horizon_client::level_loading::draw(batch, atlas, None, None);
|
||||
return true;
|
||||
}
|
||||
let _ = r.joined;
|
||||
let cancel = self.connect_cancel((w, h)).is_some();
|
||||
let status = horizon_client::text::Text::literal(r.status.as_str());
|
||||
horizon_client::level_loading::draw_connecting(batch, atlas, &status, self.cursor, cancel);
|
||||
true
|
||||
}
|
||||
/// Connected or connecting with no player yet: `ConnectScreen`, then
|
||||
/// `LevelLoadingScreen`, over the panorama with its blur.
|
||||
pub(super) fn remote_loading(&self) -> bool {
|
||||
self.remote.is_some() && self.player.is_none()
|
||||
}
|
||||
/// `ConnectScreen`'s Cancel: a server's (single player's server isn't
|
||||
/// joined through `ConnectScreen`), until the login is done.
|
||||
fn connect_cancel(&self, (w, h): (f32, f32)) -> Option<(f32, f32)> {
|
||||
let r = self.remote.as_ref()?;
|
||||
(self.player.is_none() && !r.joined && self.integrated.is_none())
|
||||
.then(|| horizon_client::level_loading::connect_cancel(w, h))
|
||||
}
|
||||
/// A click on `ConnectScreen`: Cancel aborts the connection
|
||||
/// (`connect.aborted`) and goes back. Escape does nothing there
|
||||
/// (`shouldCloseOnEsc` is false).
|
||||
pub(super) fn connect_screen_click(&mut self) -> Result<()> {
|
||||
let Some((x, y)) = self.connect_cancel(self.gui_size()) else {
|
||||
return Ok(());
|
||||
};
|
||||
if horizon_client::ui::hovered(self.cursor, x, y, 200.0, 20.0) {
|
||||
self.audio.play_button_click();
|
||||
self.leave_server(None)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// The server's death message; chat uses the shared ChatComponent.
|
||||
pub(super) fn remote_hud(&self, batch: &mut HudBatch) {
|
||||
let Some(r) = &self.remote else { return };
|
||||
|
||||
@@ -136,6 +136,35 @@ pub fn draw_progress(batch: &mut HudBatch, atlas: &HudAtlas, line: &str, progres
|
||||
batch.fill(atlas, left, top, done, 2.0, opaque(0x00FF00));
|
||||
}
|
||||
|
||||
/// `ConnectScreen`'s Cancel button corner on a GUI `w` x `h`:
|
||||
/// (width / 2 - 100, height / 4 + 120 + 12), 200 x 20.
|
||||
pub fn connect_cancel(w: f32, h: f32) -> (f32, f32) {
|
||||
((w / 2.0).trunc() - 100.0, (h / 4.0).trunc() + 132.0)
|
||||
}
|
||||
|
||||
/// `ConnectScreen.extractRenderState` over the menu background: the status
|
||||
/// centred at (width / 2, height / 2 - 50) and, while the connection can
|
||||
/// still be cancelled, Cancel.
|
||||
pub fn draw_connecting(
|
||||
batch: &mut HudBatch,
|
||||
atlas: &HudAtlas,
|
||||
status: &Text,
|
||||
cursor: (f32, f32),
|
||||
cancel: bool,
|
||||
) {
|
||||
let (w, h) = (batch.width, batch.height);
|
||||
crate::ui::menu_background(batch, atlas, 0.0, 0.0, w, h, false);
|
||||
let tw = atlas.font.width_text(status);
|
||||
let (x, y) = (((w - tw) / 2.0).trunc(), (h / 2.0).trunc() - 50.0);
|
||||
batch.text_styled(atlas, status, x, y, u32::MAX, true);
|
||||
if cancel {
|
||||
let (x, y) = connect_cancel(w, h);
|
||||
let hover = crate::ui::hovered(cursor, x, y, 200.0, 20.0);
|
||||
let label = Text::translate("gui.cancel", &[]);
|
||||
crate::ui::button(batch, atlas, x, y, 200.0, 20.0, &label, true, hover);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in new issue
Block a user