I'm trying to create a custom scrollable text area. I created a DrawingArea
and a ScrollBar
inside a Grid
. I have attached the draw
event of DrawingArea
to this.on_draw
method which simply looks at ScrollBar
's value and moves the Cairo.Context
appropriately before drawing the Pango.Layout
.
The first problem is that this.on_draw
is getting invoked whenever the ScrollBar
is touched even though I have not registered any events with ScrollBar
. How do I prevent this, or check this?
The second problem is that even though this.on_draw
is invoked, the changes made to the Context
is not displayed unless the ScrollBar
value is near 0
or 100
(100 is the upper value of Adjustment). Why is this happening?
I did find out that if I connect
the value_changed
event of ScrollBar
to a method that calls queue_redraw
of DrawingArea
, it would invoke this.on_draw
and display it properly after it. But due to the second problem, I think this.on_draw
is getting invoked too many times unnecessarily. So, what is the "proper" way of accomplishing this?
using Cairo;
using Gdk;
using Gtk;
using Pango;
public class Texter : Gtk.Window {
private Gtk.DrawingArea darea;
private Gtk.Scrollbar scroll;
private string text = "Hello\nWorld!";
public Texter () {
GLib.Object (type: Gtk.WindowType.TOPLEVEL);
Gtk.Grid grid = new Gtk.Grid();
this.add (grid);
var drawing_area = new Gtk.DrawingArea ();
drawing_area.set_size_request (200, 200);
drawing_area.expand = true;
drawing_area.draw.connect (this.on_draw);
grid.attach (drawing_area, 0, 0);
var scrollbar = new Gtk.Scrollbar (Gtk.Orientation.VERTICAL,
new Gtk.Adjustment(0, 0, 100, 0, 0, 1));
grid.attach (scrollbar, 1, 0);
this.darea = drawing_area;
this.scroll = scrollbar;
this.destroy.connect (Gtk.main_quit);
}
private bool on_draw (Gtk.Widget sender, Cairo.Context ctx) {
ctx.set_source_rgb (0.9, 0.9, 0.9);
ctx.paint ();
var y_offset = this.scroll.get_value();
stdout.printf("%f\n", y_offset);
ctx.set_source_rgb (0.25, 0.25, 0.25);
ctx.move_to(0, 100 - y_offset);
var layout = Pango.cairo_create_layout(ctx);
layout.set_font_description(Pango.FontDescription.from_string("Sans 12"));
layout.set_auto_dir(false);
layout.set_text(this.text, this.text.length);
Pango.cairo_show_layout(ctx, layout);
return false;
}
static int main (string[] args) {
Gtk.init (ref args);
var window = new Texter ();
window.show_all ();
Gtk.main ();
return 0;
}
}
Also, please point out any (possibly unrelated) mistake if you find one in the above code.