Azul is a free, functional, reactive GUI framework for Rust and C++,built using the WebRender rendering engine and a CSS / HTML-like documentobject model for rapid development of beautiful, native desktop applications
Azul is a library for creating graphical user interfaces in Rust and C. It mixesparadigms from functional, reactive and data-oriented programming with an APIsuitable for developing cross-platform desktop applications. The two core principlesof Azul is to not render objects that aren't visible and to use composition of DOMtrees over inheritance.
Azul separates the concerns of business logic / callbacks, data model and UIrendering / styling by not letting the UI / rendering logic have mutable accessto the application data. In Azul, rendering the view is a pure function that mapsyour application data to a styled DOM. "Widgets" are just functions that rendera certain state, more complex widgets use function composition.
Since recreating DOM objects is expensive (note: "expensive" = 3 milliseconds),Azul caches the DOM object and does NOT recreate it on every frame - onlywhen callbacks request to recreate it.
The application and widget data is managed using a reference-countedboxed type (RefAny
), which can be downcasted to a concrete type ifnecessary. Widget-local data that needs to be retained between frames isstored on the DOM nodes themselves, similar to how the HTML dataset
property can be used to store widget data.
The latest release for Windows can be found here.
Currenly I am using this framework to build cross-platform GUI applications: while the frameworkisn't finished yet, it is at least possible to build native, good-looking applicationsfor Windows - for example, here is an Excel clone thatI am working on:
Creating this demo took about two hours. As you can see, the layout system is alreadyquite mature. To run this XML file, download theexamples.zipfolder and exchange the "ui.xml" file for the linked file and restart the xml.exe demo.The XML itself can be hot-reloaded and later be compiled into native Rust code - giving you botha fast design iteration time and native performance.
The application currently takes ~40MB to run and of course almost no CPU at all.
With the correct CSS styles, the window is indistinguishable from a native application:
Azul currently features:
Currently available widgets:
Button
TextInput
(bug: has no cursor / text selection yet)CheckBox
ColorInput
NumberInput
ProgressBar
NodeGraph
Frame
TabControl
Azul also allows for easy creation of custom widgets,for example a node graph widget
All widgets are stylable via CSS. Widgets in progress:
ListView
Spreadsheet
Slider
Dropdown
RadioSelect
RibbonBar
Additionally, Azul features cross-platform MsgBox
and FileDialog
dialogs.
Caveats:
Due to its relatively large size (and to provide C / C++ interop),azul is built as a dynamic library in the azul-dll
package. You candownload pre-built binaries from azul.rs/releases.
AZUL_LINK_PATH
environment variable to the path of the libraryazul.h
on the release page to your project headersand the azul.dll
to your IDE project.The API for Rust, C++ and other languages is exactly the same,since the API is auto-generated by the build.py
script.If you want to generate language bindings for your language,you can generate them using the api.json
file.
To run programs on Linux, you may also need to copy thelibazul.so
into /usr/lib
. Eventually this will be solvedby upstreaming the library into repositories once all majorbugs are resolved.
By default, you should be able to run
cargo install --version 1.0.0 azul-dll
to compile the DLL from crates.io. The library will be builtand installed in the $AZUL_LINK_PATH
directory, which defaults to$CARGO_HOME_DIR/lib/azul-dll-0.1.0/target/release/
Building the library from source requires clang as well asthe prerequisites listed above.
git clone https://github.com/fschutt/azul
cd azul-dll
cargo build --release
This command should produce an azul.dll
file in the/target/release
folder, in order to use this, you willalso need to set AZUL_LINK_PATH
to $BUILD_DIR/target/release/
.
If you are developing on the library, you may also need tore-generate the Rust / C API, in which case you should preferto use the build.py
script:
python3 ./build.py
Note: The widgets are custom to each programming language. All callbackshave to use extern "C"
in order to be compatible with the library.The binary layout of all API types is described in theapi.json
file.
See the /examples folder for example code in different languages
use azul::prelude::*;
use azul_widgets::{button::Button, label::Label};
struct DataModel {
counter: usize,
}
// Model -> View
extern "C" fn render_my_view(data: &RefAny, _: LayoutInfo) -> StyledDom {
let mut result = StyledDom::default();
let data = match data.downcast_ref::<DataModel>() {
Some(s) => s,
None => return result,
};
let label = Label::new(format!("{}", data.counter)).dom();
let button = Button::with_label("Update counter")
.onmouseup(update_counter, data.clone())
.dom();
result
.append(label)
.append(button)
}
// View updates model
extern "C" fn update_counter(data: &mut RefAny, event: CallbackInfo) -> UpdateScreen {
let mut data = match data.downcast_mut::<DataModel>() {
Some(s) => s,
None => return UpdateScreen::DoNothing,
};
data.counter += 1;
UpdateScreen::RegenerateDomForCurrentWindow
}
fn main() {
let app = App::new(RefAny::new(DataModel { counter: 0 }), AppConfig::default());
app.run(WindowCreateOptions::new(render_my_view));
}
#include "azul.h"
#include "azul-widgets.h"
using namespace azul;
using namespace azul.widgets.button;
using namespace azul.widgets.label;
struct DataModel {
counter: uint32_t
}
// Model -> View
StyledDom render_my_view(const RefAny& data, LayoutInfo info) {
auto result = StyledDom::default();
const DataModel* data = data.downcast_ref();
if !(data) {
return result;
}
auto label = Label::new(String::format("{counter}", &[data.counter])).dom();
auto button = Button::with_label("Update counter")
.onmouseup(update_counter, data.clone())
.dom();
result = result
.append(label)
.append(button);
return result;
}
UpdateScreen update_counter(RefAny& data, CallbackInfo event) {
DataModel data = data.downcast_mut().unwrap();
data.counter += 1;
return UpdateScreen::RegenerateDomForCurrentWindow;
}
int main() {
auto app = App::new(RefAny::new(DataModel { .counter = 0 }), AppConfig::default());
app.run(WindowCreateOptions::new(render_my_view));
}
#include "azul.h"
typedef struct {
uint32_t counter;
} DataModel;
void DataModel_delete(DataModel* restrict A) { }
AZ_REFLECT(DataModel, DataModel_delete);
AzStyledDom render_my_view(AzRefAny* restrict data, AzLayoutInfo info) {
AzString counter_string;
DataModelRef d = DataModelRef_create(data);
if (DataModel_downcastRef(data, &d)) {
AzFmtArgVec fmt_args = AzFmtArgVec_fromConstArray({{
.key = AzString_fromConstStr("counter"),
.value = AzFmtValue_Uint(d.ptr->counter)
}});
counter_string = AzString_format(AzString_fromConstStr("{counter}"), fmt_args);
} else {
return AzStyledDom_empty();
}
DataModelRef_delete(&d);
AzDom const html = {
.root = AzNodeData_new(AzNodeType_Body),
.children = AzDomVec_fromConstArray({AzDom_new(AzNodeType_Label(counter_string))}),
.total_children = 1, // len(children)
};
AzCss const css = AzCss_fromString(AzString_fromConstStr("body { font-size: 50px; }"));
return AzStyledDom_new(html, css);
}
UpdateScreen update_counter(RefAny& data, CallbackInfo event) {
DataModelRefMut d = DataModelRefMut_create(data);
if !(DataModel_downcastRef(data, &d)) {
return UpdateScreen_DoNothing;
}
d->ptr.counter += 1;
DataModelRefMut_delete(&d);
return UpdateScreen_RegenerateDomForCurrentWindow;
}
int main() {
DataModel model = { .counter = 5 };
AzApp app = AzApp_new(DataModel_upcast(model), AzAppConfig_default());
AzApp_run(app, AzWindowCreateOptions_new(render_my_view));
return 0;
}
The documentation is built using the build.py
script, whichwill generate the entire azul.rs
website in the /target/html
directory:
python3 ./build.py
NOTE: The class documentation can also be printed as aPDF if you prefer that.
This library is licensed under the LGPL version 3.0 with anexception for static linking. Which means that similar tothe FLTK and wxWidgets license, you can build proprietaryapplications without having to publish your source code:you only have to publish changes made to the azul libraryitself. The static linking exception allows you to staticallylink Azul without having to publish your code.
Copyright 2017 - current Felix Schütt
您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn. 安装适用于 Azure 和 Azure Stack 的 JDKInstall the JDK for Azure and Azure Stack 4/19/2019 本文内容 Azul Zulu Enterprise 内部
2019年1月对于Java开发人员和用户都特别重要。原因是Oracle JDK 8发布了更新202,这是Oracle的JDK 8的最终公开更新(针对商业用户)。用户现在需要仔细考虑将来如何更新升级Java版本了。 对于非商业桌面用户,将继续通过现有Java Update机制提供对Oracle Java SE 8的更新。根据Oracle的说法,这将是“ ......至少到2020年底。 ”假设,当第
azul zing Azul Systems的人们为嵌入式,移动和物联网(IoT)市场的开发人员和制造商推出了一项新产品:向Zulu Embedded打招呼。 Azul希望通过生产兼容Java 6、7和8的开源,可定制的Java SE解决方案来与Oracle的Java Development Kit保持一致。Azul的替代Java环境产品组合中的这一新功能旨在面向从事代码开发工作的开发人员。路由器
azul zing 替代JVM的构建者Azul Systems的CTO和联合创始人Gil Tene从90年代中期开始就将基于Java的产品组合在一起。 在最初发表于4月版的《 JAX杂志》的这次采访中,他对平台的最新化身投以了难以置信的经验,并告诉我们他对Java 9路线图的看法。 JAX:您认为Java 8将带给JVM最重要的事情是什么? 泰恩:我认为Java 8有两到三个不同的重要内容–只有其
azul zing 这是我们接受Azul Systems首席技术官Gil Tene采访的第二部分。 第一部分在这里可用。 JAX:您显然是Java社区流程的一部分,尤其是您在2011年11月投票支持的执行委员会。这样做的主要推动力是什么,您希望从中实现什么? Gil Tene:Azul可以呼吸Java。 我们构建可扩展的JVM。 我们已经成为JCP的成员已有9年了,但是大部分时间我们都得到了部分好
Azul Java 平台产品不受CVE-2021-44228 和 CVE-2021-45046 影响 Azul 拥有专业的市场团队,同时也已经组建大中华区支持团队 Azul Platform Core、Platform Prime 和 Intelligence Cloud 产品性价比高、安全可靠且性能优越,堪称客户优选 加利福尼亚州森尼韦尔市 -- (美国商业资讯)--Azul 今日发布了有关 C