Glade を使って、gtk3 で図形を描画します。(Gtk::DrawingAreaCairo::Contex
図形を描画するには、まず描画領域(DrawingArea)を配置し、その中で画像描画ライブラリcairo を使って図形を描画します。

参考)
→・GTK+ CSS - GTK+ 3 Reference Manual

→・PyCairo tutorial  - ZetCode


1.描画領域(DrawingArea)の配置
Glade を起動し、ウィンドウ(GtkWindow)を作り、位置指定(GtkFixed)コンテナなどを置き、その上に描画領域をドラッグします。 
(Glade の左列>「コントロールと表示」>「描画領域」にあります)

○大きさ
 右下の「描画領域のプロパティ」>「共通」;
 ・要求する幅
 ・要求する高さ

○位置
 右下の「描画領域のプロパティ」>「パッキング」;
 ・X位置
 ・Y位置

○シグナル
 右下の「描画領域のプロパティ」>「シグナル」>「draw」
 を選びます。



2.描画する(Cairo::Context を使う)
(※ 注意;
macOS の Retina Display や 他OS の 高解像度(HiDPI)ディスプレイには、大元の gtk+3(version 3.22.26)ライブラリがまだ対応していません。そのため、macOS の Retina Display では、ウィンドウ自体が2倍の大きさに描画されてしまいます。
→・HiDPI/Retina display support and gtk3-port branch? (2014) — GIMP Development — gimpusers.com )

(2018.11.1 追記;
Ruby/GTK3 がバージョンアップして、高解像度ディスプレイでも2倍にならずに描画するようになりました。gtk3 3.3.0)

Ruby側のプログラムで、描画ライブラリの Cairo::Context を使って描画します。
なお、描画領域(DrawingArea)で設定した drawシグナルは、自動的に第2引数に Cairo::Contex を生成してくれます(第1引数は DrawingArea自身)。
そのため、改めて Cairo::Contex を生成する必要はありません。

描画するには、drawシグナルを受け取るメソッドの中で以下に挙げた描画処理を記述します。

 色の設定をする
 ・red, green, blue (, alpha);0-1.0

 描画領域全体の背景色を塗る
 
○Cairo::Context#set_line_width(width)
 線の太さを設定する(1.0 が標準)

 座標の拡大率を設定する(1.0で等倍)

 点を打つ座標を指定する

 前の座標から(x, y)までの直線を引く(経路を)指定をする

 指定された経路を線で描く

○Cairo::Context#rectangle(x1, y1, x2, y2)
 四角を描く

 円弧を描く
 ・中心;x, y
 ・半径;radius
 ・描画開始点;starting_point(角度;ラジアン 0 〜 2*Math::PI)
 ・描画終了点;ending_point

 図形内部に色を塗る

○Cairo::Context#destroy
 Cairo::Context を廃棄します
(描画処理の最後に使うことがあるようですが、エラーが出なければ特に使う必要はないようです)


設定例;
○ウィンドウ(GtkWindow)
 ・ID:window_1 
 ・デフォルトの幅:400
 ・デフォルトの高さ:300
 ・シグナル:destroy,ハンドラーの名前:gtk_main_quit

○位置指定(GtkFixed)
 デフォルトのまま

○描画領域(DrawingArea)
 ・ID:drawingarea1
 ・パッキング:X位置: 20,Y位置: 20
 ・共通:要求する幅: 290,要求する高さ: 160
 ・シグナル:draw,ハンドラーの名前:on_drawingarea1_draw


glade_drawing_1_glade


(license; public domain)
・glade_drawing_1.ui
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window_1">
    <property name="can_focus">False</property>
    <property name="default_width">400</property>
    <property name="default_height">300</property>
    <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
    <child>
      <object class="GtkFixed">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkDrawingArea" id="drawingarea1">
            <property name="width_request">290</property>
            <property name="height_request">160</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <signal name="draw" handler="on_drawingarea1_draw" swapped="no"/>
          </object>
          <packing>
            <property name="x">20</property>
            <property name="y">20</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

・glade_drawing_1.rb
require 'gtk3'

builder = Gtk::Builder.new
builder.add_from_file("glade_drawing_1.ui")

win = builder.get_object("window_1")

def gtk_main_quit
  Gtk.main_quit
end

