2

I want to draw some frames, one by one in a Gtk::DrawingArea. At the beginning of application, I need to get the size of DrawingArea, to allocate a RGB buffer, hewever, DrawingArea::get_width() and DrawingArea::get_height() return 1.

My code is based on https://developer.gnome.org/gtkmm-tutorial/stable/sec-drawing-clock-example.html.en with an extra line to get the size of DrawingArea:

#include "clock.h"
#include <gtkmm/application.h>
#include <gtkmm/window.h>

int main(int argc, char** argv)
{
   auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

   Gtk::Window win;
   win.set_title("Cairomm Clock");

   Clock c;
   win.add(c);
   c.show();

   int w = c.get_width();
   // w is 1;

   return app->run(win);
}

How can I get the size of DrawingArea before actually drawing into it?

Null
  • 349
  • 2
  • 12
  • 1
    Are you looking for the [signal_configure_event()](https://developer.gnome.org/gtkmm/stable/classGtk_1_1Widget.html#a62cc55f24729244391085a357a34535f)? Layout negotiation in GTK+ isn't simple. The actual size of a widget may not be known until it's drawn. However, AFAIK the configure event is sent before a corresponding draw event if necessary. Btw. you still could retrieve the actual size of your widget in the [draw event](https://developer.gnome.org/gtkmm/stable/classGtk_1_1Widget.html#ab0a7d34fe7ae7a83fdb1e1ddd223e8f4) itself and update your contents respectively before you draw it. – Scheff's Cat Oct 11 '20 at 08:22
  • 1
    Concerning the latter, that's what they do in the example code with `Gtk::Allocation allocation = get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height();`. Concerning _to allocate a RGB buffer_: You could this do "on demand". Just check in the draw event whether it's already done. If not, do it. So, it will be done in the first call only. Though, you might do it in the configure event instead (without checking "if it's already done"). So, it will consider size changes as well. – Scheff's Cat Oct 11 '20 at 08:26
  • @Scheff I consider signal_configure_event() as my answer, do you mind posting your comment as answer? – Null Oct 12 '20 at 04:27
  • I was an enthusiastic gtkmm developer until the Windows support became unreliable, and we decided to switch to Qt. I didn't forget all but my attention comes mainly from sentimental memories. ;-) If you got your sample running as intended you may post it as [self-answer](https://stackoverflow.com/help/self-answer) (with [mcve]). – Scheff's Cat Oct 12 '20 at 05:53

2 Answers2

2

I was able to trace size changes based on Scheff's comments:

#include "clock.h"
#include <gtkmm/application.h>
#include <gtkmm/window.h>

int width_ = 0;
int height_ = 0;
bool resized_ = false;

void check_size()
{
   if (resized_)
   {
      resized_ = false;
      // Apply size changes to resources using width_ and height_
   }
}

int main(int argc, char** argv)
{
   auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

   Gtk::Window win;
   win.set_title("Cairomm Clock");

   Clock c;
   c.signal_configure_event().connect([&](GdkEventConfigure* event)
   {
      width_ = event->width;
      height_ = event->height;
      resized_ = true;
      return true;
   });
   win.add(c);
   c.show();

   return app->run(win);
}

Where to call check_size function is dependent on the design of the application. In my case I call it right before c.queue_draw().

BobMorane
  • 3,870
  • 3
  • 20
  • 42
Null
  • 349
  • 2
  • 12
  • 1
    @BobMorane There is a time limit I need to wait before being able to mark my answer as solved. It started with 13 hours, now 6 hours are left. Thanks for edit. – Null Oct 12 '20 at 23:00
0

I solved in my playground about cairo and gtk in vala adding a signal connected to a custom on_window_configure_event

meter.vala

tudo75
  • 97
  • 1
  • 2