azul

Desktop GUI Framework
授权协议 View license
开发语言 C/C++
所属分类 程序开发、 图形/图像处理
软件类型 开源软件
地区 不详
投 递 者 窦夜洛
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Azul - Desktop GUI framework

Build status WindowsCoverage StatusLICENSERust Compiler Version

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

Website | User guide | API documentation | Video demo | Matrix Chat

About

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 datasetproperty can be used to store widget data.

Current progress

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:

image

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:

image

image

Azul currently features:

  • Text input / text entry (see "widgets" demo)
  • Animations @ 60+ FPS (using webrender)
  • CSS support see list of supported CSS keys
  • De- / encoding images and fonts (TTF, WOFF, OTF).
  • Cross-platform text shaping (via allsorts)
  • Parsing and rendering SVG (via resvg)
  • Rendering / embedding OpenGL content (using OpenGL textures)
  • Tesselating shapes into triangles (via lyon)
  • Asynchronously managing running background threads for File I/O
  • Parsing XML (via xmlparser)
  • Stable API

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

image

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:

  • Currently Azul only works on Windows because of rendering problems on X11 and Cocoa
  • Text shaping for non-Latin fonts as well as fallback fonts are rudimentary / non-existent
  • Scrolling, especially smooth scrolling is not yet implemented entirely
  • Scroll bars are not automatically inserted
  • Rich Text Layout has to be calculated manually, not done automatically
  • C++ API is a work in progress
  • Layout engine may have bugs (but those can usually be worked around)
  • Binary ABI is not entirely stable yet
  • Infinite scrolling / lazy loading of DOM content is not yet supported
  • Menus / context menus don't work yet (stub API)

Installation

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.

Using pre-built-binaries

  1. Download the library from azul.rs/releases
  2. Set your linker to link against the library
    • Rust: Set AZUL_LINK_PATH environment variable to the path of the library
    • C / C++: Copy the azul.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.

Building from source (crates.io)

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 from source (git)

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

Example

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

Hello World Application

Rust

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));
}

C++

#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));
}

C

#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;
}

Documentation

The documentation is built using the build.py script, whichwill generate the entire azul.rs website in the /target/htmldirectory:

python3 ./build.py

NOTE: The class documentation can also be printed as aPDF if you prefer that.

License

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

相关阅读

相关文章

相关问答

相关文档