Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
LegitCamper committed Oct 6, 2024
1 parent 6368b10 commit 5d697fb
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 346 deletions.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,14 @@

``` Rust
use iced::{Settings, Task, Theme};
use icy_browser::{get_fonts, BasicBrowser, Bookmark, Message};
use icy_browser::{get_fonts, Bookmark, IcyBrowser, Message, Ultralight};

fn run() -> (BasicBrowser, Task<Message>) {
fn run() -> (IcyBrowser<Ultralight>, Task<Message>) {
(
BasicBrowser::new_basic()
IcyBrowser::new()
.with_tab_bar()
.with_nav_bar()
.with_bookmark_bar(vec![Bookmark::new(
"https://www.rust-lang.org",
"rust-lang.org",
)])
.with_bookmark_bar(&[Bookmark::new("https://www.rust-lang.org", "rust-lang.org")])
.build(),
Task::none(),
)
Expand All @@ -44,8 +41,8 @@ fn main() -> iced::Result {
..Default::default()
};

iced::application("Basic Browser", BasicBrowser::update, BasicBrowser::view)
.subscription(BasicBrowser::subscription)
iced::application("Basic Browser", IcyBrowser::update, IcyBrowser::view)
.subscription(IcyBrowser::subscription)
.settings(settings)
.theme(|_| Theme::Dark)
.run_with(run)
Expand Down
10 changes: 5 additions & 5 deletions examples/basic_browser.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Simple browser with familiar browser widgets and the ultralight(webkit) webengine as a backend

use iced::{Settings, Task, Theme};
use icy_browser::{get_fonts, BasicBrowser, Bookmark, Message};
use icy_browser::{get_fonts, Bookmark, IcyBrowser, Message, Ultralight};

fn run() -> (BasicBrowser, Task<Message>) {
fn run() -> (IcyBrowser<Ultralight>, Task<Message>) {
(
BasicBrowser::new_basic()
IcyBrowser::new()
.with_tab_bar()
.with_nav_bar()
.with_bookmark_bar(&[Bookmark::new("https://www.rust-lang.org", "rust-lang.org")])
Expand All @@ -20,8 +20,8 @@ fn main() -> iced::Result {
..Default::default()
};

iced::application("Basic Browser", BasicBrowser::update, BasicBrowser::view)
.subscription(BasicBrowser::subscription)
iced::application("Basic Browser", IcyBrowser::update, IcyBrowser::view)
.subscription(IcyBrowser::subscription)
.settings(settings)
.theme(|_| Theme::Dark)
.run_with(run)
Expand Down
86 changes: 32 additions & 54 deletions examples/custom_widgets.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
// Custom view example with rainbow border

use iced::widget::{column, container};
use iced::widget::container;
use iced::{time, Border};
use iced::{Color, Element, Length, Settings, Subscription, Task, Theme};
use std::time::{Duration, Instant};

use icy_browser::{
browser_view, get_fonts, hoverable, nav_bar, tab_bar, widgets, BrowserEngine, BrowserWidget,
Ultralight,
};
use icy_browser::{get_fonts, widgets, IcyBrowser, Ultralight};

fn main() -> iced::Result {
let settings = Settings {
Expand Down Expand Up @@ -37,44 +34,53 @@ struct CustomWidgetState {
}

struct Browser {
widgets: BrowserWidget<Ultralight, CustomWidgetState>,
icy_browser: IcyBrowser<Ultralight>,
custom_widget_state: CustomWidgetState,
}

impl Default for Browser {
fn default() -> Self {
Self {
widgets: BrowserWidget::new()
.with_custom_view(
custom_view,
CustomWidgetState {
border_colors: vec![
Color::from_rgb(1.0, 0.0, 0.0), // Red
Color::from_rgb(1.0, 0.5, 0.0), // Orange
Color::from_rgb(1.0, 1.0, 0.0), // Yellow
Color::from_rgb(0.0, 1.0, 0.0), // Green
Color::from_rgb(0.0, 0.0, 1.0), // Blue
Color::from_rgb(0.29, 0.0, 0.51), // Indigo
Color::from_rgb(0.56, 0.0, 1.0), // Violet
],
start_time: Instant::now(),
},
)
.build(),
icy_browser: IcyBrowser::new().with_tab_bar().with_nav_bar().build(),
custom_widget_state: CustomWidgetState {
border_colors: vec![
Color::from_rgb(1.0, 0.0, 0.0), // Red
Color::from_rgb(1.0, 0.5, 0.0), // Orange
Color::from_rgb(1.0, 1.0, 0.0), // Yellow
Color::from_rgb(0.0, 1.0, 0.0), // Green
Color::from_rgb(0.0, 0.0, 1.0), // Blue
Color::from_rgb(0.29, 0.0, 0.51), // Indigo
Color::from_rgb(0.56, 0.0, 1.0), // Violet
],
start_time: Instant::now(),
},
}
}
}

impl Browser {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::BrowserWidget(msg) => self.widgets.update(msg).map(Message::BrowserWidget),
Message::Update => self.widgets.force_update().map(Message::BrowserWidget),
Message::BrowserWidget(msg) => self.icy_browser.update(msg).map(Message::BrowserWidget),
Message::Update => self.icy_browser.force_update().map(Message::BrowserWidget),
Message::Tick => Task::none(), // Tick
}
}

fn view(&self) -> Element<Message> {
self.widgets.view().map(Message::BrowserWidget)
let elapsed = self.custom_widget_state.start_time.elapsed().as_secs_f32();
let color_index = (elapsed * 2.0) as usize % self.custom_widget_state.border_colors.len();
let color = self.custom_widget_state.border_colors[color_index];

container(self.icy_browser.view().map(Message::BrowserWidget))
.center_x(Length::Fill)
.center_y(Length::Fill)
.padding(20)
.style(move |_theme| container::Style {
border: Border::default().color(color).width(20),
..Default::default()
})
.into()
}

fn subscription(&self) -> Subscription<Message> {
Expand All @@ -84,31 +90,3 @@ impl Browser {
])
}
}

fn custom_view<Engine: BrowserEngine>(
browser_widget: &BrowserWidget<Engine, CustomWidgetState>,
widget_state: CustomWidgetState,
) -> Element<icy_browser::Message> {
let elapsed = widget_state.start_time.elapsed().as_secs_f32();
let color_index = (elapsed * 2.0) as usize % widget_state.border_colors.len();
let color = widget_state.border_colors[color_index];

container(column![
tab_bar(browser_widget.engine().get_tabs()),
hoverable(nav_bar(&browser_widget.nav_bar_state))
.on_focus_change(icy_browser::Message::UpdateUrl),
browser_view(
browser_widget.view_size,
browser_widget.engine().get_tabs().get_current().get_view(),
!browser_widget.show_overlay,
),
])
.center_x(Length::Fill)
.center_y(Length::Fill)
.padding(20)
.style(move |_theme| container::Style {
border: Border::default().color(color).width(20),
..Default::default()
})
.into()
}
22 changes: 12 additions & 10 deletions examples/keyboard_driven.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use iced::{Element, Settings, Subscription, Task};
use std::time::Duration;

use icy_browser::{
get_fonts, widgets, BasicBrowser, Bookmark, BrowserWidget, KeyType, Message as WidgetMessage,
ShortcutBuilder, ShortcutModifier,
get_fonts, widgets, Bookmark, IcyBrowser, KeyType, Message as WidgetMessage, ShortcutBuilder,
ShortcutModifier, Ultralight,
};

fn main() -> iced::Result {
Expand All @@ -33,7 +33,7 @@ pub enum Message {
}

struct Browser {
widgets: BasicBrowser,
icy_browser: IcyBrowser<Ultralight>,
}

impl Default for Browser {
Expand All @@ -47,7 +47,7 @@ impl Default for Browser {
],
)
.build();
let widgets = BrowserWidget::new_basic()
let widgets = IcyBrowser::new()
.with_custom_shortcuts(shortcuts)
.with_tab_bar()
.with_bookmark_bar(&[
Expand All @@ -60,24 +60,26 @@ impl Default for Browser {
])
.build();

Self { widgets }
Self {
icy_browser: widgets,
}
}
}

impl Browser {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::BrowserWidget(msg) => self.widgets.update(msg).map(Message::BrowserWidget),
Message::Update => self.widgets.force_update().map(Message::BrowserWidget),
Message::BrowserWidget(msg) => self.icy_browser.update(msg).map(Message::BrowserWidget),
Message::Update => self.icy_browser.force_update().map(Message::BrowserWidget),
Message::Event(event) => self
.widgets
.update(widgets::Message::Event(Some(event)))
.icy_browser
.update(widgets::Message::IcedEvent(Some(event)))
.map(Message::BrowserWidget),
}
}

fn view(&self) -> Element<Message> {
self.widgets.view().map(Message::BrowserWidget)
self.icy_browser.view().map(Message::BrowserWidget)
}

fn subscription(&self) -> Subscription<Message> {
Expand Down
102 changes: 102 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use iced::widget::{
button,
image::{Handle, Image},
Button,
};
pub use iced_fonts::BOOTSTRAP_FONT_BYTES;
use std::{borrow::Cow, str::FromStr};
use url::{ParseError, Url};

use super::{Message, PixelFormat};

// Helper function to ensure required icons are imported
pub fn get_fonts() -> Vec<Cow<'static, [u8]>> {
vec![BOOTSTRAP_FONT_BYTES.into()]
}

// Image details for passing the view around
#[derive(Debug, Clone)]
pub struct ImageInfo {
pub pixels: Vec<u8>,
pub width: u32,
pub height: u32,
}

impl Default for ImageInfo {
fn default() -> Self {
Self {
pixels: vec![255; (Self::WIDTH as usize * Self::HEIGHT as usize) * 4],
width: Self::WIDTH,
height: Self::HEIGHT,
}
}
}

impl ImageInfo {
// The default dimentions
const WIDTH: u32 = 800;
const HEIGHT: u32 = 800;

pub fn new(pixels: Vec<u8>, format: PixelFormat, width: u32, height: u32) -> Self {
// R, G, B, A
assert_eq!(pixels.len() % 4, 0);

let pixels = match format {
PixelFormat::Rgba => pixels,
PixelFormat::Bgra => pixels
.chunks(4)
.flat_map(|chunk| [chunk[2], chunk[1], chunk[0], chunk[3]])
.collect(),
};

Self {
pixels,
width,
height,
}
}

pub fn as_image(&self) -> Image<Handle> {
Image::new(Handle::from_rgba(
self.width,
self.height,
self.pixels.clone(),
))
}
}

pub fn to_url(url: &str) -> Option<Url> {
match Url::parse(url) {
Ok(url) => Some(url),
Err(error) => {
if let ParseError::RelativeUrlWithoutBase = error {
let mut base = String::from("https://");
base.push_str(url);
Url::parse(&base).ok()
} else {
None
}
}
}
}

pub type Bookmarks = Vec<Bookmark>;

#[derive(Debug, Clone)]
pub struct Bookmark {
url: Url,
name: String,
// icon: Optional<>
}
impl Bookmark {
pub fn new(url: &str, name: &str) -> Self {
Bookmark {
url: Url::from_str(url).expect("Failed to parse url from bookmark url"),
name: name.to_string(),
}
}

pub fn as_button(&self) -> Button<Message> {
button(self.name.as_str()).on_press(Message::GoToUrl(self.url.to_string()))
}
}
Loading

0 comments on commit 5d697fb

Please sign in to comment.