WTable is populated the widgets in the layout change size
Added by Pedro Vicente over 1 year ago
I have an application that loads data into a WTable that is initially empty
At start , the widgets are layout as below
But when the WTable is populated the widgets in the layout change form (become much bigger, etc)
Is there a way to avoid this resizing , by code or CSS ?
available at
https://github.com/pedro-vicente/nostr_client_relay
in case you want to give it a try
CSS is
.yellow-box
{
background-color: #FFE4C4;
border: 1px solid black;
margin-top: 1ex;
margin-bottom: 1ex;
}
.table_messages td, .table_messages th
{
border: 1px solid #ddd;
padding: 8px;
}
.table_messages tr:nth-child(even){background-color: #f2f2f2;}
.table_messages tr:hover {background-color: #ddd;}
code is
NostroApplication::NostroApplication(const Wt::WEnvironment& env)
: WApplication(env), m_row(0)
{
useStyleSheet("nostro.css");
root()->setStyleClass("yellow-box");
setTitle("Nostro");
const int width = 500;
auto container = std::make_unique<Wt::WContainerWidget>();
auto box_main = container->setLayout(std::make_unique<Wt::WHBoxLayout>());
auto box_left = box_main->addLayout(std::make_unique<Wt::WVBoxLayout>());
auto box_right = box_main->addLayout(std::make_unique<Wt::WVBoxLayout>());
/////////////////////////////////////////////////////////////////////////////////////////////////////
//input, left
/////////////////////////////////////////////////////////////////////////////////////////////////////
std::string local = "localhost:8080/nostr";
std::string uri = "relay.snort.social";
box_left->addWidget(std::make_unique<Wt::WText>("Relay Uri"));
m_edit_uri = box_left->addWidget(std::make_unique<Wt::WLineEdit>());
m_edit_uri->setText(uri);
m_edit_uri->setWidth(200);
/////////////////////////////////////////////////////////////////////////////////////////////////////
//radion buttons, select EVENT or REQ
/////////////////////////////////////////////////////////////////////////////////////////////////////
m_button_message = std::make_shared<Wt::WButtonGroup>();
Wt::WRadioButton* button;
button = box_left->addWidget(std::make_unique<Wt::WRadioButton>("Event"));
button->setInline(true);
m_button_message->addButton(button);
button = box_left->addWidget(std::make_unique<Wt::WRadioButton>("Request"));
button->setInline(true);
m_button_message->addButton(button);
m_button_message->setSelectedButtonIndex(0);
/////////////////////////////////////////////////////////////////////////////////////////////////////
//EVENT
/////////////////////////////////////////////////////////////////////////////////////////////////////
auto group_event = box_left->addWidget(std::make_unique<Wt::WGroupBox>("Event"));
group_event->addWidget(std::make_unique<Wt::WText>("Public Key"));
group_event->addWidget(std::make_unique<Wt::WBreak>());
m_edit_key = group_event->addWidget(std::make_unique<Wt::WLineEdit>());
m_edit_key->setWidth(width);
group_event->addWidget(std::make_unique<Wt::WBreak>());
group_event->addWidget(std::make_unique<Wt::WText>("Content"));
group_event->addWidget(std::make_unique<Wt::WBreak>());
m_area_content = group_event->addWidget(std::make_unique<Wt::WTextArea>());
m_area_content->setInline(false);
m_area_content->setColumns(80);
m_area_content->resize(Wt::WLength::Auto, 100);
/////////////////////////////////////////////////////////////////////////////////////////////////////
//REQ
/////////////////////////////////////////////////////////////////////////////////////////////////////
auto group_request = box_left->addWidget(std::make_unique<Wt::WGroupBox>("Request"));
group_request->addWidget(std::make_unique<Wt::WText>("Event id"));
group_request->addWidget(std::make_unique<Wt::WBreak>());
m_edit_event_id = group_request->addWidget(std::make_unique<Wt::WLineEdit>());
m_edit_event_id->setWidth(width);
group_request->addWidget(std::make_unique<Wt::WBreak>());
/////////////////////////////////////////////////////////////////////////////////////////////////////
//generated message
/////////////////////////////////////////////////////////////////////////////////////////////////////
box_left->addWidget(std::make_unique<Wt::WText>("Message"));
m_area_input = box_left->addWidget(std::make_unique<Wt::WTextArea>());
m_area_input->setInline(false);
m_area_input->setColumns(100);
m_area_input->resize(Wt::WLength::Auto, 200);
m_area_input->setFocus();
box_left->addWidget(std::make_unique<Wt::WBreak>());
/////////////////////////////////////////////////////////////////////////////////////////////////////
//buttons
/////////////////////////////////////////////////////////////////////////////////////////////////////
auto hbox_buttons = box_left->addLayout(std::make_unique<Wt::WHBoxLayout>());
auto button_gen = hbox_buttons->addWidget(std::make_unique<Wt::WPushButton>("Generate message"));
auto button_send = hbox_buttons->addWidget(std::make_unique<Wt::WPushButton>("Send message"));
/////////////////////////////////////////////////////////////////////////////////////////////////////
//output, right
/////////////////////////////////////////////////////////////////////////////////////////////////////
m_table_messages = box_right->addWidget(std::make_unique<Wt::WTable>());;
m_table_messages->resize(1000, Wt::WLength::Auto);
m_table_messages->setStyleClass("table_messages");
button_send->clicked().connect(this, &NostroApplication::send_message);
button_gen->clicked().connect(this, &NostroApplication::make_message);
root()->addWidget(std::move(container));
}
Replies (3)
RE: WTable is populated the widgets in the layout change size - Added by Pedro Vicente over 1 year ago
The attached 2 images show the effect, before and after
As can be seen the 2 buttons become very large in size (it seems it depends on the table size)
Untitled.png (62.4 KB) Untitled.png | before | ||
Untitled1.png (810 KB) Untitled1.png | after |
RE: WTable is populated the widgets in the layout change size - Added by Pedro Vicente over 1 year ago
After reading this article
https://www.webtoolkit.eu/wt/doc/reference/html/overview.html#containers
found out that layout managers are a bad way to align containers, CSS is the way to go
the div can be aligned as columns
CSS
.row
{
display: grid;
grid-auto-flow: column;
border: 2px outset red;
background-color: lightblue;
}
.col
{
border: solid;
background-color: darkgrey;
}
code
auto container_row = container->addWidget(std::make_unique<Wt::WContainerWidget>());
container_row->setStyleClass("row");
auto group_event = container_row->addWidget(std::make_unique<Wt::WGroupBox>("Event"));
group_event->setStyleClass("col");
Untitled.png (412 KB) Untitled.png | with CSS |
RE: WTable is populated the widgets in the layout change size - Added by Matthias Van Ceulebroeck over 1 year ago
Hi Pedro,
layout managers are not necessarily a bad to to align containers. it really depends on your use case. But to make it customizable, you indeed should add some CSS.
Your specific case happens because you put the table and the input form in the same WHBoxLayout
. So, when the WTable
on the right grows, the content on the left tries to match the height of the WTable
. It will stretch its content to fit the same height as the WTable
.
You can solve this for example by putting a max_height
on box_left
in your CSS.
Alternatively for more complex layouts you can take a look at WTemplate
. This allows you to template your HTML. For example you could have the template content like:
<div>
<div class="left-side">
${event}
${request}
${message}
</div>
<div class="right-side">
${table}
</div>
</div>
.left-side, .right-side {
width: 50%;
}
.left-side {
float:left
}
.right-side {
float:left
}
Then in your CSS code you can do
auto group_request = template->bindNew<Wt::WGroupBox>("event", "Event")
Personally I find that easier to manage complexer layouts, since otherwise you can eventually have way too much layouts/containers to keep a decent overview.
Best,
Matthias