Skip to content

Instantly share code, notes, and snippets.

@zheksoon
Last active March 20, 2018 08:07
Show Gist options
  • Save zheksoon/5ed91f694397a73f10aa882affa637d3 to your computer and use it in GitHub Desktop.
Save zheksoon/5ed91f694397a73f10aa882affa637d3 to your computer and use it in GitHub Desktop.
Pure C-complaint React-like syntax proposal for libui for building dynamic native user interfaces in reactive manner
// Pure C-complaint React-like syntax proposal for libui for building dynamic native
// user interfaces in reactive manner.
// "h" function is vararg function that returns itself, so it's possible to chain calls
// without need to write "h" again and again, only in cases you need to break the chain
// with semicolon.
// As its first parameter "h" takes component function pointer of the next definition:
// void Component(uiConstructor h, ...)
// and then list of key-value pairs a-la props in React.js land. The props list must end
// with some special value, which should indicate the end of vararg list (C has no other
// way to determine number of vararg props other than take some signal value or counter
// as a parameter). The special value is "end" constant defined in hypothetical module.
// After "h" call with a component, one must explicitly end component definition by
// calling "h" with the "end" constant as component function pointer - actually the same as
// writting closing tag in HTML or React's JSX.
// Because during UI definition there is no actual calls to components,
// it becomes possible to make React-like component tree reconsilation and diffing, minimizing
// number of real native components updates (not in absolute sense but relative to full updates).
// Also because of the declarativeness it would become possible to pass children to components -
// it wouldn't be possible in imperative constructs because children components are declared later
// than parent component.
// libui control gallery example using the hypothetic syntax and extension functions
void BasicControlPage(uiConstructor h, ...) {
int value;
matchProps("value", &value);
h(VerticalBox, "padded", 1, end)
(HorizontalBox, "padded", 1, end)
(Button, "text", "Button", end)(end)
(Checkbox, "text", "Checkbox", end)(end)
(Label, "text", "This is a label. Right now, labels can only span one line.", end)(end)
(HorizontalSeparator, end)(end)
(end)
(Group, "text", "Entries", "margined", 1, end)
(Form, "padded", 1, end)
(FormItem, "text", "Entry", end)
(Entry, end)(end)
(end)
(FormItem, "text", "PasswordEntry", end)
(PasswordEntry, end)(end)
(end)
(FormItem, "text", "Search Entry", end)
(SearchEntry, end)(end)
(end)
(FormItem, "text", "Multiline Entry", end)
(MultilineEntry, end)(end)
(end)
(FormEntry, "text", "Multiline Entry No Wrap", end)
(NonWrappingMultilineEntry, end)(end)
(end)
(end)
(end)
(end);
}
void NumbersPage(uiConstructor h, ...) {
void onSpinBoxChangedClojure[] = { onSpinBoxChanged, NULL };
void onSliderChangedClojure[] = { onSliderChanged, NULL };
h(HorizontalBox, "padded", 1, end)
(Group, "title", "Numbers", "margined", 1, end)
(VerticalBox, "padded", 1, end)
(Spinbox, "min", 0,
"max", 100,
"onChanged", onSpinBoxChangedClojure,
end)
(end)
(Slider, "min", 0,
"max", 100,
"onChanged", onSliderChangedClojure,
end)
(end)
(ProgressBar, "value", -1, end)(end)
(end)
(end)
(Group, "title", "Lists", "margined", 1, end)
(VerticalBox, "padded", 1, end)
(Combobox, end)
(ComboboxItem, "label", "Combobox Item 1", end)(end)
(ComboboxItem, "label", "Combobox Item 2", end)(end)
(ComboboxItem, "label", "Combobox Item 3", end)(end)
(end)
(EditableCombobox, end)
(EditableComboboxItem, "label", "Editable Item 1", end)(end)
(EditableComboboxItem, "label", "Editable Item 2", end)(end)
(EditableComboboxItem, "label", "Editable Item 3", end)(end)
(end)
(RadioButtons, end)
(RadioButtonsItem, "label", "Radio Button 1", end)(end)
(RadioButtonsItem, "label", "Radio Button 2", end)(end)
(RadioButtonsItem, "label", "Radio Button 3", end)(end)
(end)
(end)
(end)
(end);
}
void DataChoosersPage(uiConstructor h, ...) {
void onOpenFileClickedClojure[] = { onOpenFileClicked, NULL };
void onFileSaveClickedClojure[] = { onSaveFileClicked, NULL };
h(HorizontalBox, "padded", 1, end)
(VerticalBox, "padded", 1, end)
(DatePicker, end)(end)
(TimePicker, end)(end)
(DateTimePicker, end)(end)
(FontButton, end)(end)
(ColorButton, end)(end)
(end)
(VerticalSeparator, end)(end)
(VerticalBox, "padded", 1, end)
(Grid, "padded", 1, end)
(GridItem, "left", 0, "top", 0, end)
(Button, "text", "Open File"
"onClicked", onOpenFileClickedClojure,
end)
(end)
(end)
(GridItem, "left", 1, "top", 0, "hexpand", 1, end)
(Entry, "readOnly", 1,
"text", openFileEntryText, end)
(end)
(end)
(GridItem, "left", 0, "top", 1, end)
(Button, "text", "Save File"
"onClicked", onFileSaveClickedClojure,
end)
(end)
(end)
(GridItem, "left", 1, "top", 1, "hexpand", 1, end)
(Entry, "readonly", 1
"text", saveFileEntryText,
end)
(end)
(end)
(GridItem, "left", 0, "top", 2, "xspan", 2, end)
(Grid, "padded", 1, end)
(GridItem, "left", 0, "top", 0, end)
(Button, "text", "Message Box"
"onClicked", onMshBoxClickedClojure,
end)
(end)
(end)
(GridItem, "left", 1, "top", 0, end)
(Button, "text", "Error Box"
"onClicked", onMshBoxErrorClicked,
end)
(end)
(end)
(end)
(end)
(end)
(end)
(end);
}
void App(uiConstructor h, ...) {
h(Window, "title", "libui Control Gallery"
"width", 640,
"height", 480,
"hasMenubar", 1,
"margined", 1,
end)
(Tab, end)
(TabItem, "magined", 1, end)
(BasicControlPage, end)(end)
(end)
(TabItem, "magined", 1, end)
(NumbersPage, end)(end)
(end)
(TabItem, "magined", 1, end)
(DataChoosersPage, end)(end)
(end)
(end)
(end);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment