Fix cursor focus and selection in input box, add AWS env var warning box, and remove AWS Bedrock login banner
This commit is contained in:
@@ -274,3 +274,5 @@ impl From<Option<AccessibilityContent>> for ActionAccessibilityContent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type WarpA11yRole = GalaxyA11yRole;
|
||||
|
||||
@@ -97,5 +97,5 @@ impl Element for Clipped {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "clipped_tests.rs"]
|
||||
#[path = "clipped_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -467,5 +467,5 @@ impl ScrollableElement for ClippedScrollable {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "clipped_scrollable_tests.rs"]
|
||||
#[path = "clipped_scrollable_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -445,5 +445,5 @@ impl SelectableElement for Container {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "container_tests.rs"]
|
||||
#[path = "container_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -367,5 +367,5 @@ impl Element for EventHandler {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "event_handler_tests.rs"]
|
||||
#[path = "event_handler_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -996,5 +996,5 @@ impl SelectableElement for Expanded {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "mod_tests.rs"]
|
||||
#[path = "mod_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -605,5 +605,5 @@ impl RunBuilder {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "wrap_tests.rs"]
|
||||
#[path = "wrap_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
use super::{
|
||||
FormattedTextElement, FrameMouseHandlers, HeadingFontSizeMultipliers, HighlightedHyperlink,
|
||||
HyperlinkSupport, LaidOutTextFrame, SecretRange,
|
||||
};
|
||||
use crate::text::BlockHeaderSize;
|
||||
use crate::{
|
||||
elements::{Point, SelectableElement, ZIndex},
|
||||
fonts::FamilyId,
|
||||
text_layout::TextFrame,
|
||||
};
|
||||
use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine};
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::{rect::RectF, vector::vec2f};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine};
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::rect::RectF;
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
use string_offset::ByteOffset;
|
||||
|
||||
use super::apply_secret_replacements;
|
||||
use super::{
|
||||
apply_secret_replacements, FormattedTextElement, FrameMouseHandlers,
|
||||
HeadingFontSizeMultipliers, HighlightedHyperlink, HyperlinkSupport, LaidOutTextFrame,
|
||||
SecretRange,
|
||||
};
|
||||
use crate::elements::{Point, SelectableElement, ZIndex};
|
||||
use crate::fonts::FamilyId;
|
||||
use crate::text::BlockHeaderSize;
|
||||
use crate::text_layout::TextFrame;
|
||||
|
||||
#[test]
|
||||
fn test_default_heading_font_size_multipliers() {
|
||||
|
||||
@@ -710,27 +710,24 @@ impl Element for Hoverable {
|
||||
|
||||
// The double-clicked handler takes precendence. However, we should still fall back to the single-click handler
|
||||
// on a double-click if there's no double-click handler set.
|
||||
if matches!(click_count, Some(2)) && self.double_click_handler.is_some() {
|
||||
let handler = self
|
||||
.double_click_handler
|
||||
.as_mut()
|
||||
.expect("handler should exist");
|
||||
handler(ctx, app, *position);
|
||||
ctx.notify();
|
||||
return true;
|
||||
} else if click_count.is_some() && self.click_handler.is_some() {
|
||||
let handler = self.click_handler.as_mut().expect("handler should exist");
|
||||
handler(ctx, app, *position);
|
||||
ctx.notify();
|
||||
return true;
|
||||
} else if click_count.is_some() && self.click_with_modifiers_handler.is_some() {
|
||||
let handler = self
|
||||
.click_with_modifiers_handler
|
||||
.as_mut()
|
||||
.expect("handler should exist");
|
||||
handler(ctx, app, *position, *modifiers);
|
||||
ctx.notify();
|
||||
return true;
|
||||
if matches!(click_count, Some(2)) {
|
||||
if let Some(handler) = self.double_click_handler.as_mut() {
|
||||
handler(ctx, app, *position);
|
||||
ctx.notify();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if click_count.is_some() {
|
||||
if let Some(handler) = self.click_handler.as_mut() {
|
||||
handler(ctx, app, *position);
|
||||
ctx.notify();
|
||||
return true;
|
||||
}
|
||||
if let Some(handler) = self.click_with_modifiers_handler.as_mut() {
|
||||
handler(ctx, app, *position, *modifiers);
|
||||
ctx.notify();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::MouseMoved {
|
||||
@@ -742,10 +739,8 @@ impl Element for Hoverable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Event::LeftMouseDragged { .. } => {
|
||||
if self.suppress_drag && self.state().is_clicked() {
|
||||
return true;
|
||||
}
|
||||
Event::LeftMouseDragged { .. } if self.suppress_drag && self.state().is_clicked() => {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -828,5 +823,5 @@ impl SelectableElement for Hoverable {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "hoverable_tests.rs"]
|
||||
#[path = "hoverable_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use pathfinder_geometry::vector::Vector2F;
|
||||
|
||||
use super::{
|
||||
AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext, Point,
|
||||
SizeConstraint,
|
||||
};
|
||||
use crate::event::DispatchedEvent;
|
||||
|
||||
/// A wrapper element that triggers periodic repaints at a fixed interval.
|
||||
///
|
||||
/// Wrap any child element in `LiveElement` to ensure the view repaints on a
|
||||
/// timer, which is useful for content that changes over time (e.g. an elapsed
|
||||
/// duration counter). The repaint cycle is self-sustaining: each `paint` call
|
||||
/// schedules the next repaint.
|
||||
pub struct LiveElement {
|
||||
child: Box<dyn Element>,
|
||||
repaint_interval: Duration,
|
||||
size: Option<Vector2F>,
|
||||
origin: Option<Point>,
|
||||
}
|
||||
|
||||
impl LiveElement {
|
||||
pub fn new(child: Box<dyn Element>, repaint_interval: Duration) -> Self {
|
||||
Self {
|
||||
child,
|
||||
repaint_interval,
|
||||
size: None,
|
||||
origin: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for LiveElement {
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
ctx: &mut LayoutContext,
|
||||
app: &AppContext,
|
||||
) -> Vector2F {
|
||||
let size = self.child.layout(constraint, ctx, app);
|
||||
self.size = Some(size);
|
||||
size
|
||||
}
|
||||
|
||||
fn after_layout(&mut self, ctx: &mut AfterLayoutContext, app: &AppContext) {
|
||||
self.child.after_layout(ctx, app);
|
||||
}
|
||||
|
||||
fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext, app: &AppContext) {
|
||||
self.child.paint(origin, ctx, app);
|
||||
self.origin = Some(Point::from_vec2f(origin, ctx.scene.z_index()));
|
||||
ctx.repaint_after(self.repaint_interval);
|
||||
}
|
||||
|
||||
fn size(&self) -> Option<Vector2F> {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn origin(&self) -> Option<Point> {
|
||||
self.origin
|
||||
}
|
||||
|
||||
fn dispatch_event(
|
||||
&mut self,
|
||||
event: &DispatchedEvent,
|
||||
ctx: &mut EventContext,
|
||||
app: &AppContext,
|
||||
) -> bool {
|
||||
self.child.dispatch_event(event, ctx, app)
|
||||
}
|
||||
|
||||
fn as_selectable_element(&self) -> Option<&dyn super::SelectableElement> {
|
||||
self.child.as_selectable_element()
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-util"))]
|
||||
fn debug_text_content(&self) -> Option<String> {
|
||||
self.child.debug_text_content()
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,6 @@ mod debug;
|
||||
mod dismiss;
|
||||
mod drag;
|
||||
|
||||
#[cfg(feature = "tui")]
|
||||
pub mod tui;
|
||||
pub mod drag_resize;
|
||||
mod empty;
|
||||
mod event_handler;
|
||||
@@ -20,6 +18,7 @@ mod hoverable;
|
||||
mod icon;
|
||||
mod image;
|
||||
mod list;
|
||||
mod live;
|
||||
mod min_size;
|
||||
pub mod new_scrollable;
|
||||
mod percentage;
|
||||
@@ -33,6 +32,8 @@ mod size_constraint_switch;
|
||||
mod stack;
|
||||
pub mod table;
|
||||
mod text;
|
||||
#[cfg(feature = "tui")]
|
||||
pub mod tui;
|
||||
mod uniform_list;
|
||||
mod viewported_list;
|
||||
|
||||
@@ -61,6 +62,7 @@ pub use hoverable::*;
|
||||
pub use icon::*;
|
||||
pub use image::*;
|
||||
pub use list::*;
|
||||
pub use live::*;
|
||||
pub use min_size::*;
|
||||
pub use new_scrollable::NewScrollable;
|
||||
use pathfinder_color::ColorU;
|
||||
|
||||
@@ -1586,5 +1586,5 @@ impl ClippedScrollStateHandle {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "scrollable_tests.rs"]
|
||||
#[path = "scrollable_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -157,5 +157,5 @@ pub(crate) fn scroll_delta_for_axis(
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "util_tests.rs"]
|
||||
#[path = "util_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_scroll_delta_for_axis_fully_into_view() {
|
||||
let mode = ScrollToPositionMode::FullyIntoView;
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Horizontal,
|
||||
RectF::new(vec2f(100., 0.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(400., 50.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
100.
|
||||
);
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Horizontal,
|
||||
RectF::new(vec2f(200., 0.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(100., 50.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
-100.
|
||||
);
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Horizontal,
|
||||
RectF::new(vec2f(100., 0.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(325., 50.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
25.
|
||||
);
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Horizontal,
|
||||
RectF::new(vec2f(100., 0.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(150., 50.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
0.
|
||||
);
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Horizontal,
|
||||
RectF::new(vec2f(100., 0.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 50.), vec2f(350., 50.)),
|
||||
mode,
|
||||
),
|
||||
0.
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scroll_delta_for_axis_top_into_view() {
|
||||
let mode = ScrollToPositionMode::TopIntoView;
|
||||
|
||||
// --- Element LARGER than the viewport ---
|
||||
|
||||
// Element taller than viewport, below viewport: align top with
|
||||
// viewport top.
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 400.), vec2f(50., 300.)),
|
||||
mode,
|
||||
),
|
||||
300.
|
||||
);
|
||||
|
||||
// Element taller than viewport, above viewport: align top with
|
||||
// viewport top.
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 200.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 100.), vec2f(50., 300.)),
|
||||
mode,
|
||||
),
|
||||
-100.
|
||||
);
|
||||
|
||||
// Element taller than viewport, top at viewport top: align top
|
||||
// (delta = 0).
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 100.), vec2f(50., 300.)),
|
||||
mode,
|
||||
),
|
||||
0.
|
||||
);
|
||||
|
||||
// Element taller than viewport, top visible but bottom extends
|
||||
// past: align top with viewport top (shows max content from top).
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 200.), vec2f(50., 300.)),
|
||||
mode,
|
||||
),
|
||||
100.
|
||||
);
|
||||
|
||||
// Element taller than viewport, spans entire viewport (top above,
|
||||
// bottom below): align top with viewport top.
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 50.), vec2f(50., 400.)),
|
||||
mode,
|
||||
),
|
||||
-50.
|
||||
);
|
||||
|
||||
// --- Element FITS in the viewport (delegates to FullyIntoView) ---
|
||||
|
||||
// Small element below viewport: scroll down (bottom to viewport
|
||||
// bottom).
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 400.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
100.
|
||||
);
|
||||
|
||||
// Small element above viewport: scroll up (top to viewport top).
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 200.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 100.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
-100.
|
||||
);
|
||||
|
||||
// Small element fully visible: no scroll.
|
||||
assert_eq!(
|
||||
scroll_delta_for_axis(
|
||||
Axis::Vertical,
|
||||
RectF::new(vec2f(0., 100.), vec2f(250., 250.)),
|
||||
RectF::new(vec2f(50., 150.), vec2f(50., 50.)),
|
||||
mode,
|
||||
),
|
||||
0.
|
||||
);
|
||||
}
|
||||
@@ -683,5 +683,5 @@ impl Element for Scrollable {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "scrollable_tests.rs"]
|
||||
#[path = "scrollable_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -149,5 +149,5 @@ impl Element for SizeConstraintSwitch {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "size_constraint_switch_tests.rs"]
|
||||
#[path = "size_constraint_switch_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -441,5 +441,5 @@ impl Extend<Box<dyn Element>> for Stack {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "mod_tests.rs"]
|
||||
#[path = "mod_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -887,5 +887,5 @@ impl Default for PositioningAxis<YAxisAnchor> {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "offset_positioning_tests.rs"]
|
||||
#[path = "offset_positioning_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -1436,5 +1436,5 @@ impl PartialClickableElement for Text {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "text_tests.rs"]
|
||||
#[path = "text_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -326,5 +326,5 @@ where
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "uniform_list_tests.rs"]
|
||||
#[path = "uniform_list_test.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -437,6 +437,7 @@ fn test_binding_description_eq_ignores_dynamic_override() {
|
||||
mod settings_value_tests {
|
||||
use settings_value::SettingsValue;
|
||||
|
||||
use crate::keymap::Keystroke;
|
||||
|
||||
#[test]
|
||||
fn test_keystroke_to_file_value_is_normalized_string() {
|
||||
|
||||
@@ -14,8 +14,6 @@ use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use galaxy_util::path::ShellFamily;
|
||||
|
||||
use anyhow::Result;
|
||||
pub use app::AppCallbacks;
|
||||
use async_task::Runnable;
|
||||
@@ -24,6 +22,7 @@ pub use file_picker::{
|
||||
FilePickerCallback, FilePickerConfiguration, FileType, SaveFilePickerCallback,
|
||||
SaveFilePickerConfiguration,
|
||||
};
|
||||
use galaxy_util::path::ShellFamily;
|
||||
use lazy_static::lazy_static;
|
||||
use pathfinder_geometry::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||
|
||||
Reference in New Issue
Block a user