Skip to content

Commit 5d697fb

Browse files
committed
refactor
1 parent 6368b10 commit 5d697fb

File tree

7 files changed

+264
-346
lines changed

7 files changed

+264
-346
lines changed

README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,14 @@
2222

2323
``` Rust
2424
use iced::{Settings, Task, Theme};
25-
use icy_browser::{get_fonts, BasicBrowser, Bookmark, Message};
25+
use icy_browser::{get_fonts, Bookmark, IcyBrowser, Message, Ultralight};
2626

27-
fn run() -> (BasicBrowser, Task<Message>) {
27+
fn run() -> (IcyBrowser<Ultralight>, Task<Message>) {
2828
(
29-
BasicBrowser::new_basic()
29+
IcyBrowser::new()
3030
.with_tab_bar()
3131
.with_nav_bar()
32-
.with_bookmark_bar(vec![Bookmark::new(
33-
"https://www.rust-lang.org",
34-
"rust-lang.org",
35-
)])
32+
.with_bookmark_bar(&[Bookmark::new("https://www.rust-lang.org", "rust-lang.org")])
3633
.build(),
3734
Task::none(),
3835
)
@@ -44,8 +41,8 @@ fn main() -> iced::Result {
4441
..Default::default()
4542
};
4643

47-
iced::application("Basic Browser", BasicBrowser::update, BasicBrowser::view)
48-
.subscription(BasicBrowser::subscription)
44+
iced::application("Basic Browser", IcyBrowser::update, IcyBrowser::view)
45+
.subscription(IcyBrowser::subscription)
4946
.settings(settings)
5047
.theme(|_| Theme::Dark)
5148
.run_with(run)

examples/basic_browser.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Simple browser with familiar browser widgets and the ultralight(webkit) webengine as a backend
22

33
use iced::{Settings, Task, Theme};
4-
use icy_browser::{get_fonts, BasicBrowser, Bookmark, Message};
4+
use icy_browser::{get_fonts, Bookmark, IcyBrowser, Message, Ultralight};
55

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

23-
iced::application("Basic Browser", BasicBrowser::update, BasicBrowser::view)
24-
.subscription(BasicBrowser::subscription)
23+
iced::application("Basic Browser", IcyBrowser::update, IcyBrowser::view)
24+
.subscription(IcyBrowser::subscription)
2525
.settings(settings)
2626
.theme(|_| Theme::Dark)
2727
.run_with(run)

examples/custom_widgets.rs

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
// Custom view example with rainbow border
22

3-
use iced::widget::{column, container};
3+
use iced::widget::container;
44
use iced::{time, Border};
55
use iced::{Color, Element, Length, Settings, Subscription, Task, Theme};
66
use std::time::{Duration, Instant};
77

8-
use icy_browser::{
9-
browser_view, get_fonts, hoverable, nav_bar, tab_bar, widgets, BrowserEngine, BrowserWidget,
10-
Ultralight,
11-
};
8+
use icy_browser::{get_fonts, widgets, IcyBrowser, Ultralight};
129

1310
fn main() -> iced::Result {
1411
let settings = Settings {
@@ -37,44 +34,53 @@ struct CustomWidgetState {
3734
}
3835

3936
struct Browser {
40-
widgets: BrowserWidget<Ultralight, CustomWidgetState>,
37+
icy_browser: IcyBrowser<Ultralight>,
38+
custom_widget_state: CustomWidgetState,
4139
}
4240

4341
impl Default for Browser {
4442
fn default() -> Self {
4543
Self {
46-
widgets: BrowserWidget::new()
47-
.with_custom_view(
48-
custom_view,
49-
CustomWidgetState {
50-
border_colors: vec![
51-
Color::from_rgb(1.0, 0.0, 0.0), // Red
52-
Color::from_rgb(1.0, 0.5, 0.0), // Orange
53-
Color::from_rgb(1.0, 1.0, 0.0), // Yellow
54-
Color::from_rgb(0.0, 1.0, 0.0), // Green
55-
Color::from_rgb(0.0, 0.0, 1.0), // Blue
56-
Color::from_rgb(0.29, 0.0, 0.51), // Indigo
57-
Color::from_rgb(0.56, 0.0, 1.0), // Violet
58-
],
59-
start_time: Instant::now(),
60-
},
61-
)
62-
.build(),
44+
icy_browser: IcyBrowser::new().with_tab_bar().with_nav_bar().build(),
45+
custom_widget_state: CustomWidgetState {
46+
border_colors: vec![
47+
Color::from_rgb(1.0, 0.0, 0.0), // Red
48+
Color::from_rgb(1.0, 0.5, 0.0), // Orange
49+
Color::from_rgb(1.0, 1.0, 0.0), // Yellow
50+
Color::from_rgb(0.0, 1.0, 0.0), // Green
51+
Color::from_rgb(0.0, 0.0, 1.0), // Blue
52+
Color::from_rgb(0.29, 0.0, 0.51), // Indigo
53+
Color::from_rgb(0.56, 0.0, 1.0), // Violet
54+
],
55+
start_time: Instant::now(),
56+
},
6357
}
6458
}
6559
}
6660

6761
impl Browser {
6862
fn update(&mut self, message: Message) -> Task<Message> {
6963
match message {
70-
Message::BrowserWidget(msg) => self.widgets.update(msg).map(Message::BrowserWidget),
71-
Message::Update => self.widgets.force_update().map(Message::BrowserWidget),
64+
Message::BrowserWidget(msg) => self.icy_browser.update(msg).map(Message::BrowserWidget),
65+
Message::Update => self.icy_browser.force_update().map(Message::BrowserWidget),
7266
Message::Tick => Task::none(), // Tick
7367
}
7468
}
7569

7670
fn view(&self) -> Element<Message> {
77-
self.widgets.view().map(Message::BrowserWidget)
71+
let elapsed = self.custom_widget_state.start_time.elapsed().as_secs_f32();
72+
let color_index = (elapsed * 2.0) as usize % self.custom_widget_state.border_colors.len();
73+
let color = self.custom_widget_state.border_colors[color_index];
74+
75+
container(self.icy_browser.view().map(Message::BrowserWidget))
76+
.center_x(Length::Fill)
77+
.center_y(Length::Fill)
78+
.padding(20)
79+
.style(move |_theme| container::Style {
80+
border: Border::default().color(color).width(20),
81+
..Default::default()
82+
})
83+
.into()
7884
}
7985

8086
fn subscription(&self) -> Subscription<Message> {
@@ -84,31 +90,3 @@ impl Browser {
8490
])
8591
}
8692
}
87-
88-
fn custom_view<Engine: BrowserEngine>(
89-
browser_widget: &BrowserWidget<Engine, CustomWidgetState>,
90-
widget_state: CustomWidgetState,
91-
) -> Element<icy_browser::Message> {
92-
let elapsed = widget_state.start_time.elapsed().as_secs_f32();
93-
let color_index = (elapsed * 2.0) as usize % widget_state.border_colors.len();
94-
let color = widget_state.border_colors[color_index];
95-
96-
container(column![
97-
tab_bar(browser_widget.engine().get_tabs()),
98-
hoverable(nav_bar(&browser_widget.nav_bar_state))
99-
.on_focus_change(icy_browser::Message::UpdateUrl),
100-
browser_view(
101-
browser_widget.view_size,
102-
browser_widget.engine().get_tabs().get_current().get_view(),
103-
!browser_widget.show_overlay,
104-
),
105-
])
106-
.center_x(Length::Fill)
107-
.center_y(Length::Fill)
108-
.padding(20)
109-
.style(move |_theme| container::Style {
110-
border: Border::default().color(color).width(20),
111-
..Default::default()
112-
})
113-
.into()
114-
}

examples/keyboard_driven.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use iced::{Element, Settings, Subscription, Task};
66
use std::time::Duration;
77

88
use icy_browser::{
9-
get_fonts, widgets, BasicBrowser, Bookmark, BrowserWidget, KeyType, Message as WidgetMessage,
10-
ShortcutBuilder, ShortcutModifier,
9+
get_fonts, widgets, Bookmark, IcyBrowser, KeyType, Message as WidgetMessage, ShortcutBuilder,
10+
ShortcutModifier, Ultralight,
1111
};
1212

1313
fn main() -> iced::Result {
@@ -33,7 +33,7 @@ pub enum Message {
3333
}
3434

3535
struct Browser {
36-
widgets: BasicBrowser,
36+
icy_browser: IcyBrowser<Ultralight>,
3737
}
3838

3939
impl Default for Browser {
@@ -47,7 +47,7 @@ impl Default for Browser {
4747
],
4848
)
4949
.build();
50-
let widgets = BrowserWidget::new_basic()
50+
let widgets = IcyBrowser::new()
5151
.with_custom_shortcuts(shortcuts)
5252
.with_tab_bar()
5353
.with_bookmark_bar(&[
@@ -60,24 +60,26 @@ impl Default for Browser {
6060
])
6161
.build();
6262

63-
Self { widgets }
63+
Self {
64+
icy_browser: widgets,
65+
}
6466
}
6567
}
6668

6769
impl Browser {
6870
fn update(&mut self, message: Message) -> Task<Message> {
6971
match message {
70-
Message::BrowserWidget(msg) => self.widgets.update(msg).map(Message::BrowserWidget),
71-
Message::Update => self.widgets.force_update().map(Message::BrowserWidget),
72+
Message::BrowserWidget(msg) => self.icy_browser.update(msg).map(Message::BrowserWidget),
73+
Message::Update => self.icy_browser.force_update().map(Message::BrowserWidget),
7274
Message::Event(event) => self
73-
.widgets
74-
.update(widgets::Message::Event(Some(event)))
75+
.icy_browser
76+
.update(widgets::Message::IcedEvent(Some(event)))
7577
.map(Message::BrowserWidget),
7678
}
7779
}
7880

7981
fn view(&self) -> Element<Message> {
80-
self.widgets.view().map(Message::BrowserWidget)
82+
self.icy_browser.view().map(Message::BrowserWidget)
8183
}
8284

8385
fn subscription(&self) -> Subscription<Message> {

src/helpers.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use iced::widget::{
2+
button,
3+
image::{Handle, Image},
4+
Button,
5+
};
6+
pub use iced_fonts::BOOTSTRAP_FONT_BYTES;
7+
use std::{borrow::Cow, str::FromStr};
8+
use url::{ParseError, Url};
9+
10+
use super::{Message, PixelFormat};
11+
12+
// Helper function to ensure required icons are imported
13+
pub fn get_fonts() -> Vec<Cow<'static, [u8]>> {
14+
vec![BOOTSTRAP_FONT_BYTES.into()]
15+
}
16+
17+
// Image details for passing the view around
18+
#[derive(Debug, Clone)]
19+
pub struct ImageInfo {
20+
pub pixels: Vec<u8>,
21+
pub width: u32,
22+
pub height: u32,
23+
}
24+
25+
impl Default for ImageInfo {
26+
fn default() -> Self {
27+
Self {
28+
pixels: vec![255; (Self::WIDTH as usize * Self::HEIGHT as usize) * 4],
29+
width: Self::WIDTH,
30+
height: Self::HEIGHT,
31+
}
32+
}
33+
}
34+
35+
impl ImageInfo {
36+
// The default dimentions
37+
const WIDTH: u32 = 800;
38+
const HEIGHT: u32 = 800;
39+
40+
pub fn new(pixels: Vec<u8>, format: PixelFormat, width: u32, height: u32) -> Self {
41+
// R, G, B, A
42+
assert_eq!(pixels.len() % 4, 0);
43+
44+
let pixels = match format {
45+
PixelFormat::Rgba => pixels,
46+
PixelFormat::Bgra => pixels
47+
.chunks(4)
48+
.flat_map(|chunk| [chunk[2], chunk[1], chunk[0], chunk[3]])
49+
.collect(),
50+
};
51+
52+
Self {
53+
pixels,
54+
width,
55+
height,
56+
}
57+
}
58+
59+
pub fn as_image(&self) -> Image<Handle> {
60+
Image::new(Handle::from_rgba(
61+
self.width,
62+
self.height,
63+
self.pixels.clone(),
64+
))
65+
}
66+
}
67+
68+
pub fn to_url(url: &str) -> Option<Url> {
69+
match Url::parse(url) {
70+
Ok(url) => Some(url),
71+
Err(error) => {
72+
if let ParseError::RelativeUrlWithoutBase = error {
73+
let mut base = String::from("https://");
74+
base.push_str(url);
75+
Url::parse(&base).ok()
76+
} else {
77+
None
78+
}
79+
}
80+
}
81+
}
82+
83+
pub type Bookmarks = Vec<Bookmark>;
84+
85+
#[derive(Debug, Clone)]
86+
pub struct Bookmark {
87+
url: Url,
88+
name: String,
89+
// icon: Optional<>
90+
}
91+
impl Bookmark {
92+
pub fn new(url: &str, name: &str) -> Self {
93+
Bookmark {
94+
url: Url::from_str(url).expect("Failed to parse url from bookmark url"),
95+
name: name.to_string(),
96+
}
97+
}
98+
99+
pub fn as_button(&self) -> Button<Message> {
100+
button(self.name.as_str()).on_press(Message::GoToUrl(self.url.to_string()))
101+
}
102+
}

0 commit comments

Comments
 (0)