def on_drawingarea1_draw(widget, cairo_contex) #drawシグナルは、第2引数にCairo::Contexが入る
  cairo_contex.set_source_rgb(0, 1.0, 1.0)   # RGB; 0-1.0
  cairo_contex.paint

  cairo_contex.set_source_rgb(1.0, 0, 0)
  cairo_contex.set_line_width(1)
  cairo_contex.move_to(  0,  10)
  cairo_contex.line_to( 25,  10)
  cairo_contex.line_to( 37,   0)
  cairo_contex.line_to( 49,  10)
  cairo_contex.line_to(289,  10)
  cairo_contex.line_to(289, 159)
  cairo_contex.line_to(  0, 159)
  cairo_contex.line_to(  0,  10)
  cairo_contex.stroke

  cairo_contex.set_source_rgb(1.0, 0, 1.0)
  cairo_contex.arc(20, 40, 10, 0, 2 * Math::PI)
  cairo_contex.fill
end

builder.connect_signals {|handler| method(handler)}
win.show_all
Gtk.main

glade_drawing_1



※ macOS で Retina Display だと、2倍に拡大表示されて一部しか表示されません。
(2018.11.1 追記;
 gtk3 3.3.0 で正常に表示するようになりました)
 
glade_drawing_1_retina


ウィンドウを広げると、2倍の大きさに表示されているのが分かります。
glade_drawing_1_retina_2



3.応用
描画領域(DrawingArea)の上にテキストビュー(TextView)を重ねて表示してみます。

設定例;
○ウィンドウ(GtkWindow)
 ・ID:window_1 
 ・デフォルトの幅:400
 ・デフォルトの高さ:300
 ・シグナル:destroy,ハンドラーの名前:gtk_main_quit

○位置指定(GtkFixed)
 デフォルトのまま

○描画領域(DrawingArea)
 ・ID:drawingarea1
 ・パッキング:X位置: 20,Y位置: 20
 ・共通:要求する幅: 290,要求する高さ: 160
 ・シグナル:draw,ハンドラーの名前:on_drawingarea1_draw

○テキストビュー(GtkTextView)
 ・ID:textview1
 ・パッキング:X位置: 80,Y位置: 80
 ・共通:要求する幅: 150,要求する高さ: 50
 ・バッファー:textbuffer
 
○テキストバッファー(GtkTextBuffer)
 ・ID:textbuffer1
 ・ラベル:Hello World!


glade_drawing_2_glade


・glade_drawing_2.ui
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkTextBuffer" id="textbuffer1">
    <property name="text">Hello World!</property>
  </object>
  <object class="GtkWindow" id="window_1">
    <property name="can_focus">False</property>
    <property name="default_width">400</property>
    <property name="default_height">300</property>
    <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
    <child>
      <object class="GtkFixed">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkDrawingArea" id="drawingarea1">
            <property name="width_request">290</property>
            <property name="height_request">160</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <signal name="draw" handler="on_drawingarea1_draw" swapped="no"/>
          </object>
          <packing>
            <property name="x">20</property>
            <property name="y">20</property>
          </packing>
        </child>
        <child>
          <object class="GtkTextView" id="textview1">
            <property name="width_request">150</property>
            <property name="height_request">50</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="buffer">textbuffer1</property>
          </object>
          <packing>
            <property name="x">80</property>
            <property name="y">80</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

・glade_drawing_2.rb
require 'gtk3'

builder = Gtk::Builder.new
builder.add_from_file("glade_drawing_2.ui")

win = builder.get_object("window_1")

def gtk_main_quit
  Gtk.main_quit
end

def on_drawingarea1_draw(widget, cairo_contex) #drawシグナルは、第2引数にCairo::Contexが入る
  cairo_contex.set_source_rgb(0, 1.0, 1.0)   # RGB; 0-1.0
  cairo_contex.paint

  cairo_contex.set_source_rgb(1.0, 0, 0)
  cairo_contex.set_line_width(1)
  cairo_contex.move_to(  0,  10)
  cairo_contex.line_to( 25,  10)
  cairo_contex.line_to( 37,   0)
  cairo_contex.line_to( 49,  10)
  cairo_contex.line_to(289,  10)
  cairo_contex.line_to(289, 159)
  cairo_contex.line_to(  0, 159)
  cairo_contex.line_to(  0,  10)
  cairo_contex.stroke

  cairo_contex.set_source_rgb(1.0, 0, 1.0)
  cairo_contex.arc(20, 40, 10, 0, 2 * Math::PI)
  cairo_contex.fill
end

text_area = builder.get_object("textview1")
css_provider = Gtk::CssProvider.new
css_provider.load(data:
"
text {
  background-color: yellow;
}
")
text_area.style_context.add_provider(css_provider, Gtk::StyleProvider::PRIORITY_USER)


builder.connect_signals {|handler| method(handler)}
win.show_all
Gtk.main

glade_drawing_2