mikke89 / rmlui Goto Github PK
View Code? Open in Web Editor NEWRmlUi - The HTML/CSS User Interface library evolved
Home Page: https://mikke89.github.io/RmlUiDoc/
License: MIT License
RmlUi - The HTML/CSS User Interface library evolved
Home Page: https://mikke89.github.io/RmlUiDoc/
License: MIT License
I'm getting this warning in Visual Studio 2017
'Rml::Core::Variant::Variant<std::tuple<Rml::Core::Variant &&> >': recursive on all control paths, function will cause runtime stack overflow
Variant.inl line 38
I temporarily fixed it with this code:
Variant::Variant(const std::tuple<T>& values)
{
Set(std::get<0>(values));
}
As suggested by @barroto in #2, this fork of libRocket is now quite distinct from the original project. A rename of this work then seems natural.
Some things that me may consider with this change:
What do you think? These are just ideas I'm throwing out there, any ideas you may have are very welcome.
I'm not sure how the original documentation was built, but you seem able to assist here, @barroto?
ElementFormControlSelect.RemoveAll has been cleared, so provisional support.
ElementFormControlSelect.RemoveAll("accessory-window", "actor-selector") -- Bug fixes local select = AsSelect(document:GetElementById('actor-selector')) select.inner_rml = contents select.value = ''
Usage of RmlUi would be a lot simpler if we removed the sub-namespaces. I don't feel like they are really necessary.
Thus,
Rml::Core::Element* element;
Rml::Controls::ElementFormControl* control_element;
Rml::Core::Log::Message(Rml::Core::Log::LT_WARNING, "...");
would become
Rml::Element* element;
Rml::ElementFormControl* control_element;
Rml::Log::Message(Rml::Log::LT_WARNING, "...");
We may need to keep the namespaces for some functions, so this stays the same:
Rml::Core::Initialise();
Rml::Controls::Initialise();
or, maybe remove it for core?
Rml::Initialise();
Rml::Controls::Initialise();
I haven't tried it to see if there are any name conflicts, but worst case is we need to do some renaming.
Thoughts?
I just don't really see the benefits of the Stream
class. We are not loading files so big that they need to be streamed in parts. And we don't really need support for Write() and several other functions that are implemented.
The parsing in particular could be simplified a lot (and probably made faster) by just using a String or StringView in the necessary places.
Anybody have objections to this?
Similarly, the URL class is very big and overly generalized. Do we really need parameters, login/password fields? Perhaps it can all be replaced by a simple URL string, and a way to combine two URLs to resolve relative paths. This is lower priority though, as it doesn't really complicate the rest of the codebase. It's really big though, over 400 bytes here.
Finally, the FileInterface
is really only used internally to read in whole files at a time. Thus, why not replace it with a single method to do exactly this?
Hi, I'm just experimenting with Samples programs, and it seems that range's orientation attribuite, if specified as both horizontal and vertical, displays the trackbar collapsed with only + and - images visibile.
Is there any way to see this feature implemented just like AngularJS or CoherentGT?
Some examples:
https://www.w3schools.com/angular/angular_databinding.asp
https://coherent-labs.com/Documentation/cpp-gt/df/dfb/_h_t_m_l_data_binding.html
Also would be cool to create DataTemplates through bindings and converters.
Implement scaling modes for the image decorator, e.g. such as:
Also, consider adding a 'fixed-size' center mode for tiled-horizontal, tiled-vertical, and tiled-box decorators.
See discussion in: #22 (comment)
I've given quite some effort lately into improving the performance of the library, and especially for creation and destruction of elements which can sometimes be slow.
There are some breaking changes, so I'm taking some extra time before merging into master:
To give some numbers, I'm getting a 3.5x (!) speedup during heavy construction / destruction of elements, compared to before I started the performance branch. From 18.5 to 65.0 FPS for more than 500 elements per update loop. These numbers do not even include earlier performance improvements. And I'm not done yet ;)
I think I'm mostly reaching out to discuss the performance of librocket in general, as well as what you think about these breaking changes. Any thoughts?
T Element::GetProperty(const String& name)
{
const Property* property = GetProperty(name);
RMLUI_ASSERTMSG(property, "Invalid property name.");
return property->Get< T >();
}
The code should also check for property
not being nullptr
after the assert because RMLUI_ASSERTMSG
expands to nothing in release builds, and if property
is a nullptr
indeed, the program will crash with segmentation fault.
Every UI library needs a gallery!
I started adding some screenshots in the documentation:
https://mikke89.github.io/RmlUiDoc/pages/gallery.html
And the idea is to put all or some of these in the Readme
here.
Ideally, we want something that showcases various parts of the library, and looks nice at the same time. Although, I'm not sure if all of those examples look too good?
Perhaps you're using RmlUi in a project yourself, and you'd be willing to share screenshots? Then please add them here with a reply :)
It would also be nice to have some links to projects using RmlUi, so if you'd like you can leave a link with your screenshots and I'll add them to the gallery.
Build error occurs in VisualStdio Android development environment.
The build is RMLUI_STATIC_LIB only
gnustl_static
Code I tentatively addressed
./Include/RmlUi/Core/Types.h
template <class T> struct hash { using utype = typename ::std::underlying_type<T>::type; size_t operator() (const T& t) const { ::std::hash<utype> h; return h(static_cast<utype>(t)); }
to
``
#ifdef ANDROID
template <> struct hash<::Rml::Core::PropertyId> {
using utype = typename ::std::underlying_type<::Rml::Core::PropertyId>::type;
size_t operator() (const ::Rml::Core::PropertyId& t) const { ::std::hash h; return h(static_cast(t)); }
#endif
``
This one is spewed at you on each RmlUi file or include when compiling for x86_64 in Visual studio.
This change should make it more clear that we will be merging this into master once everything is ready. Develop branch will become RmlUi v3.0.
Also, just letting you know I'm leaving for vacation next week, so there will be less activity from me for the following three weeks.
Happy coding :)
It'd be awesome of RmlUi didn't insist on being compiled with RTTI enabled. First and foremost, it would reduce the footprint of the library considerably. Second of all, this should reduce compilation time. And on top of that, it would make integrating the library into RTTI-less projects easier.
There are all kinds of RTTI and dynamic_cast replacements found on the Internet, however this particular one caught my attention: http://kahncode.com/2019/09/24/c-tricks-fast-rtti-and-dynamic-cast/
While the work on increasing performance is well underway with great results already, there are some ideas that could improve it further but break some existing things, and possibly reduce some of the generality of the library.
Specifically, strings are passed and copied everywhere around in the code and need to be looked up in hash tables quite a lot. Especially for properties, events, and possibly pseudoclasses. What I propose instead is to use simple numeric IDs, one specific for each property. Everything would become much simpler then if we disallow custom property names (such as those used by decorators) and events.
But of course, we're not getting rid of decorators! Instead, I think we can improve them.
I think it is kind of awkward currently to have to specify the exact subrectangle in a texture right inside the decorator declaration. Instead, I propose first that we enable somehow to define a spritesheet with all subrectangles defining a given sprite in one place. Then we introduce a new property, either decorator
or background-image
(as in css) which specifies a decorator by combining possibly multiple sprite names from the spritesheet, and comma-separated for multiple decorators.
E.g. something like this:
@spritesheet(invader-theme) {
src: invader-theme.png;
invader-left: 10px 40px 30px 10px;
...
}
button.invader {
decorator: tiled-horizontal(invader-left, invader-center, invader-right), image(button-bg);
}
One of the nice things is that we could then easily replace the whole spritesheet (1) to change to a different theme, or more importantly, (2) to specify a higher resolution image when the dp unit changes so that the textures are crisp at say 1dp==2px.
Thoughts?
This is somewhat a continuation of issue #40. Consider the following scenario:
I think this is a good time to deprecate things that seem really out-of-date. For example, the docs mention Python 2.5 (!) support only. Generally I think Lua is the better way for our audience, being a lot easier to integrate. My impression is that Lua is much more wide-spread in the game-dev community at least.
A list of things which I suggests we remove completely:
This one is weird but it seems that on the develop branch, the document element never receives the "load" event. I can see the call to DispatchEvent alright but it just doesn't work for me for some reason. Things like "focus" and "blur" do make it to ProcessDefaultAction though.
Hello mate!
I've also added animations and transform features to libRocket long time ago, I've also added duktape for javascript bindings, however your work looks more complete.
I've dropped libRocket only because of a few features that were missing:
Are you planning to implement these features in the near future?
Also, is there any WYSIWYG editor for libRocket?
Thanks in advance.
Hi, calling
ElementFormControlSelect::Add(rml, value, -1, true);
return an index 0 or 1.
This should be due to the call to
int WidgetDropDown::AddOption(const Rml::Core::String& rml, const Rml::Core::String& new_value, int before, bool select, bool selectable)
{
Core::ElementPtr element = Core::Factory::InstanceElement(selection_element, "*", "option", Rml::Core::XMLAttributes());
element->SetInnerRML(rml);
bool result = AddOption(std::move(element), new_value, before, select, selectable);
return result;
}
where result is converted to bool.
The major difference between stock libRocket and our own fork here https://github.com/Qfusion/libRocket is that the former manages its own library of fonts and glyphs and is closely tied to freetype. Quite often this is an undesired behaviour: bitmap fonts, fonts are managed by the application, etc.
Related PR:
https://github.com/libRocket/libRocket/pull/267/files
Related commit in our fork:
Qfusion/libRocket@c0d15d8
The downside of our implementation isn't able to handle font effects as it doesn't export rendered glyphs to libRocket.
I have troubles compiling the master branch in appveyor due to the following error:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\vector(1889): error C2036: 'Rocket::Core::Transforms::Primitive *': unknown size [C:\projects\librocket\Build\RocketCore.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\vector(1872): note: while compiling class template member function 'bool std::vector<Rocket::Core::Transforms::Primitive,std::allocator<_Ty>>::_Buy(const unsigned int)'
with
[
_Ty=Rocket::Core::Transforms::Primitive
]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\vector(735): note: see reference to function template instantiation 'bool std::vector<Rocket::Core::Transforms::Primitive,std::allocator<_Ty>>::_Buy(const unsigned int)' being compiled
with
[
_Ty=Rocket::Core::Transforms::Primitive
]
c:\projects\librocket\include\rocket\core\Transform.h(83): note: see reference to class template instantiation 'std::vector<Rocket::Core::Transforms::Primitive,std::allocator<_Ty>>' being compiled
with
[
_Ty=Rocket::Core::Transforms::Primitive
]
A whole game engine can be compiled in the time it takes to compile RmlUI alone :P
It would be nice if the compilation time of RmlUI could be reduced. The precompiled header helps but not that much because of the heavy use of templates.
I recall profiling it using MSVC's /d2cgsummary flag (see https://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/ ), but I can't remember any details anymore. My best guess would be that most of the time comes from the monstrous Core.h include file but we need that to be re-verified.
I know it's been suggested before, but here's a more less working implementation, which can be salvaged for RmlUI: https://github.com/Qfusion/qfusion/blob/master/source/ui/decorators/ui_gradient_decorator.cpp
I think it's missing three major things (but none are critical in my opinion):
Comments and suggestions are welcome :)
This looks potentially useful and viable for promotion to a stock widget but needs proper merging and a sample program.
At the moment GetElapsedTime divides SDL_GetTicks by 1000 (integer) as a result it returns a rounded value. It should be fixed in this way:
double RmlUiSDL2SystemInterface::GetElapsedTime()
{
return SDL_GetTicks() / 1000.0;
}
The datagrid cells don't currently scale to the width of the table.
I'm not sure if it's desired behavior that the value is normalized?
For example the a is changed to 21 it fires an value of 0.21.
For other min max values the example wouldn't be nice anymore, because the event is returning the slider position instead of the value.
I feel like we have a considerable amount of features in the develop branch now, and it's time we merge it with master soon for an official 3.0 release.
The obvious major thing missing is documentation of all the new features, and we probably need to go through all the existing documentation as a lot of details have been changed. The changelog is quite exstensive, and should serve as a good starting point.
If there is something you feel should be done before the release of RmlUi 3.0, then let's discuss it here. Also if you find or know of any larger bugs or stability issues, it would be nice to have these resolved before the release.
Please add:
ProgressBar: https://github.com/crazyjul/libRocket/tree/master/Contrib
CircularBar: https://github.com/FishingCactus/libRocketCircularBar
Can you enable GitHub's Issues for RmlUiDoc?
The font interface libRocket as a whole relies on "font-charset". If this applies to RmlUi is there a possibility of removing font-charset workaround in order to simply generate glyphs as needed or at least let me use my own better font renderer.
I mostly say this as I want to use emoji and russian and many other languages (depending on user choice).
Hi,
thanks for your on animation support for libRocket! Unfortunately due to various operating systems, libs and compilers still catching up with C++17 features, compiling your fork is some real pain. The most problematic bit is std::variant and std::visit, the later is only available in MacOS 10.14 and llvm installed from brew.
Now please forgive my ignorance, but was using std::variant really necessary or maybe there's a way to get rid of it at the expense of a few additional lines of code?
Thanks.
Could anyone help with this?
Oddly enough but I seem to be unable to compile RmlUi in Travis for my own project and it seems rightfully so:
In file included from /home/travis/build/Qfusion/qfusion/third-party/libRocket/Source/Core/../../Include/RmlUi/Core/Types.h:51:
/home/travis/build/Qfusion/qfusion/third-party/libRocket/Source/Core/../../Include/RmlUi/Core/Containers/robin_hood.h:657:22: error: implicit instantiation of undefined template 'std::hash<Rml::Core::PropertyId>'
struct hash : public std::hash<T> {
^
/home/travis/build/Qfusion/qfusion/third-party/libRocket/Source/Core/../../Include/RmlUi/Core/Containers/robin_hood.h:743:11: note: in instantiation of template class 'robin_hood::hash<Rml::Core::PropertyId>' requested here
: public Hash,
^
/home/travis/build/Qfusion/qfusion/third-party/libRocket/Source/Core/../../Include/RmlUi/Core/PropertyDictionary.h:87:14: note: in instantiation of template class 'robin_hood::detail::unordered_map<true, 80, Rml::Core::PropertyId, Rml::Core::Property, robin_hood::hash<Rml::Core::PropertyId>, std::equal_to<Rml::Core::PropertyId> >' requested here
PropertyMap properties;
^
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/functional_hash.h:58:12: note: template is declared here
struct hash;
PropertyId is a enum class and using it as a key for unordered_map requires a specialized hash function but it appears RmlUi is providing one.
Hi, I'm on master and this is the output when running cmake on Linux Ubuntu 19.10 (CMake 3.13):
$ cmake ..
CMake Warning (dev) at /usr/share/cmake-3.13/Modules/FindOpenGL.cmake:270 (message):
Policy CMP0072 is not set: FindOpenGL prefers GLVND by default when
available. Run "cmake --help-policy CMP0072" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
FindOpenGL found both a legacy GL library:
OPENGL_gl_LIBRARY: /usr/lib/x86_64-linux-gnu/libGL.so
and GLVND libraries for OpenGL and GLX:
OPENGL_opengl_LIBRARY: /usr/lib/x86_64-linux-gnu/libOpenGL.so
OPENGL_glx_LIBRARY: /usr/lib/x86_64-linux-gnu/libGLX.so
OpenGL_GL_PREFERENCE has not been set to "GLVND" or "LEGACY", so for
compatibility with CMake 3.10 and below the legacy GL library will be used.
Call Stack (most recent call first):
CMakeLists.txt:459 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
Documentation for this is here, under the "Linux-specific" section.
This can be fixed adding to CMakeList.txt
either
if (POLICY CMP0072)
cmake_policy (SET CMP0072 NEW)
endif(POLICY CMP0072)
or
set(OpenGL_GL_PREFERENCE "GLVND")
just before find_package(OpenGL REQUIRED)
bool FocusFirstTabElement(void) { return FocusNextTabElement(this, true); }
We use this function to focus on the first "tabbable" element when the document is displayed for the first time, if possible. Make sense for modal dialogs, input forms and such.
Please consider adding this function to the public API or maybe, as an alternative, a new Focus flag with similar functionality.
And replace them with unique_ptr, or shared_ptr where strictly necessary. E.g. elements should uniquely own their children. Replace AddChild with CreateChild so users don't have to move them on every element creation.
All use of raw pointers should then denote a non-owning pointer.
The methods that worked in libRocket are gone.
Please implement it because you want to change the pixel size according to the screen size.
This method is used in our touch input handler and looks like a potentially useful API method in general. Any thoughts or objections?
In the Android environment, OpenGL resources are automatically destroyed when the application is put on standby. I want to rebuild the resources. What should I do?
// Rml::Core::ReleaseCompiledGeometries(); not found
Rml::Core::ReleaseTextures();
The following line produces an assertion failure in debug build in MSVC:
for (auto it = begin; it != end; ++it)
Further down the stack:
_Vector_const_iterator& operator++()
{ // preincrement
#if _ITERATOR_DEBUG_LEVEL != 0
const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
_STL_VERIFY(_Ptr, "can't increment value-initialized vector iterator");
_STL_VERIFY(_Ptr < _Mycont->_Mylast, "can't increment vector iterator past end");
#endif /* _ITERATOR_DEBUG_LEVEL != 0 */
The _Mycont pointer is null
Basically, what I'm suggesting for now is porting over the touch events glue code from qfusion. For that, RmlUi would need to introduce one new API call that translate touch events into mouse events:
Context::ProcessTouchEvent(ev_type, x, y)
Here's the boilerplate code for Context::ProcessTouchEvent:
context->ProcessMouseMove( x, y, KeyConverter::getModifiers() );
if( type == TOUCH_DOWN ) {
context->ProcessMouseButtonDown( 0, KeyConverter::getModifiers() );
} else {
int delta = contextTouch.y - y;
if( delta ) {
if( !contextTouch.scroll ) {
int threshold = 32 * renderInterface->GetPixelRatio();
if( abs( delta ) > threshold ) {
contextTouch.scroll = true;
contextTouch.y += ( ( delta < 0 ) ? threshold : -threshold );
delta = contextTouch.y - y;
}
}
if( contextTouch.scroll ) {
Element *focusElement = context->GetFocusElement();
if( !focusElement || ( focusElement->GetTagName() != "keyselect" ) ) {
Element *element;
for( element = context->GetElementAtPoint( contextTouch.origin ); element; element = element->GetParentNode() ) {
if( element->GetTagName() == "scrollbarvertical" ) {
break;
}
int overflow = element->GetProperty< int >( "overflow-y" );
if( ( overflow != Rml::Core::OVERFLOW_AUTO ) && ( overflow != Rml::Core::OVERFLOW_SCROLL ) ) {
continue;
}
int scrollTop = element->GetScrollTop();
if( ( ( delta < 0 ) && ( scrollTop > 0 ) ) ||
( ( delta > 0 ) && ( element->GetScrollHeight() > scrollTop + element->GetClientHeight() ) ) ) {
element->SetScrollTop( element->GetScrollTop() + delta );
break;
}
}
}
contextTouch.y = y;
}
}
if( type == TOUCH_UP ) {
context->ProcessMouseButtonUp( 0, KeyConverter::getModifiers() );
}
}
It would be nice if there was a discussion room for RmlUi so that informal dev questions can be asked.
One platform that is used by a lot of GitHub projects is https://gitter.im/
The following condition in ElementTabSet::ProcessEvent always fails:
if (event.GetCurrentElement() == this && event == Core::EventId::Click)
4397a84 broke configuring with CMake < 3.12 as add_compile_definitions
was added in 3.12.
I'm still using CMake 3.10 as that's the newest version that ships with the Android NDK.
Whilst trying to compile the samples under Linux, this is the error I got:
In file included from /usr/include/X11/Xlib.h:44:0,
from /usr/include/GL/glx.h:30,
from Samples/shell/include/ShellOpenGL.h:44,
from Samples/shell/include/ShellRenderInterfaceOpenGL.h:32,
from Samples/shell/src/ShellRenderInterfaceOpenGL.cpp:29:
Include/Rocket/Core/Tween.h:39:14: error: expected identifier before numeric constant
enum Type { None, Back, Bounce, Circular, Cubic, Elastic, Exponential, Linear, Quadratic, Quartic, Quintic, Sine, Callback, Count };
^
Apparently None
is already defined as a preprocessor macro in the system header file X.h:
/usr/include/X11/X.h:115:0:
#define None 0L /* universal null resource or null atom */
Any idea on the best way to fix this?
I hate defines...
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.