Skip to content

Commit

Permalink
fix minor bugs and fix tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
LegitCamper committed Aug 18, 2024
1 parent 01c6590 commit 091516a
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 101 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ codegen-units = 1
lto = "fat"
strip = "debuginfo"
panic = "abort"
incremental = true

[profile.dev]
incremental = true
opt-level = "s"
lto = "thin"

[build]
rustflags = ["-Z", "threads=8"]
Expand Down Expand Up @@ -39,5 +45,3 @@ tempfile = "3.12.0"
ul-next = { version = "0.2.0", optional = true }
url = "2.5.2"

[build-dependencies]
cmake = "0.1"
21 changes: 5 additions & 16 deletions examples/basic_browser.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Simple browser with familiar browser widget and the ultralight(webkit) webengine as a backend

use iced::{executor, Application, Command, Settings, Subscription, Theme};
use iced::{Sandbox, Settings, Theme};
use iced_aw::BOOTSTRAP_FONT_BYTES;
use std::time::Duration;

use icy_browser::{browser_widgets, BrowserWidget, Ultralight};

Expand All @@ -23,23 +22,19 @@ struct Browser {
#[derive(Debug, Clone)]
pub enum Message {
BrowserWidget(browser_widgets::Message),
DoBrowserWork,
}

impl Application for Browser {
impl Sandbox for Browser {
type Message = Message;
type Executor = executor::Default;
type Flags = ();
type Theme = Theme;

fn new(_flags: Self::Flags) -> (Self, Command<Message>) {
fn new() -> Self {
let widgets = BrowserWidget::new_with_ultralight()
.with_tab_bar()
.with_nav_bar()
.with_browsesr_view()
.build();

(Self { widgets }, Command::none())
Self { widgets }
}

fn title(&self) -> String {
Expand All @@ -50,18 +45,12 @@ impl Application for Browser {
Theme::Dark
}

fn subscription(&self) -> Subscription<Message> {
iced::time::every(Duration::from_millis(100)).map(move |_| Message::DoBrowserWork)
}

fn update(&mut self, message: Self::Message) -> Command<Message> {
fn update(&mut self, message: Self::Message) {
match message {
Message::BrowserWidget(msg) => {
self.widgets.update(msg);
}
Message::DoBrowserWork => self.widgets.update(browser_widgets::Message::DoWork),
}
Command::none()
}

fn view(&self) -> iced::Element<'_, Self::Message> {
Expand Down
28 changes: 27 additions & 1 deletion src/engines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ impl<TabInfo> Tabs<TabInfo> {
}
}

pub fn id_to_index(&self, id: u32) -> usize {
for (idx, tab) in self.tabs.iter().enumerate() {
if tab.id == id {
return idx;
}
}
panic!("Id: {} was not found", id);
}

pub fn index_to_id(&self, index: usize) -> u32 {
self.tabs
.get(index)
.unwrap_or_else(|| panic!("Index {} was not found", index))
.id
}

pub fn get_current_id(&self) -> u32 {
self.current
}
Expand All @@ -125,7 +141,17 @@ impl<TabInfo> Tabs<TabInfo> {
}

pub fn remove(&mut self, id: u32) {
self.tabs.retain(|tab| tab.id != id)
// TODO: have list of prevous tabs instead
if self.current == id {
for tab in self.tabs.iter().rev() {
if tab.id != id {
self.current = tab.id;
break;
}
}
}

self.tabs.retain(|tab| tab.id != id);
}

pub fn get_current(&self) -> &Tab<TabInfo> {
Expand Down
118 changes: 54 additions & 64 deletions src/engines/ultralight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,73 +174,63 @@ impl BrowserEngine for Ultralight {
}

fn new_tab(&mut self, url: &Url) -> u32 {
if self
.tabs
.tabs
.iter()
.filter(|tab| *tab.url.read().unwrap() == *url.as_ref())
.count()
== 0
{
let view = self
.renderer
.create_view(self.width, self.height, &self.view_config, None)
.unwrap();

let surface = view.surface().unwrap();
view.load_url(url.as_ref()).unwrap();

// RGBA
debug_assert!(surface.row_bytes() / self.width == 4);

// set callbacks
let site_url = Arc::new(RwLock::new(url.to_string()));
let cb_url = site_url.clone();
view.set_change_url_callback(move |_view, url| {
*cb_url.write().unwrap() = url;
});

let title = Arc::new(RwLock::new(view.title().unwrap()));
let cb_title = title.clone();
view.set_change_title_callback(move |_view, title| {
*cb_title.write().unwrap() = title;
});

let cursor = Arc::new(RwLock::new(mouse::Interaction::Idle));
let cb_cursor = cursor.clone();
view.set_change_cursor_callback(move |_view, cursor_update| {
*cb_cursor.write().unwrap() = match cursor_update {
Cursor::None => mouse::Interaction::Idle,
Cursor::Pointer => mouse::Interaction::Idle,
Cursor::Hand => mouse::Interaction::Pointer,
Cursor::Grab => mouse::Interaction::Grab,
Cursor::VerticalText => mouse::Interaction::Text,
Cursor::IBeam => mouse::Interaction::Text,
Cursor::Cross => mouse::Interaction::Crosshair,
Cursor::Wait => mouse::Interaction::Working,
Cursor::Grabbing => mouse::Interaction::Grab,
Cursor::NorthSouthResize => mouse::Interaction::ResizingVertically,
Cursor::EastWestResize => mouse::Interaction::ResizingHorizontally,
Cursor::NotAllowed => mouse::Interaction::NotAllowed,
Cursor::ZoomIn => mouse::Interaction::ZoomIn,
Cursor::ZoomOut => mouse::Interaction::ZoomIn,
_ => mouse::Interaction::Pointer,
};
});

let tab_info = UltalightTabInfo {
surface,
view,
cursor,
let view = self
.renderer
.create_view(self.width, self.height, &self.view_config, None)
.unwrap();

let surface = view.surface().unwrap();
view.load_url(url.as_ref()).unwrap();

// RGBA
debug_assert!(surface.row_bytes() / self.width == 4);

// set callbacks
let site_url = Arc::new(RwLock::new(url.to_string()));
let cb_url = site_url.clone();
view.set_change_url_callback(move |_view, url| {
*cb_url.write().unwrap() = url;
});

let title = Arc::new(RwLock::new(view.title().unwrap()));
let cb_title = title.clone();
view.set_change_title_callback(move |_view, title| {
*cb_title.write().unwrap() = title;
});

let cursor = Arc::new(RwLock::new(mouse::Interaction::Idle));
let cb_cursor = cursor.clone();
view.set_change_cursor_callback(move |_view, cursor_update| {
*cb_cursor.write().unwrap() = match cursor_update {
Cursor::None => mouse::Interaction::Idle,
Cursor::Pointer => mouse::Interaction::Idle,
Cursor::Hand => mouse::Interaction::Pointer,
Cursor::Grab => mouse::Interaction::Grab,
Cursor::VerticalText => mouse::Interaction::Text,
Cursor::IBeam => mouse::Interaction::Text,
Cursor::Cross => mouse::Interaction::Crosshair,
Cursor::Wait => mouse::Interaction::Working,
Cursor::Grabbing => mouse::Interaction::Grab,
Cursor::NorthSouthResize => mouse::Interaction::ResizingVertically,
Cursor::EastWestResize => mouse::Interaction::ResizingHorizontally,
Cursor::NotAllowed => mouse::Interaction::NotAllowed,
Cursor::ZoomIn => mouse::Interaction::ZoomIn,
Cursor::ZoomOut => mouse::Interaction::ZoomIn,
_ => mouse::Interaction::Pointer,
};
});

let tab = Tab::new(site_url, title, tab_info);
let id = tab.id;
let tab_info = UltalightTabInfo {
surface,
view,
cursor,
};

self.tabs.insert(tab);
return id;
}
unreachable!();
let tab = Tab::new(site_url, title, tab_info);
let id = tab.id;

self.tabs.insert(tab);
return id;
}

fn goto_tab(&mut self, id: u32) {
Expand Down
37 changes: 27 additions & 10 deletions src/widgets/browser_widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub enum Message {
Refresh,
GoHome,
GoUrl(String),
ChangeTab(u32),
CloseTab(u32),
ChangeTab(TabSelectionType),
CloseTab(TabSelectionType),
CreateTab,
UrlChanged(String),
SendKeyboardEvent(keyboard::Event),
Expand All @@ -27,6 +27,13 @@ pub enum Message {
DoWork,
}

#[derive(Debug, Clone)]
/// Allows different widgets to interact in their native way
pub enum TabSelectionType {
Id(u32),
Index(usize),
}

pub struct BrowserWidget<Engine: BrowserEngine> {
engine: Option<Engine>,
home: Url,
Expand Down Expand Up @@ -101,7 +108,7 @@ where
}

pub fn build(self) -> Self {
assert!(!self.engine.is_none());
assert!(self.engine.is_some());

let mut build = Self {
engine: self.engine,
Expand Down Expand Up @@ -130,6 +137,8 @@ where
}

pub fn update(&mut self, message: Message) {
self.engine().do_work();

match message {
Message::DoWork => self.engine().do_work(),
Message::UpdateBounds(bounds) => {
Expand All @@ -142,10 +151,20 @@ where
Message::SendMouseEvent(point, event) => {
self.engine_mut().handle_mouse_event(point, event);
}
Message::ChangeTab(id) => self.engine_mut().goto_tab(id),
Message::CloseTab(id) => {
self.engine_mut().get_tabs_mut().remove(id);
}
Message::ChangeTab(index_type) => match index_type {
TabSelectionType::Id(id) => self.engine_mut().goto_tab(id),
TabSelectionType::Index(index) => {
let id = self.engine_mut().get_tabs().index_to_id(index);
self.engine_mut().goto_tab(id);
}
},
Message::CloseTab(select_type) => match select_type {
TabSelectionType::Id(id) => self.engine_mut().get_tabs_mut().remove(id),
TabSelectionType::Index(index) => {
let id = self.engine_mut().get_tabs().index_to_id(index);
self.engine_mut().get_tabs_mut().remove(id);
}
},
Message::CreateTab => {
self.url = self.home.to_string();
let home = self.home.clone();
Expand Down Expand Up @@ -191,9 +210,7 @@ where
let mut column = column![];

if self.tab_bar {
let tabs = self.engine().get_tabs();
let active_tab = self.engine().get_tabs().get_current().id();
column = column.push(tab_bar(tabs, active_tab))
column = column.push(tab_bar(self.engine().get_tabs()))
}
if self.nav_bar {
column = column.push(nav_bar(&self.url))
Expand Down
24 changes: 17 additions & 7 deletions src/widgets/tab_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,30 @@ use iced::{self, Element, Length};
use iced_aw::core::icons::bootstrap::{icon_to_text, Bootstrap};
use iced_aw::{TabBar as TB, TabLabel};

use super::browser_widgets::Message;
use super::browser_widgets::{Message, TabSelectionType};
use crate::engines::Tabs;

// helper function to create navigation bar
pub fn tab_bar<TabInfo>(tabs: &Tabs<TabInfo>, active_tab: u32) -> Element<'static, Message> {
pub fn tab_bar<TabInfo>(tabs: &Tabs<TabInfo>) -> Element<'static, Message> {
let current_id = tabs.get_current_id();
let active_tab = tabs
.tabs()
.iter()
.position(|tab| tab.id() == current_id)
.expect("Failed to find tab with that id");

let tab_bar = tabs
.tabs()
.iter()
.fold(TB::new(Message::ChangeTab), |tab_bar, tab| {
let id = tab_bar.size();
tab_bar.push(id as u32, TabLabel::Text(tab.title()))
})
.fold(
TB::new(|index| Message::ChangeTab(TabSelectionType::Index(index))),
|tab_bar, tab| {
let id = tab_bar.size();
tab_bar.push(id, TabLabel::Text(tab.title()))
},
)
.set_active_tab(&active_tab)
.on_close(Message::CloseTab)
.on_close(|index| Message::CloseTab(TabSelectionType::Index(index)))
.tab_width(Length::Shrink)
.spacing(5.0)
.padding(5.0);
Expand Down

0 comments on commit 091516a

Please sign in to comment.