Added ghost elements to avoid focusing on them
This commit is contained in:
@@ -51,14 +51,24 @@ pub fn app(screen: Arc<Screen>) -> Rsx {
|
|||||||
%count
|
%count
|
||||||
"This will increment every second: {count}"
|
"This will increment every second: {count}"
|
||||||
|
|
||||||
|
FlexRow
|
||||||
|
{
|
||||||
|
"Username"
|
||||||
@Transform::new().padding(1, 1).dimensions(40, 1);
|
@Transform::new().padding(1, 1).dimensions(40, 1);
|
||||||
@Style { foreground: Some(0xffffff), background: Background::RoundedOutline(0xff0000) };
|
@Style { foreground: Some(0xffffff), background: Background::RoundedOutline(0xff0000) };
|
||||||
|
@Focused;
|
||||||
Input { }
|
Input { }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transform::new().margin(0, 1);
|
||||||
|
FlexRow
|
||||||
|
{
|
||||||
|
"Password"
|
||||||
@Transform::new().padding(1, 1).dimensions(40, 1);
|
@Transform::new().padding(1, 1).dimensions(40, 1);
|
||||||
@Style { foreground: Some(0xffffff), background: Background::RoundedOutline(0xffff00) };
|
@Style { foreground: Some(0xffffff), background: Background::RoundedOutline(0xffff00) };
|
||||||
Input { }
|
Input { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ impl Element for Div {
|
|||||||
element.inject(|w| w.component(NoRenderRoot));
|
element.inject(|w| w.component(NoRenderRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ impl Element for FlexRow {
|
|||||||
element.inject(|w| w.component(NoRenderRoot));
|
element.inject(|w| w.component(NoRenderRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -123,6 +127,10 @@ impl Element for FlexCol {
|
|||||||
element.inject(|w| w.component(NoRenderRoot));
|
element.inject(|w| w.component(NoRenderRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ impl Element for Heading {
|
|||||||
self.children.push(element.clone());
|
self.children.push(element.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ impl Element for String {
|
|||||||
scope.draw_text(0, 0, self);
|
scope.draw_text(0, 0, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -7,6 +7,7 @@ use super::Extension;
|
|||||||
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyModifiers};
|
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyModifiers};
|
||||||
|
|
||||||
component!(AlwaysFocused);
|
component!(AlwaysFocused);
|
||||||
|
component!(Focused);
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
Left,
|
Left,
|
||||||
@@ -21,6 +22,14 @@ pub struct RelativeFocusExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Extension for RelativeFocusExtension {
|
impl Extension for RelativeFocusExtension {
|
||||||
|
fn init(&mut self, _ctx: &super::Context) {
|
||||||
|
for widget in _ctx.get_widgets().iter() {
|
||||||
|
if let Some(Focused) = widget.get() {
|
||||||
|
widget.set_focused(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &super::Context, event: &dyn super::Event) {
|
fn event(&mut self, ctx: &super::Context, event: &dyn super::Event) {
|
||||||
if let Some(e) = event.get::<CrosstermEvent>() {
|
if let Some(e) = event.get::<CrosstermEvent>() {
|
||||||
match e {
|
match e {
|
||||||
@@ -145,7 +154,7 @@ impl Extension for RelativeFocusExtension {
|
|||||||
if let Some(p) = ctx
|
if let Some(p) = ctx
|
||||||
.get_widgets()
|
.get_widgets()
|
||||||
.iter()
|
.iter()
|
||||||
.position(|w| Arc::ptr_eq(w, &widget))
|
.position(|w| Arc::ptr_eq(w, &widget) && !w.is_ghost())
|
||||||
{
|
{
|
||||||
rendered.lock().unwrap().push((p, t.x, t.y));
|
rendered.lock().unwrap().push((p, t.x, t.y));
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-4
@@ -31,11 +31,21 @@ pub type BoxedComponent = Box<dyn Component + Send + Sync>;
|
|||||||
pub trait Element: Send + Sync {
|
pub trait Element: Send + Sync {
|
||||||
/// Called to perform rendering for the element.
|
/// Called to perform rendering for the element.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn render(&mut self, scope: &mut RenderScope, render_context: &crate::render_scope::RenderContext) {}
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
scope: &mut RenderScope,
|
||||||
|
render_context: &crate::render_scope::RenderContext,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/// Called after rendering, for follow-up logic or cleanup.
|
/// Called after rendering, for follow-up logic or cleanup.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn after_render(&mut self, scope: &mut RenderScope, render_context: &crate::render_scope::RenderContext) {}
|
fn after_render(
|
||||||
|
&mut self,
|
||||||
|
scope: &mut RenderScope,
|
||||||
|
render_context: &crate::render_scope::RenderContext,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/// Called to draw child widgets, if any.
|
/// Called to draw child widgets, if any.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -44,6 +54,10 @@ pub trait Element: Send + Sync {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn event(&mut self, event: &dyn Event) {}
|
fn event(&mut self, event: &dyn Event) {}
|
||||||
|
|
||||||
|
fn is_ghost(&mut self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a type-erased reference to this object.
|
/// Returns a type-erased reference to this object.
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
|
||||||
@@ -138,10 +152,21 @@ impl Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_ghost(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Dynamic(w) => w.element.lock().unwrap().is_ghost(),
|
||||||
|
Self::Static(w) => w.element.lock().unwrap().is_ghost(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_focused(&self, f: bool) {
|
pub fn set_focused(&self, f: bool) {
|
||||||
match self {
|
match self {
|
||||||
Self::Dynamic(w) => *w.focused.lock().unwrap() = f,
|
Self::Dynamic(w) => {
|
||||||
Self::Static(w) => *w.focused.lock().unwrap() = f,
|
*w.focused.lock().unwrap() = f && !w.element.lock().unwrap().is_ghost()
|
||||||
|
}
|
||||||
|
Self::Static(w) => {
|
||||||
|
*w.focused.lock().unwrap() = f && !w.element.lock().unwrap().is_ghost()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user