I have a custom GameBoard
which inherits from Gtk::VBox
container and stacking two child Gtk::Grid
containers:
class GameBoard : public Gtk::VBox
{
public:
GameBoard();
virtual ~GameBoard();
private:
Gtk::Grid m_nextDiscArea;
Gtk::Grid m_gameBoardGrid;
};
The GameBoard
constructor is implemented this way:
GameBoard::GameBoard()
{
const int nbRows{6};
const int nbColumns{7};
m_nextDiscArea.set_row_homogeneous(true);
m_nextDiscArea.set_column_homogeneous(true);
for(int col{0}; col < nbColumns; ++col)
{
Disc* noDisc{new Disc};
m_nextDiscArea.attach(*noDisc, col, 0, 1, 1);
}
m_gameBoardGrid.set_row_homogeneous(true);
m_gameBoardGrid.set_column_homogeneous(true);
for(int row{0}; row < nbRows; ++row)
{
for(int col{0}; col < nbColumns; ++col)
{
Disc* noDisc{new Disc};
m_gameBoardGrid.attach(*noDisc, col, row, 1, 1);
}
}
pack_start(m_nextDiscArea);
pack_start(m_gameBoardGrid);
}
The issue I am facing is partially covered in my last post, but that solution is not working for this case. The problem is that when the child widgets of of the two grids are displayed, they have different sizing, and the 6x7 grid has smaller discs, which seems a bit weird:
I have tried playing with set_v/hexpand
, set_v/halign
but nothing seems to work. How can I have the same size for the child widgets of both grids?
For completion, here is the interface of the Disc
class. It simply draws a disc with a color background using Cairo:
class Disc : public Gtk::DrawingArea
{
public:
Disc();
Disc(double p_red, double p_green, double p_blue, double p_alpha);
virtual ~Disc();
protected:
// Signal handlers:
bool on_draw(const Cairo::RefPtr<Cairo::Context>& p_context) override;
private:
double m_red {0.0};
double m_green {0.0};
double m_blue {0.0};
double m_alpha {0.0};
};
A solution to this problem was given to me by theGtkNerd. Instead of using a Gtk::VBox
to pack the two Gtk::Grid
s, a Gtk::Paned
can be used. The GameBoard
class then becomes:
class GameBoard : public Gtk::Paned
{
public:
GameBoard();
virtual ~GameBoard();
private:
Gtk::Grid m_nextDiscArea;
Gtk::Grid m_gameBoardGrid;
};
The constructor can be implemented as:
GameBoard::GameBoard()
{
// The two Paned areas are vertically aligned:
set_orientation(Gtk::Orientation::ORIENTATION_VERTICAL);
const int nbRows{6};
const int nbColumns{7};
m_nextDiscArea.set_row_homogeneous(true);
m_nextDiscArea.set_column_homogeneous(true);
for(int col{0}; col < nbColumns; ++col)
{
Disc* noDisc{new Disc};
noDisc->set_size_request(40, 40); // Give minimal size.
m_nextDiscArea.attach(*noDisc, col, 0, 1, 1);
}
m_gameBoardGrid.set_row_homogeneous(true);
m_gameBoardGrid.set_column_homogeneous(true);
for(int row{0}; row < nbRows; ++row)
{
for(int col{0}; col < nbColumns; ++col)
{
Disc* noDisc{new Disc};
noDisc->set_size_request(40, 40); // Give minimal size.
m_gameBoardGrid.attach(*noDisc, col, row, 1, 1);
}
}
// Layout setup: 'true' for m_nextDiscArea to be expanded
// 'false' to make sure it is not shrinkable (we can make
// it hidden using the paned). Same for m_gameBoardGrid.
pack1(m_nextDiscArea, true, false);
pack2(m_gameBoardGrid, true, false);
}
Here is a screenshot of the result. Resizing keeps all discs in proportion:
I am not exactly sure why this works as expected, and I have found nothing on this in the documentation so far, but it does.