Content aware sizing and Bootstrap 5 enablement
Added by Mark Travis about 2 months ago
Hopefully, I got the title correct.
I'm running into some usability issues with my app in terms of resizing WCartesianCharts and WTableViews, particularly on the width dimension.
I can't use "percentage" of screen width for these objects because they must be sized in pixels.
I've gotten a very nice app appearance using WTemplates in combination with a Bootstrap 5 theme. I'm very happy with it for the most part.
But if the user has a browser window smaller than 1024 or bigger than 1024, the pixel-perfect layout starts falling apart. I haven't even looked at the iPad web presentation, yet.
I have zero problems with re-sizing and re-flowing every Wt object except for these two.
Are there plans to make these two Wt objects more Bootstrap 5 friendly? I guess I could write an object to spit out "table,thead,tbody,td,tr,th" objects to a WTemplate similar to what pdfrender does. Not my first choice.
Here's what I'm talking about. The first image is "pixel-perfect". The second image shows what happens if I shrink the window. I have similar issues when I go wider.
Pixel-perfect at a width of 1024¶
overflow to the right of the page on WCartesianCharts and WTableViews¶
Replies (4)
RE: Content aware sizing and Bootstrap 5 enablement - Added by Matthias Van Ceulebroeck 25 days ago
Hello Mark,
we are aware that some widgets (like WTableView, and a lot of charts) are not really responsive. They are correctly sized when a layout manager is wrapped around them though.
Maybe you can try to bind a WContainerWidget
with a setLayout(std::make_unique<WFitLayout>())
, to which you bind the above WTableView
and charts (see documentation)?
Best,
Matthias
RE: Content aware sizing and Bootstrap 5 enablement - Added by Mark Travis 24 days ago
Interesting. ok, after reviewing these pages long ago, I was under the impression one needed to choose between WTemplate/CSS or the use of layout managers.
https://www.webtoolkit.eu/widgets/layout/layout-managers
https://www.webtoolkit.eu/wt/doc/reference/html/overview.html#layout
Also, in this thread, Roel states that:
"You can't combine a WLayout with CSS-based sizing. The layout will always counteract any CSS styling. Wt will not interfere with the size of your widgets if you don't use a layout, but add everything to the WContainerWidget directly instead."
https://redmine.emweb.be/boards/1/topics/13148?r=13151#message-13151
I may be missing a finer point on this? Can Bootstrap 5, CSS, and WTemplate mix with WLayout?
I was one of the first (I think) to fully adopt the WBootstrap5Theme(), so I may have avoided problem areas from the early days that have now been fixed. (Or maybe I'm just a little better at implementation now. :) )
RE: Content aware sizing and Bootstrap 5 enablement - Added by Matthias Van Ceulebroeck 24 days ago
Hey Mark,
while it's true that in most cases layout managers are prone to their chain being interrupted (as WTemplate
s tend to do), the WFitLayout
is a little bit of an exception.
This can be used without wrapping layout managers. This manager will simply scale its content to its available size.
I also do believe that simply not setting the size of the widgets should automatically make it fit to the amount of space it has available? However, for a chart that may lead to the chart not being shown.
Then I do believe that wrapping it in a WFitLayout
is sufficient. See my test below:
#include <Wt/Chart/WCartesianChart.h>
#include <Wt/Chart/WStandardChartProxyModel.h>
#include <Wt/WApplication.h>
#include <Wt/WBootstrap5Theme.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WFitLayout.h>
#include <Wt/WStandardItemModel.h>
#include <Wt/WStandardItem.h>
#include <Wt/WTableView.h>
#include <Wt/WTemplate.h>
class LayoutApplication : public Wt::WApplication
{
public:
LayoutApplication(const Wt::WEnvironment& env)
: Wt::WApplication(env)
{
setTheme(std::make_unique<Wt::WBootstrap5Theme>());
std::string content = "<div class='container-fluid bg-secondary'>"
" <div class='container'>"
" <div class='card p-3'>${table}</div>"
" <div class='card p-3'>${chart}</div>"
" </div>"
"</div>";
auto templ = root()->addNew<Wt::WTemplate>(content);
auto model = createModel();
auto container = std::make_unique<Wt::WContainerWidget>();
auto lay = container->setLayout(std::make_unique<Wt::WFitLayout>());
lay->addWidget(createTable(model));
templ->bindWidget("table", std::move(container));
container = std::make_unique<Wt::WContainerWidget>();
lay = container->setLayout(std::make_unique<Wt::WFitLayout>());
lay->addWidget(createChart(std::make_shared<Wt::Chart::WStandardChartProxyModel>(model)));
templ->bindWidget("chart", std::move(container));
}
private:
std::shared_ptr<Wt::WStandardItemModel> createModel()
{
int rows = 3;
int cols = 10;
auto model = std::make_shared<Wt::WStandardItemModel>(rows, cols);
for (int col = 1; col < cols; ++col) {
model->setHeaderData(col, Wt::Orientation::Horizontal, "Col: " + std::to_string(col));
}
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
auto item = std::make_unique<Wt::WStandardItem>(std::to_string(row) + std::to_string(col));
model->setItem(row, col, std::move(item));
}
}
return model;
}
std::unique_ptr<Wt::WTableView> createTable(const std::shared_ptr<Wt::WStandardItemModel>& model)
{
auto table = std::make_unique<Wt::WTableView>();
table->setModel(model);
table->setWidth(1400);
return table;
}
std::unique_ptr<Wt::Chart::WCartesianChart> createChart(const std::shared_ptr<Wt::Chart::WStandardChartProxyModel>& model)
{
auto chart = std::make_unique<Wt::Chart::WCartesianChart>();
chart->setModel(model);
chart->setXSeriesColumn(0);
chart->resize(800, 400);
for (int i = 0; i < 3; ++i) {
auto s = std::make_unique<Wt::Chart::WDataSeries>(i, Wt::Chart::SeriesType::Line);
chart->addSeries(std::move(s));
}
return chart;
}
};
int main(int argc, char **argv)
{
return Wt::WRun(argc, argv, [](const Wt::WEnvironment &env) {
return std::make_unique<LayoutApplication>(env);
});
}
RE: Content aware sizing and Bootstrap 5 enablement - Added by Mark Travis 24 days ago
Thanks! I will definitely give this a try.