User Guide : Drawing and Device Contexts - mcorino/wxRuby3 GitHub Wiki

In wxRuby the Wx::DC class family provides functionality for drawing to windows, bitmaps, printers etc.
What most of these classes have in common is that actual drawing output is buffered until the time the device context object is destroyed. For this reason the common practice in wxWidgets C++ code would be to create temporary DC objects on the stack and draw on them while they are in scope (for several classes it is even strongly advised to never create them any other way and to never keep objects alive out of scope). When leaving the scope these object would than be automatically destroyed and any buffered output flushed to the final target.
In Ruby this approach is impossible as Ruby is a purely dynamic language and does not support this kind of scope bound life cycles. Any DC object created would have to be dynamically created and due to the properties of the GC driven life cycles could well be kept alive beyond the scope of it's creation. This will not always cause problems but could and does not really have an upside.
To prevent confusion and potential problems wxRuby defines all Wx::DC derived classes to be abstract classes that
cannot be instantiated using new
. Rather all Wx::DC derived classes provide ::draw_on
factory methods to create
temporary dc objects that will be passed on to blocks given and will only exist for the duration of the execution of
the block. This will guarantee proper DC cleanup when leaving it's usage scope.
Note that it is a BAD idea to think about storing the dc reference provided to the block for later access!
A typical usage of a ::draw_on
method would be:
myTestBitmap1x = Wx::Bitmap.new(60, 15, 32)
Wx::MemoryDC.draw_on(myTestBitmap1x) do |mdc|
mdc.set_background(Wx::WHITE_BRUSH)
mdc.clear
mdc.set_pen(Wx::BLACK_PEN)
mdc.set_brush(Wx::WHITE_BRUSH)
mdc.draw_rectangle(0, 0, 60, 15)
mdc.draw_line(0, 0, 59, 14)
mdc.set_text_foreground(Wx::BLACK)
mdc.draw_text("x1", 0, 0)
end
The Wx::PaintDC and Wx::AutoBufferedPaintDC classes provide ::draw_on
methods just like all other DC classes but
this is mostly to be consistent.
In this case it is recommended to instead use the Wx::Window#paint or Wx::Window#paint_buffered methods as these
provide some optimizations with regard to automatically detecting if the methods are called inside Wx::EVT_PAINT
handlers (which should normally be the case) or not.
So the typical way to do buffered painting inside a windows Wx::EVT_PAINT
handler would be something like:
def on_paint(_event)
self.paint_buffered do |dc|
# ... do some drawing ...
end
end