Skip to content

Commit

Permalink
feat: Implement ContextSwitcher Component, Close #33
Browse files Browse the repository at this point in the history
  • Loading branch information
wangeguo committed Jan 3, 2024
1 parent 897754d commit a001575
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/utils/connection_status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2023 The Amphitheatre Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt::Display;

#[derive(Clone, Debug, Default)]
pub enum ConnectionStatus {
#[default]
Connecting,
Connected,
Disconnected,
}

// impl std::fmt::Display for State
impl Display for ConnectionStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConnectionStatus::Connecting => write!(f, "Connecting..."),
ConnectionStatus::Connected => write!(f, "Connected"),
ConnectionStatus::Disconnected => write!(f, "Disconnected. Retrying..."),
}
}
}
1 change: 1 addition & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod connection_status;
pub mod strings;
99 changes: 99 additions & 0 deletions src/widgets/context_switcher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use amp_common::config::ContextConfiguration;
use iced::{widget::Component, Alignment, Length};
use iced_aw::{Icon, ICON_FONT};
use tracing::debug;

use crate::{styles, utils::connection_status::ConnectionStatus};

use super::{Button, Column, Container, Element, Renderer, Row, Text};

#[derive(Default)]
pub struct ContextSwitcher<Message> {
context: ContextConfiguration,
status: ConnectionStatus,

on_change: Option<Box<dyn Fn(String) -> Message>>,
}

#[derive(Clone)]
pub enum Event {
ButtonPressed,
}

impl<Message> ContextSwitcher<Message> {
pub fn new(context: ContextConfiguration, status: ConnectionStatus) -> Self {
Self {
context,
status,
on_change: None,
}
}

pub fn on_change(mut self, on_change: impl Fn(String) -> Message + 'static) -> Self {
self.on_change = Some(Box::new(on_change));
self
}
}

impl<Message> Component<Message, Renderer> for ContextSwitcher<Message> {
type State = ();
type Event = Event;

fn update(&mut self, _state: &mut Self::State, event: Self::Event) -> Option<Message> {
match event {
Event::ButtonPressed => {
debug!("The context switcher pressed");
None
}
}
}

fn view(&self, _state: &Self::State) -> Element<Self::Event> {
let style = match self.status {
ConnectionStatus::Connecting => styles::Text::Secondary,
ConnectionStatus::Connected => styles::Text::Success,
ConnectionStatus::Disconnected => styles::Text::Danger,
};
let text = self.status.to_string();
let state = Row::new()
.push(Text::new("•").size(14).style(style))
.push(Text::new(text).size(14).style(styles::Text::Secondary))
.align_items(Alignment::Center);

let title = self.context.current().map(|c| c.title.as_str()).unwrap_or("UNKNOWN");
let heading = Column::new().push(Text::new(title)).push(state).width(Length::Fill);

Container::new(
Button::new(
Row::new()
.push(heading)
.push(Text::new(Icon::ChevronExpand.to_string()).font(ICON_FONT).size(16.0))
.align_items(Alignment::Center)
.width(Length::Fill),
)
.style(styles::Button::Element)
.on_press(Event::ButtonPressed),
)
.into()
}
}

impl<'a, Message> From<ContextSwitcher<Message>> for Element<'a, Message>
where
Message: 'a + Clone,
{
fn from(switcher: ContextSwitcher<Message>) -> Self {
iced::widget::component(switcher)
}
}
3 changes: 3 additions & 0 deletions src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub mod empty;
pub mod lists;
pub mod tabs;

mod context_switcher;
pub use context_switcher::ContextSwitcher;

use crate::styles::Theme;

pub type Renderer = iced::Renderer<Theme>;
Expand Down

0 comments on commit a001575

Please sign in to comment.