094ed59a04
* Use objc2 * Replace `objc_id` * Remove sel_impl import * Fix `add_method` calls * Fix accessing raw FFI functions * Fix Encode impl * Fix message sends arguments that do not implement `Encode` * Use immutable reference in a few places where now necessary See https://github.com/madsmtm/objc2/pull/150 for a bit of background * Add a few Send + Sync bounds where examples require it This is something we'll need to look into properly * Use `&'static Class` instead of `*const Class` Safer and more ergonomic. Also required for `msg_send_id!` macro * Use msg_send_id! and rc::Id * Update objc2 to v0.3.0-beta.2 * Replace `BOOL` with `Bool` when declaring delegates This makes cacao compile on Aarch64 again * Remove a few impossible to use correctly `into_inner` functions These consumed `self`, and hence also dropped `Id` variable that was responsible for keeping the returned pointer alive * Remove a few impossible to use correctly `From` implementations * Quickly fix UB with using BACKGROUND_COLOR ivar * Fix double-freeing of windows * Fix double freeing of strings * Fix a few remaining double-frees
107 lines
3.1 KiB
Rust
107 lines
3.1 KiB
Rust
use cacao::objc::{msg_send, sel};
|
|
|
|
use cacao::button::Button;
|
|
use cacao::input::{TextField, TextFieldDelegate};
|
|
|
|
use cacao::appkit::toolbar::{ItemIdentifier, Toolbar, ToolbarDelegate, ToolbarDisplayMode, ToolbarItem};
|
|
|
|
use super::Action;
|
|
|
|
const BACK_BUTTON: &str = "BackButton";
|
|
const FWDS_BUTTON: &str = "FwdsButton";
|
|
const URL_BAR: &str = "URLBar";
|
|
|
|
#[derive(Debug)]
|
|
pub struct URLBar;
|
|
|
|
impl TextFieldDelegate for URLBar {
|
|
const NAME: &'static str = "URLBar";
|
|
|
|
fn text_did_end_editing(&self, value: &str) {
|
|
Action::Load(value.to_string()).dispatch();
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct BrowserToolbar {
|
|
back_item: ToolbarItem,
|
|
forwards_item: ToolbarItem,
|
|
url_bar: TextField<URLBar>,
|
|
url_bar_item: ToolbarItem
|
|
}
|
|
|
|
impl BrowserToolbar {
|
|
pub fn new() -> Self {
|
|
let back_button = Button::new("Back");
|
|
let mut back_item = ToolbarItem::new(BACK_BUTTON);
|
|
back_item.set_button(back_button);
|
|
back_item.set_action(|_| Action::Back.dispatch());
|
|
|
|
let forwards_button = Button::new("Forwards");
|
|
let mut forwards_item = ToolbarItem::new(FWDS_BUTTON);
|
|
forwards_item.set_button(forwards_button);
|
|
forwards_item.set_action(|_| Action::Forwards.dispatch());
|
|
|
|
let url_bar = TextField::with(URLBar);
|
|
let url_bar_item = ToolbarItem::new(URL_BAR);
|
|
|
|
// We cheat for now to link these, as there's no API for Toolbar yet
|
|
// to support arbitrary view types. The framework is designed to support this kind of
|
|
// cheating, though: it's not outlandish to need to just manage things yourself when it
|
|
// comes to Objective-C/AppKit sometimes.
|
|
//
|
|
// As long as we keep hold of things here and they all drop together, it's relatively safe.
|
|
url_bar.objc.with_mut(|obj| unsafe {
|
|
let _: () = msg_send![&*url_bar_item.objc, setView:&*obj];
|
|
});
|
|
|
|
BrowserToolbar {
|
|
back_item,
|
|
forwards_item,
|
|
url_bar,
|
|
url_bar_item
|
|
}
|
|
}
|
|
|
|
pub fn set_url(&self, url: &str) {
|
|
self.url_bar.set_text(url);
|
|
}
|
|
|
|
fn item_identifiers(&self) -> Vec<ItemIdentifier> {
|
|
vec![
|
|
ItemIdentifier::Custom(BACK_BUTTON),
|
|
ItemIdentifier::Custom(FWDS_BUTTON),
|
|
ItemIdentifier::Space,
|
|
ItemIdentifier::Custom(URL_BAR),
|
|
ItemIdentifier::Space,
|
|
]
|
|
}
|
|
}
|
|
|
|
impl ToolbarDelegate for BrowserToolbar {
|
|
const NAME: &'static str = "BrowserToolbar";
|
|
|
|
fn did_load(&mut self, toolbar: Toolbar) {
|
|
toolbar.set_display_mode(ToolbarDisplayMode::IconOnly);
|
|
}
|
|
|
|
fn allowed_item_identifiers(&self) -> Vec<ItemIdentifier> {
|
|
self.item_identifiers()
|
|
}
|
|
|
|
fn default_item_identifiers(&self) -> Vec<ItemIdentifier> {
|
|
self.item_identifiers()
|
|
}
|
|
|
|
fn item_for(&self, identifier: &str) -> &ToolbarItem {
|
|
match identifier {
|
|
BACK_BUTTON => &self.back_item,
|
|
FWDS_BUTTON => &self.forwards_item,
|
|
URL_BAR => &self.url_bar_item,
|
|
_ => {
|
|
std::unreachable!();
|
|
}
|
|
}
|
|
}
|
|
}
|