Introduction to Widgets
ウィジェットは、Ratatuiのユーザーインターフェイスの構成要素です。それらは、ターミナルインターフェイスのレイアウトとスタイルを作成および管理するために使用されます。ウィジェットを組み合わせてネストして複雑なUIを作成することができ、アプリケーションのニーズに合わせて簡単にカスタマイズできます。
Ratatuiは、UISをすばやく作成するために使用できるさまざまな内蔵ウィジェットを提供します。これらのウィジェットには次のものが含まれます。
さらに、[String
], [&str
], [Span
], [Line
], [Text
] はウィーゲットとして使用できます (ただし、これらの直接の代わりに Paragraph
を使用することは一般的です) 。
これらのウィジェットの詳細については、[ウィジェットAPI Docs] [Widgets-Docs]と[Widget Showcase] [Showcase]を表示できます。さらに、Ratatuiで使用できるサードパーティのウィジェットがいくつかあります。これは、[サードパーティのウィジェットショーケース] [サードパーティ-widgets]および[Awesome Ratatui]リポジトリにあります。
ウィジェットtrait
Ratatuiでは、ウィジェットがRust trait として実装されており、実装と拡張が容易になります。ウィジェットの2つの主なtrait は、[Widget
]と[StatefulWidget
]です。これは、ウィジェットの状態をレンダリングおよび管理するための基本的な機能を提供します。
さらに、[WidgetRef
]および[StatefulWidgetRef
]trait により、ウィジェットを参照してレンダリングすることができます。これは、ウィジェットのコレクションを保存およびレンダリングするのに役立ちます。後者の2つのtrait は、Ratatui 0.26に追加され、執筆時点で、不安定な特徴フラグで格付けされているため、これらのtrait の第三者の使用は限られている可能性があります。すべての内部ウィジェットがREFtrait を実装するために更新されており、 Widget for &T where T: WidgetRef
のブランケット実装もあります。
ウィジェット
[Widget
]trait は、Ratatuiのウィジェットの最も基本的なtrait です。ウィジェットをバッファーにレンダリングするための基本的な機能を提供します。
pub trait Widget { fn render(self, area: Rect, buf: &mut Buffer);}
Statefulwidget
[StatefulWidget
]trait は、[Widget
]trait に似ていますが、レンダリング中に管理および更新できる状態も含まれます。
pub trait StatefulWidget { type State; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State);}
WidgetRefとStateful Widget Ref
[WidgetRef
]trait により、ウィジェットを消費する代わりに参照ごとにウィジェットをレンダリングできます。これは、個人やコレクションの保存とレンダリングに役立ちます。
[StatefulWidgetRef
]trait は、[WidgetRef
]trait に似ていますが、レンダリング中に管理および更新できる状態も含まれます。
これらの2つのtrait は、Ratatui 0.26.0で導入され、以前にその仮定で構築されたすべてのコードを壊すわけではなく、ウィジェットが常にレンダリングで消費されることを意味する欠点を避けるのに役立ちました。これらの2つのウィジェットは現在、不安定であるとマークされており、 unstable-widget-ref
機能フラグの背後にゲートされています。
pub trait WidgetRef { fn render_ref(&self, area: Rect, buf: &mut Buffer);}
pub trait StatefulWidgetRef { type State; fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State);}
ウィジェットを使用します
Ratatuiでは、ターミナルインターフェイスのレイアウトとスタイルを作成および管理するためにウィジェットが使用されます。ウィジェットを組み合わせてネストして複雑なUIを作成することができ、アプリケーションのニーズに合わせて簡単にカスタマイズできます。
アプリケーションでウィジェットを使用するには、通常、[Frame
]タイプを使用します。これには、ウィジェットをレンダリングする2つの方法があります: [render_widget
]と[render_stateful_widget
] (および対応する _ref
メソッド) 。これらのメソッドは、ウィジェットを描画するアプリケーションのエントリポイントであり、通常、[Terminal::draw
]メソッドに渡される閉鎖から呼び出されます。
render_widget
メソッドを使用してウィジェットを描画する例は次のとおりです。
terminal.draw(|frame| { frame.render_widget(some_widget, frame.area());});
そして、 render_stateful_widget
メソッドを使用してStatefulwidgetを描画する例を次に示します。
terminal.draw(|frame| { frame.render_stateful_widget(some_stateful_widget, frame.area(), &mut some_state);});
これらの方法は、[Widget
]または[StatefulWidget
]のtrait の render
関数を内部的に呼び出します。
一般的な構成パターンは、 Frame::render_widget()
に渡され、その後のウィジェット内で渡される単一のルートウィジェット (以下の例の App
struct) のみを持っていることです。ウィジェットへ。
#[derive(Default)]struct App { // ... should_quit: bool}
fn main() { let app = App::default(); // ... while !app.should_quit { terminal.draw(|frame| { frame.render_widget(&app, frame.area()) }) }}
impl Widget for &App { fn render(self, area: Rect, buf: &mut Buffer) { // ... MyHeaderWidget::new("Header text") .render(Rect::new(0, 0, area.width, 1), buf); }}
ウィジェットの実装
Ratatuiでは、ウィジェットがRust trait として実装されており、実装と拡張が容易になります。ウィジェットの2つの主なtrait は、[Widget
]と[StatefulWidget
]です。これは、ウィジェットの状態をレンダリングおよび管理するための基本的な機能を提供します。
簡単なグリーティングウィジェットの[Widget
]のtrait を実装する例を次に示します。
struct GreetingWidget { name: String,}
impl Widget for GreetingWidget { fn render(self, area: Rect, buf: &mut Buffer) { let greeting = format!("Hello, {}!", self.name); buf.set_string(area.x, area.y, greeting, Style::default()); }}
この例では、 GreetingWidget
structには、 String
である単一のフィールド name
があります。 render
関数は、 Rect
と Buffer
への可変参照を取り、バッファ内の指定された座標に文字列を設定します。
ウィジェットは、 Buffer
でメソッドを呼び出すだけに制限されていません。また、 render
メソッド内で他のウィジェットを作成およびレンダリングすることもできます。たとえば、 buf
でメソッドを直接呼び出す代わりに、ウィジェットは Span
のベクトルを持つ Line
ウィジェットを作成できます。ここで、名前の Span
この Line
ウィジェットは、ウィジェットの render
メソッド内でレンダリングできます。
ネストされたウィジェットを使用した同じ挨拶の例です。
struct GreetingWidget { name: String,}
impl Widget for GreetingWidget { fn render(self, area: Rect, buf: &mut Buffer) { let hello = Span::raw("Hello, "); let name = Span::styled(self.name, Modifier::BOLD); let line = Line::from(vec![hello, name]); line.render(area, buf); }}
このアプローチにより、ウィジェットを作成して再利用できます。たとえば、 Line
ウィジェットは、他のウィジェットやアプリケーションの他の部分でも使用できます。さらに、レンダリングに関連するコードが一貫した場所 ( impl Widget
ブロック) で編成されるため、ウィジェットのテストとメンテナンスを容易にすることができます。
ステートフルウィジェットの実装
状況によっては、ウィジェットが自分自身をレンダリングしながら余分な状態を変異させることができる必要がある場合があります。この例は、内蔵 List
ウィジェットがどのように機能するかです。レンダリング中、 List
は状態内のスクロール位置を更新して、選択したアイテムがレンダリングエリアに表示されるようにします。
フレームカウントウィジェットの StatefulWidget
trait を実装する例は次のとおりです。
struct FrameCountWidget { style: Style,}
impl StatefulWidget for FrameCountWidget { type State = i32;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut i32) { *state += 1; let text = format!("Frame count: {state}"); Line::styled(text, self.style).render(area, buf); }}
この例では、 FrameCount
ウィジェットがレンダリングされるたびに状態を増やし、フレーム数をカウントします。
WidgetRefの実装
Ratatui 0.26.0では、[WidgetRef
] (および同様に[StatefulWidgetRef
]) trait を追加しました。これらにより、参照によってレンダリングされるウィジェットを作成できます。これは、すべてのフレームで構築する代わりに複数回レンダリングできるウィジェットを保存するのに役立ちます。また、 Box<dyn T>
を使用してウィジェットをボクシングすることにより、ウィジェットの動的コレクション (レイアウトのペインなど) を簡単に作成できます。
WidgetRef
/ StatefulWidgetRef
の実装は、trait の消費バージョンの実装に似ています (違いは、メソッド名が render_ref
であり、自己は参照であるということです) 。
struct GreetingWidget { name: String,}
impl WidgetRef for GreetingWidget { fn render_ref(&self, area: Rect, buf: &mut Buffer) { let hello = Span::raw("Hello, "); let name = Span::styled(self.name, Modifier::BOLD); let line = Line::from(vec![hello, name]); line.render(area, buf); }}
これは、フレーム間にウィジェットを保存する方法として役立ちます。例えば。:
struct App { greeting: GreetingWidget,}
// and then later:
frame.render_widget_ref(&app.greeting, area);
さまざまなタイプのウィジェットのコレクション、またはコンパイル時間に既知のタイプを持たない単一のウィジェットがある状況では、REFのtrait により、[Box<T>
]を使用してウィジェットをtrait オブジェクトとして保存することができます。
例えば。次のコードは、 Vec
に2つの異なるウィジェットが保存されている方法を示しています。
struct Greeting { ... }struct Farewell { ... }impl WidgetRef for Greeting { ... }impl WidgetRef for Farewell { ... }
let widgets: Vec<Box<dyn WidgetRef>> = vec![ Box::new(Greeting { name: "alice".into() }), Box::new(Farewell { name: "bob".into() })];for widget in widgets { widget.render_ref(area, buf);}
[Widget
]: https://docs.rs/ratatui/latest/ratatui/widgets/trait .Widget.html
[StatefulWidget
]: https://docs.rs/ratatui/latest/ratatui/widgets/trait .StatefulWidget.html
[WidgetRef
]: https://docs.rs/ratatui/latest/ratatui/widgets/trait .WidgetRef.html
[StatefulWidgetRef
]: https://docs.rs/ratatui/latest/ratatui/widgets/trait .StatefulWidgetRef.html
Block
: https://docs.rs/ratatui/latest/ratatui/widgets/block/struct.Block.html
BarChart
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.BarChart.html
Calendar
: https://docs.rs/ratatui/latest/ratatui/widgets/calendar/struct.Monthly.html
Canvas
: https://docs.rs/ratatui/latest/ratatui/widgets/canvas/struct.Canvas.html
Chart
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Chart.html
Clear
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Clear.html
Gauge
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Gauge.html
LineGauge
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.LineGauge.html
List
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.List.html
Paragraph
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html
Scrollbar
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Scrollbar.html
Sparkline
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Sparkline.html
Table
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Table.html
Tabs
: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Tabs.html
[String
]: https://doc.rust-lang.org/std/string/struct.String.html
[&str
]: https://doc.rust-lang.org/std/primitive.str.html
[Line
]: https://docs.rs/ratatui/latest/ratatui/text/struct.Line.html
[Span
]: https://docs.rs/ratatui/latest/ratatui/text/struct.Span.html
[Text
]: https://docs.rs/ratatui/latest/ratatui/text/struct.Text.html
[Box<T>
]: https://doc.rust-lang.org/std/boxed/struct.Box.html
[showcase]: https://ratatui.rs/showcase/widgets/
[third-party-widgets]: https://ratatui.rs/showcase/third-party-widgets/
[widgets-docs]: https://docs.rs/ratatui/latest/ratatui/widgets/index.html
[Frame
]: https://docs.rs/ratatui/latest/ratatui/struct.Frame.html
[render_widget
]: https://docs.rs/ratatui/latest/ratatui/struct.Frame.html#method.render_widget
[render_stateful_widget
]: https://docs.rs/ratatui/latest/ratatui/struct.Frame.html#method.render_stateful_widget
[Awesome Ratatui]: https://github.com/ratatui/awesome-ratatui