Adds a text_input example to act as a test.
- TextFieldDelegate methods needed to retain the string, otherwise it could crash under fast usage. - Work on improving the browser example; WIP.
This commit is contained in:
parent
420422187a
commit
80ec654d8d
|
@ -1,9 +1,12 @@
|
|||
//! This example showcases setting up a basic application and window, setting up some views to
|
||||
//! work with autolayout, and some basic ways to handle colors.
|
||||
|
||||
use cacao::webview::WebView;
|
||||
use cacao::webview::{WebView, WebViewConfig, WebViewDelegate};
|
||||
|
||||
use cacao::input::{TextField, TextFieldDelegate};
|
||||
|
||||
use cacao::macos::{App, AppDelegate};
|
||||
use cacao::macos::toolbar::{Toolbar, ToolbarItem, ItemIdentifier, ToolbarDelegate};
|
||||
use cacao::macos::menu::{Menu, MenuItem};
|
||||
use cacao::macos::window::{Window, WindowConfig, WindowDelegate};
|
||||
|
||||
|
@ -39,7 +42,6 @@ impl AppDelegate for BasicApp {
|
|||
MenuItem::SelectAll
|
||||
]),
|
||||
|
||||
// Sidebar option is 11.0+ only.
|
||||
Menu::new("View", vec![
|
||||
MenuItem::EnterFullScreen
|
||||
]),
|
||||
|
@ -59,9 +61,50 @@ impl AppDelegate for BasicApp {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct URLBar;
|
||||
|
||||
impl TextFieldDelegate for URLBar {
|
||||
const NAME: &'static str = "URLBar";
|
||||
}
|
||||
|
||||
struct BrowserToolbar {
|
||||
url_bar: TextField<URLBar>
|
||||
}
|
||||
|
||||
impl BrowserToolbar {
|
||||
pub fn new() -> Self {
|
||||
BrowserToolbar {
|
||||
url_bar: TextField::with(URLBar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolbarDelegate for BrowserToolbar {
|
||||
const NAME: &'static str = "BrowserToolbar";
|
||||
|
||||
fn allowed_item_identifiers(&self) -> Vec<ItemIdentifier> { vec![] }
|
||||
fn default_item_identifiers(&self) -> Vec<ItemIdentifier> { vec![] }
|
||||
|
||||
fn item_for(&self, _identifier: &str) -> &ToolbarItem { std::unreachable!(); }
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct WebViewInstance;
|
||||
|
||||
impl WebViewDelegate for WebViewInstance {}
|
||||
|
||||
struct AppWindow {
|
||||
content: WebView
|
||||
toolbar: Toolbar<BrowserToolbar>,
|
||||
content: WebView<WebViewInstance>
|
||||
}
|
||||
|
||||
impl AppWindow {
|
||||
pub fn new() -> Self {
|
||||
AppWindow {
|
||||
toolbar: Toolbar::new("com.example.BrowserToolbar", BrowserToolbar::new()),
|
||||
content: WebView::with(WebViewConfig::default(), WebViewInstance::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowDelegate for AppWindow {
|
||||
|
@ -71,6 +114,7 @@ impl WindowDelegate for AppWindow {
|
|||
window.set_title("Browser Example");
|
||||
window.set_minimum_content_size(400., 400.);
|
||||
|
||||
window.set_toolbar(&self.toolbar);
|
||||
window.set_content_view(&self.content);
|
||||
|
||||
self.content.load_url("https://www.duckduckgo.com/");
|
||||
|
@ -79,6 +123,6 @@ impl WindowDelegate for AppWindow {
|
|||
|
||||
fn main() {
|
||||
App::new("com.test.window", BasicApp {
|
||||
window: Window::with(WindowConfig::default(), AppWindow::default())
|
||||
window: Window::with(WindowConfig::default(), AppWindow::new())
|
||||
}).run();
|
||||
}
|
||||
|
|
122
examples/text_input.rs
Normal file
122
examples/text_input.rs
Normal file
|
@ -0,0 +1,122 @@
|
|||
//! This example showcases setting up a basic application and window, setting up some views to
|
||||
//! work with autolayout, and some basic ways to handle colors.
|
||||
|
||||
use cacao::layout::{Layout, LayoutConstraint};
|
||||
use cacao::input::{TextField, TextFieldDelegate};
|
||||
use cacao::view::View;
|
||||
|
||||
use cacao::macos::{App, AppDelegate};
|
||||
use cacao::macos::menu::{Menu, MenuItem};
|
||||
use cacao::macos::window::{Window, WindowConfig, WindowDelegate};
|
||||
|
||||
struct BasicApp {
|
||||
window: Window<AppWindow>
|
||||
}
|
||||
|
||||
impl AppDelegate for BasicApp {
|
||||
fn did_finish_launching(&self) {
|
||||
App::set_menu(vec![
|
||||
Menu::new("", vec![
|
||||
MenuItem::Services,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Hide,
|
||||
MenuItem::HideOthers,
|
||||
MenuItem::ShowAll,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Quit
|
||||
]),
|
||||
|
||||
Menu::new("File", vec![
|
||||
MenuItem::CloseWindow
|
||||
]),
|
||||
|
||||
Menu::new("Edit", vec![
|
||||
MenuItem::Undo,
|
||||
MenuItem::Redo,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Cut,
|
||||
MenuItem::Copy,
|
||||
MenuItem::Paste,
|
||||
MenuItem::Separator,
|
||||
MenuItem::SelectAll
|
||||
]),
|
||||
|
||||
// Sidebar option is 11.0+ only.
|
||||
Menu::new("View", vec![
|
||||
MenuItem::EnterFullScreen
|
||||
]),
|
||||
|
||||
Menu::new("Window", vec![
|
||||
MenuItem::Minimize,
|
||||
MenuItem::Zoom,
|
||||
MenuItem::Separator,
|
||||
MenuItem::new("Bring All to Front")
|
||||
]),
|
||||
|
||||
Menu::new("Help", vec![])
|
||||
]);
|
||||
|
||||
App::activate();
|
||||
self.window.show();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ConsoleLogger;
|
||||
|
||||
impl TextFieldDelegate for ConsoleLogger {
|
||||
const NAME: &'static str = "ConsoleLogger";
|
||||
|
||||
fn text_should_begin_editing(&self, value: &str) -> bool {
|
||||
println!("Should begin with value: {}", value);
|
||||
true
|
||||
}
|
||||
|
||||
fn text_did_change(&self, value: &str) {
|
||||
println!("Did change to: {}", value);
|
||||
}
|
||||
|
||||
|
||||
fn text_did_end_editing(&self, value: &str) {
|
||||
println!("Ended: {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AppWindow {
|
||||
input: TextField<ConsoleLogger>,
|
||||
content: View
|
||||
}
|
||||
|
||||
impl AppWindow {
|
||||
pub fn new() -> Self {
|
||||
AppWindow {
|
||||
input: TextField::with(ConsoleLogger),
|
||||
content: View::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowDelegate for AppWindow {
|
||||
const NAME: &'static str = "WindowDelegate";
|
||||
|
||||
fn did_load(&mut self, window: Window) {
|
||||
window.set_title("Input Logger Example");
|
||||
window.set_minimum_content_size(300., 300.);
|
||||
|
||||
self.content.add_subview(&self.input);
|
||||
window.set_content_view(&self.content);
|
||||
|
||||
LayoutConstraint::activate(&[
|
||||
self.input.center_x.constraint_equal_to(&self.content.center_x),
|
||||
self.input.center_y.constraint_equal_to(&self.content.center_y),
|
||||
self.input.width.constraint_equal_to_constant(280.)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new("com.test.window", BasicApp {
|
||||
window: Window::with(WindowConfig::default(), AppWindow::new())
|
||||
}).run();
|
||||
}
|
|
@ -13,19 +13,19 @@ use crate::utils::load;
|
|||
/// Called when editing this text field has ended (e.g. user pressed enter).
|
||||
extern "C" fn text_did_end_editing<T: TextFieldDelegate>(this: &mut Object, _: Sel, _info: id) {
|
||||
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
|
||||
let s = NSString::from_retained(unsafe { msg_send![this, stringValue] });
|
||||
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
|
||||
view.text_did_end_editing(s.to_str());
|
||||
}
|
||||
|
||||
extern "C" fn text_did_begin_editing<T: TextFieldDelegate>(this: &mut Object, _: Sel, _info: id) {
|
||||
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
|
||||
let s = NSString::from_retained(unsafe { msg_send![this, stringValue] });
|
||||
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
|
||||
view.text_did_begin_editing(s.to_str());
|
||||
}
|
||||
|
||||
extern "C" fn text_did_change<T: TextFieldDelegate>(this: &mut Object, _: Sel, _info: id) {
|
||||
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
|
||||
let s = NSString::from_retained(unsafe { msg_send![this, stringValue] });
|
||||
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
|
||||
view.text_did_change(s.to_str());
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ extern "C" fn text_should_begin_editing<T: TextFieldDelegate>(
|
|||
_info: id,
|
||||
) -> BOOL {
|
||||
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
|
||||
let s = NSString::from_retained(unsafe { msg_send![this, stringValue] });
|
||||
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
|
||||
|
||||
match view.text_should_begin_editing(s.to_str()) {
|
||||
true => YES,
|
||||
|
|
Loading…
Reference in a new issue