natinusala / borealis Goto Github PK
View Code? Open in Web Editor NEWHardware accelerated, controller and TV oriented UI library for PC and Nintendo Switch (libnx)
License: Apache License 2.0
Hardware accelerated, controller and TV oriented UI library for PC and Nintendo Switch (libnx)
License: Apache License 2.0
Hello there :)
I've been working with borealis to build a GUI for SMM, and I would like to add a progress bar layout while the program is executing something (std::async). I tried different things but it seems I can't use brls::Dialog as a class template to do this. So I was wondering maybe this could be interesting to have a kind of template to display anything (like a progress bar) in the style of brls::Dialog::open().
But if you have a better idea to display a popup progress bar (a bit like tinfoil for example) with what's already existing, it would be great too!
Cheers
To be done:
lib/platforms/switch/swkbd.cpp
from meson.build
, move and adapt current swkbd
file to switch_keyboard
impl)Self explanatory.
Depends on #88
There is a segfault when borealis tries to render a sidebar with no children.
Unsure if this is intended, but a quick fix is trivial.
// File: library/lib/sidebar.cpp
View* Sidebar::getDefaultFocus()
{
...
// Line 43
View* toFocus{ nullptr };
if(this->children.size() != 0)
// Try to focus last focused one
toFocus = this->children[this->lastFocus]->view->getDefaultFocus();
...
}
Here's an easy fix
// File: library/lib/tab_frame.cpp
void TabFrame::switchToView(View* view)
{
...
// Line 66
this->rightPane = view;
if (this->rightPane != nullptr)
this->layout->addView(this->rightPane, true, true); // addView() calls willAppear()
}
Self explanatory. If you have a better name please don't hesitate to tell me.
Make it in two parts: one EditView
view that's just the content, so that people can use it in their own AppletFrame
s, as well as a standalone EditFrame
that's AppletFrame
+ EditView
for convenience.
There should be two modes:
TabFrame
works)TabFrame
should also be changed to use the new LayerView
internally, using free / allocate mode.
A concept of "layer" must be introduced, to allow adding stuff below and over activites without hardcoding them in Application
.
A layer has a "draw" method and is simply resized to fullscreen when the window gets resized (like activities are). A "ViewLayer" layer must be done, which takes a "root" view and handles layout, etc... the same way the activities work. When a ViewLayer
is resized, its view is resized and a layout pass must be done.
The current activities stack must be moved to its own layer. When the window is resized it must resize all layers, which will in turn resize all activities, running a layout pass on each one of them.
Notifications and framerate counter should be on their own layer too. They of course have to be reimplemented using the new layout system.
Notifications should be able to be placed on any corner of the screen. As as for the dialogs, notifications should be both easy to use and extensible - users should be able to post simple text notifications as well as custom views if they want fancy / custom stuff.
Depends on #150 to animate notifications, as well as #154 for the actual framerate counter.
To do list:
ViewLayer
Application
codeHello!
is there any way to get a value from any listitem?
if i cant get the value could you make public unsigned selectedValue;
?
also i need block "+" because when i start the system update i can exit from the app.
(I don't know if borealis already has that options.)
thanks!
Right now, all XML errors are generated by concatenating strings with the +
operator. We have fmt in the library, so might as well use it instead.
Actually, a global "sprintf"-like function to format to a std::string would be useful, provided by brls in the utils.
Hello,
Is there a way to hide, close or delete a brls::List
object form brls::TabFrame
?
like the opposite of the addTab
function.
As far as I can see it relies on private vector object. there is a lot of classes involve in this process and I do not want to take bad decision.
borealis/library/include/borealis/absolute_layout.hpp
Lines 37 to 39 in 205e97a
Some that would be nice to have are removeView, getChild, and clear
Pretty self explanatory. The "valued" list items with a "value set" callback should be renamed to SettingListItem
, with their value type as prefix (BoolSettingListItem
...).
One issue is to figure out how to handle spacing between ListItems
when putting multiple ones in a vertical Box
. The same separator must be used when two items are close to each other, which means we need a way for an item to be aware of its surroundings.
An okay solution would be to add a "ListItemGroup" view that handles spacing between the items, the same way a checkbox group works on the web. List items should be usable with and without a group.
Depends on #96
There are cases where the pulsation is not visible, for instance when focusing the primary button in the demo.
The highlight animation should be looked into and fixed.
Hello,
First, thank you for your amazing work.
I would like to move my current GUI to borealis.
My objective is to delegate video to my core FFMPEG application.
Currently, the app is using SDL2(audio, video, gamepad, touchscreen) as main interface (but I can switch video to opengl easily).
I'm experiencing with borealis' view (StagedApplet) and nvgluCreateFramebuffer.
But I think I misunderstood the project philosophy.
Could you please give me some hints on how to implement video "player" (best practices)
My question are the following:
How to integrate/delegate raw OpenGL app in borealis (in fullscreen) ?
Any suggestion for audio/gamepad/touchscreen ?
I also searched across others borealis project without success.
Thank you a lot
Depends on #107
TransitionAnimation
should only be used for activities and view stacksWhen we start the app, the whole UI is created from the XML files. Every little XML view and attribute causes a whole layout pass on the entire activity view tree, which is bad.
We need a way to know when we are loading an XML file and differ all layout passes until this is done, do only do ONE pass in the end instead of multiple dozens.
The soundboard should be able to play all sounds supported by borealis.
But make it better with a fully dynamic number of rows and columns. No reason to make it suck now that we have yoga to take care of the layout for us.
What's left:
onControllerButtonPressed
setActive
when a sidebar item is selected, just like HOS does (this avoids creating and deleting every tab one after the other when going down the list by holding the DOWN button)Linked issue in sys-clk: retronx-team/sys-clk#23
borealis does not seem to display Korean characters (attached screenshots in the linked issue), this is probably due to the fact only the regular and the symbol font is loaded. The solution to solve this can be to load the other fonts returned by pl
, and add them as a fallback font of the current regular font nvgAddFallbackFontId(...)
Pretty self explanatory.
Depends on #95
The only things missing are footer and hint once #88 is done.
addView
and removeView
to call setContentView
like ScrollingFrame
already hasHello there,
I'm trying to use borealis as a submodule for my Switch homebrew SimpleModManager. I included the borealis lib with cmake in my project, and the compilation seems to work fine. However when I try to launch it on the Switch it crashes.
I've tried to isolate the problem and it seems like it comes from there :
// Init glfw
glfwSetErrorCallback(errorCallback);
glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
if (!glfwInit())
{
Logger::error("Failed to initialize glfw");
return false;
}
...
Application::window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, title.c_str(), nullptr, nullptr); // here is the crash
When glfwInit()
is called, it makes glfwCreateWindow
crashing.
Have you any clue on where it could come from ?
P.-S. Great GUI by the way :) It's been a while since I've looked for a kind a neutral GUI lib for the swich!
This crashes. Very likely related to #29 but for BoxLayout.
brls::AppletFrame* rootFrame = new brls::AppletFrame(false, false);
brls::List* myList = new brls::List();
rootFrame->setContentView(myList);
brls::Application::pushView(rootFrame);
Should be pretty straightforward.
What's left to do:
getDefaultFocus
to try to focus the right pane insteadThat one is popular!
Requires #107 to animate the step changes while keeping the staged applet frame the same.
To be done:
FIT
and CROP
scaling typesTILED
scaling type using NVGimageFlags
if possibleImageAlignment
enum, implement it for all scaling typesThe concept of "drawing" can be defined in its own class. It would allow generalizing things like shapes, with common properties such as border color / radius, corner radius, shadow, etc...
A drawing is made of one or multiple layers.
A layer is made of multiple properties:
Basically the same thing as what make the view backgrounds now.
Note: the current view background has a stub for a "custom" shadow that's not actually implemented. It should be implemented in drawings. The idea is to ask the user for all shadow properties (width, feather, opacity, offset).
View backgrounds can then be entirely replaced with a single Drawing
, which will then take care of all the rendering.
draw
method (the same as the one in View
)View
inherit from Drawable
Drawing
class, also inheriting from Drawable
, taken from the current view backgrounds@theme
, @style
... in drawing XML files,Drawing
instance (also remove all custom backgrounds like sidebar...)drawing
XML type for views: @drawing/...
to reference drawings for view background for example (and add a backgroundDrawing
attribute)DrawableView
method that takes a Drawable
and simply draws it across its entire surfaceAs in title. I will provide info on two examples resulting in different behavior.
Example 1:
#include <stdio.h>
#include <stdlib.h>
#include <borealis.hpp>
#include <string>
int main(int argc, char* argv[])
{
// Init the app
brls::Logger::setLogLevel(brls::LogLevel::DEBUG);
if (!brls::Application::init("Borealis example"))
{
brls::Logger::error("Unable to init Borealis application");
return EXIT_FAILURE;
}
// Create a sample view
brls::TabFrame* rootFrame = new brls::TabFrame();
brls::AppletFrame* _appletFrame = new brls::AppletFrame(true, true);
//Set title
rootFrame->setTitle("Borealis Example App");
_appletFrame->setTitle("Borealis Example App");
//Create lists
brls::List* testList = new brls::List();
brls::List* testList2 = new brls::List();
//Create listItem pushing view to AppletFrame
brls::ListItem* HideTabItem = new brls::ListItem("Hide tab");
HideTabItem->getClickEvent()->subscribe([_appletFrame](brls::View* view) {
brls::Application::pushView(_appletFrame);
});
testList->addView(HideTabItem);
rootFrame->addTab("Main", testList);
//Create listItem pushing view to rootFrame
brls::ListItem* ShowTabItem = new brls::ListItem("Show tab");
ShowTabItem->getClickEvent()->subscribe([rootFrame](brls::View* view) {
brls::Application::pushView(rootFrame);
});
testList2->addView(ShowTabItem);
_appletFrame->setContentView(testList2);
// Add the root view to the stack
brls::Application::pushView(rootFrame);
// Run the app
while (brls::Application::mainLoop())
;
// Exit
return EXIT_SUCCESS;
}
By using clickEvent to push AppletFrame view then go back by pushing TabFrame view results in crash when trying to exit by using home menu and dedicated button. Provided example is returning 0x2A8 error.
Crash report:
01601141633_010000000000100d.log
Example 2:
#include <stdio.h>
#include <stdlib.h>
#include <borealis.hpp>
#include <string>
int main(int argc, char* argv[])
{
// Init the app
brls::Logger::setLogLevel(brls::LogLevel::DEBUG);
if (!brls::Application::init("Borealis example"))
{
brls::Logger::error("Unable to init Borealis application");
return EXIT_FAILURE;
}
// Create a sample view
brls::TabFrame* rootFrame = new brls::TabFrame();
brls::AppletFrame* _appletFrame = new brls::AppletFrame(true, true);
//Set title
rootFrame->setTitle("Borealis Example App");
_appletFrame->setTitle("Borealis Example App");
//Create lists
brls::List* testList = new brls::List();
brls::List* testList2 = new brls::List();
//Create listItem pushing view to AppletFrame
brls::ListItem* HideTabItem = new brls::ListItem("Hide tab");
HideTabItem->getClickEvent()->subscribe([_appletFrame](brls::View* view) {
brls::Application::pushView(_appletFrame);
});
testList->addView(HideTabItem);
rootFrame->addTab("Main", testList);
//Create listItem pushing view to rootFrame
brls::ListItem* ShowTabItem = new brls::ListItem("Show tab");
ShowTabItem->getClickEvent()->subscribe([rootFrame](brls::View* view) {
brls::Application::popView();
});
testList2->addView(ShowTabItem);
_appletFrame->setContentView(testList2);
// Add the root view to the stack
brls::Application::pushView(rootFrame);
// Run the app
while (brls::Application::mainLoop())
;
// Exit
return EXIT_SUCCESS;
}
By using clickEvent to push AppletFrame view, go back by using popview and again push AppletFrame it will stuck and crash in few seconds. Provided example is returning 0x2A8 error.
Crash report:
01601142026_010000000000100d.log
Earlier few times I also got 0x6A8 error with different code using similar methods, but I cannot replicate it now. Only what I have is crash report:
01600894264_010000000000100d.log
FW 10.1.0
Atmosphere 0.13.0
Using album and title replacement mode (in second case it just crash app, not whole system)
What's missing:
Sidebar
)addView(View* bool defaultFocus)
, a method on its own setDefaultFocus
and an XML attribute referencing the default view by ID (defaultFocus="my/id"
on the box, my/id
being one of the child views). Don't use index anymore.How interested would you and other developers be on having a consistent design system working along with Borealis?
I started last year to build one, called Aurora Ds, but ended up stopping due to a couple of reasons.
You can check out the skeleton here, with a few elements borrowed from a few people for a quicker ramp up :P
The idea is to document and support all current and future Borealis components and layouts and simplify the work of developers and makers on bringing new apps to life.
Using figma with it's very permissive free tier, allows easy replication and building new UI's from components, that will be mapped to Borealis's code.
Eventually a plugin for figma could be built to export either themes or layouts, with it's simple plugin framework, or directly through API access. This is similar to what I already today with Diez Framework: https://diez.org/.
I think this could vastly simplify building in a very visual way and create richer experiences.
I also loved how attuned we are ๐ , Aurora (design system) Borealis (UI library).
I noticed that there is a COPYING file at the root of the project (which I presume is because of using skeleton from fincs/hybrid_app). Would it not be a better idea to move that to a separate folder like licenses/hybrid_app.license
. Reason I ask this is because I got confused about two licenses being provided for the project and had to do some headscratching to figure why the zlib license was present for.
What's left:
Dialogs should be easier to use now, with multiple ways to create them:
The aim is for the dialogs to be super easy to use while allowing customization to various levels. Inheritance is your friend.
This is a hairy one because I would like a way to treat Image
and MaterialIcon
the same way (and potentially more icons / images classes in the future).
The point is to add either an image or an icon in a button, applet frame header, etc... using the same method for both. That way we can swap one for the other without any trouble. The easy way would be to replace the image with a View*
but I'm sure we can do better.
The MaterialIcon
should not be reimplemented using Label
as a base as it is overkill. It should use its own drawing method.
I would also love an abstraction layer for material icons to use a nice enum instead of an ugly char
to identify an icon.
Sometimes people want to make a transition of two views, without necessarily pushing a new activity. For instance you may want to change the content of an applet frame, while keeping the header and footer (or at least without animating them).
The ViewStack
view should allow to stack multiple views, with an optional transition animation between pushs and pops (fade in / out, slide left / right, etc...). The choosen transition animation and "isTranslucent" flag of the view should tell what views can be drawn (all of them or only the top most one).
The behavior is the same as the activity stack so it should be generalized to both, as we also want to animate activity pushes / pops, see #112.
I would also like a StackAppletFrame
that has a ViewStack
as content, but also handles a title and icon stack, linked to the views stack. That is for convenience when using ViewStack
inside AppletFrame
.
I've been trying to use Borealis with JetBrains's CLion IDE, but when I try creating a new TabFrame
, CLion gives the following error:
Allocating an object of abstract class type 'brls::TabFrame' unimplemented pure virtual method 'draw' in 'TabFrame'
CLion uses CMake (specifically CMake 3.17 with the version of CLion that I'm using) to resolve all of the includes, and I do include Borealis in the CMakeLists.txt
file, but I'm using a traditional Makefile
to actually compile the code. The code does compile fine with make
, but that error in CLion is annoying nonetheless. I'm using the latest beta version of CLion 2020.2.
Here's the full code:
#include <borealis.hpp>
int main() {
brls::Logger::setLogLevel(brls::LogLevel::DEBUG);
if (!brls::Application::init("Howl")) {
brls::Logger::error("Failed to initialize Borealis application.");
return EXIT_FAILURE;
}
brls::TabFrame *rootFrame = new brls::TabFrame();
}
And here's the CMakeLists.txt
file (which, again, I don't actually use to compile the code with, but CLion uses it to resolve the includes):
cmake_minimum_required(VERSION 3.17)
project(HowlNX)
set(CMAKE_CXX_STANDARD 17)
include_directories($ENV{DEVKITARM}/include)
include_directories($ENV{DEVKITPRO}/libnx/include)
include_directories(borealis/library/include)
add_executable(HowlNX source/main.cpp)
Hello,
I think the borealis embedded swkbd is pretty cool.
unfortunately I'm using '/' for my project and this option is locked by default in borealis.
borealis/library/lib/swkbd.cpp
Line 65 in d5ba2ea
I would like to propose a PR, but since swkbd flags are only known by the SWITCH version,
I do not know how to properly implement this without altering the linux compatibility.
do you have any idea on how to proceed ?
thank you a lot
Use Yoga's HasNewLayout
and MarkAsSeen
around our onLayout()
to only trigger the event when the layout actually changes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.