--- /dev/null
+#![allow(dead_code)]
+#[allow(unused_imports)]
+
+use std::ffi::{c_char, c_int, c_void};
+use std::ffi::CString;
+use crate::ui::toolkit;
+use crate::ui::ffi::*;
+
+extern "C" {
+ fn ui_window(title: *const c_char) -> *const UiObject;
+
+ fn ui_button_create(obj: *const UiObject, args: *const UiButtonArgs);
+ fn ui_togglebutton_create(obj: *const UiObject, args: *const UiToggleArgs);
+ fn ui_checkbox_create(obj: *const UiObject, args: *const UiToggleArgs);
+ fn ui_switch_create(obj: *const UiObject, args: *const UiToggleArgs);
+ fn ui_radiobutton_create(obj: *const UiObject, args: *const UiToggleArgs);
+ fn ui_linkbutton_create(obj: *const UiObject, args: *const UiLinkButtonArgs);
+
+ fn ui_button_args_new() -> *mut UiButtonArgs;
+ fn ui_button_args_set_label(args: *mut UiButtonArgs, label: *const c_char);
+ // TODO: implement arg funcs
+ fn ui_button_args_free(args: *mut UiButtonArgs);
+
+ fn ui_toggle_args_new() -> *mut UiToggleArgs;
+ fn ui_toggle_args_free(args: *mut UiToggleArgs);
+}
+
+pub struct ButtonBuilder {
+ args: *mut UiButtonArgs,
+ obj: *const UiObject
+}
+
+pub struct ToggleBuilder {
+ args: *mut UiToggleArgs
+}
+
+impl toolkit::UiObject {
+ pub fn button(&self) -> ButtonBuilder {
+ unsafe {
+ let args = ui_button_args_new();
+ ButtonBuilder { args: args, obj: self.ptr }
+ }
+ }
+
+ pub fn togglebutton() -> ToggleBuilder {
+ unsafe {
+ let args = ui_toggle_args_new();
+ ToggleBuilder { args: args }
+ }
+ }
+
+ pub fn checkbox() -> ToggleBuilder {
+ unsafe {
+ let args = ui_toggle_args_new();
+ ToggleBuilder { args: args }
+ }
+ }
+
+ pub fn switch() -> ToggleBuilder {
+ unsafe {
+ let args = ui_toggle_args_new();
+ ToggleBuilder { args: args }
+ }
+ }
+
+ pub fn radiobutton() -> ToggleBuilder {
+ unsafe {
+ let args = ui_toggle_args_new();
+ ToggleBuilder { args: args }
+ }
+ }
+}
+
+impl Drop for ButtonBuilder {
+ fn drop(&mut self) {
+ unsafe {
+ ui_button_args_free(self.args);
+ }
+ }
+}
+
+impl ButtonBuilder {
+ pub fn build(self) {
+ unsafe {
+ ui_button_create(self.obj, self.args);
+ }
+ }
+
+ pub fn label(self, label: &str) -> Self {
+ let cstr = CString::new(label).unwrap();
+ unsafe {
+ ui_button_args_set_label(self.args, cstr.as_ptr());
+ }
+ self
+ }
+}