2297695fd2
Make the custom widget a generic class, and add and use a derived class. Also add a second instance of the custom widget, to better test the interface properties support.
210 lines
4.7 KiB
C#
210 lines
4.7 KiB
C#
using GLib;
|
|
using Gtk;
|
|
using System;
|
|
|
|
class CustomScrollableWidgetTest {
|
|
public static int Main (string[] args)
|
|
{
|
|
Gtk.Application.Init ();
|
|
Window win = new Window ("Custom Scrollable Widget Test");
|
|
win.DeleteEvent += new DeleteEventHandler (OnQuit);
|
|
|
|
VPaned paned = new VPaned ();
|
|
|
|
ScrolledWindow scroll = new ScrolledWindow ();
|
|
scroll.HscrollbarPolicy = PolicyType.Automatic;
|
|
scroll.VscrollbarPolicy = PolicyType.Automatic;
|
|
|
|
var cw = new DerivedScrollableWidget<string> ("This one label that is repeated");
|
|
scroll.Add (cw);
|
|
paned.Pack1 (scroll, true, false);
|
|
|
|
scroll = new ScrolledWindow ();
|
|
scroll.HscrollbarPolicy = PolicyType.Automatic;
|
|
scroll.VscrollbarPolicy = PolicyType.Automatic;
|
|
|
|
var cw2 = new DerivedScrollableWidget<object> ("Another label that is repeated");
|
|
scroll.Add (cw2);
|
|
paned.Pack2 (scroll, true, false);
|
|
|
|
win.Add (paned);
|
|
win.DefaultWidth = 200;
|
|
win.DefaultHeight = 200;
|
|
win.ShowAll ();
|
|
Gtk.Application.Run ();
|
|
return 0;
|
|
}
|
|
|
|
static void OnQuit (object sender, DeleteEventArgs args)
|
|
{
|
|
Gtk.Application.Quit ();
|
|
}
|
|
}
|
|
|
|
abstract class CustomBase : Widget
|
|
{
|
|
public CustomBase () : base ()
|
|
{ }
|
|
}
|
|
|
|
class DerivedScrollableWidget<T> : CustomScrollableWidget<T>
|
|
{
|
|
public DerivedScrollableWidget (string label) : base (label)
|
|
{ }
|
|
}
|
|
|
|
class CustomScrollableWidget<T> : CustomBase, ScrollableImplementor {
|
|
private int num_rows = 20;
|
|
private string label;
|
|
private Pango.Layout layout;
|
|
|
|
public CustomScrollableWidget (string custom_label) : base ()
|
|
{
|
|
label = custom_label;
|
|
layout = null;
|
|
|
|
HasWindow = false;
|
|
}
|
|
|
|
private Pango.Layout Layout {
|
|
get {
|
|
if (layout == null)
|
|
layout = CreatePangoLayout (label);
|
|
return layout;
|
|
}
|
|
}
|
|
|
|
private Gdk.Rectangle ContentArea {
|
|
get {
|
|
Gdk.Rectangle area;
|
|
area.X = Allocation.X;
|
|
area.Y = Allocation.Y;
|
|
|
|
int layoutWidth, layoutHeight;
|
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
|
area.Width = layoutWidth;
|
|
area.Height = layoutHeight * num_rows;
|
|
|
|
return area;
|
|
}
|
|
}
|
|
|
|
protected override bool OnDrawn (Cairo.Context cr)
|
|
{
|
|
int layout_x = - HadjustmentValue;
|
|
int layout_y = - VadjustmentValue;
|
|
|
|
int layoutWidth, layoutHeight;
|
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
|
|
|
for (int i = 0; i < num_rows; i++) {
|
|
Layout.SetText (String.Format ("{0} {1}", label, i));
|
|
StyleContext.RenderLayout (cr, layout_x, layout_y, Layout);
|
|
layout_y += layoutHeight;
|
|
}
|
|
|
|
return base.OnDrawn (cr);
|
|
}
|
|
|
|
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
|
|
{
|
|
base.OnSizeAllocated (allocation);
|
|
|
|
if (hadjustment != null) {
|
|
hadjustment.PageSize = allocation.Width;
|
|
hadjustment.PageIncrement = allocation.Width;
|
|
UpdateAdjustments ();
|
|
}
|
|
|
|
if (vadjustment != null) {
|
|
vadjustment.PageSize = allocation.Height;
|
|
vadjustment.PageIncrement = allocation.Height;
|
|
UpdateAdjustments ();
|
|
}
|
|
}
|
|
|
|
|
|
private Adjustment hadjustment;
|
|
public Adjustment Hadjustment {
|
|
get { return hadjustment; }
|
|
set {
|
|
if (value == hadjustment) {
|
|
return;
|
|
}
|
|
hadjustment = value;
|
|
if (hadjustment == null) {
|
|
return;
|
|
}
|
|
hadjustment.ValueChanged += OnHadjustmentChanged;
|
|
UpdateAdjustments ();
|
|
}
|
|
}
|
|
|
|
private Adjustment vadjustment;
|
|
public Adjustment Vadjustment {
|
|
get { return vadjustment; }
|
|
set {
|
|
if (value == vadjustment) {
|
|
return;
|
|
}
|
|
vadjustment = value;
|
|
if (vadjustment == null) {
|
|
return;
|
|
}
|
|
vadjustment.ValueChanged += OnVadjustmentChanged;
|
|
UpdateAdjustments ();
|
|
}
|
|
}
|
|
|
|
private int HadjustmentValue {
|
|
get { return hadjustment == null ? 0 : (int)hadjustment.Value; }
|
|
}
|
|
|
|
private int VadjustmentValue {
|
|
get { return vadjustment == null ? 0 : (int)vadjustment.Value; }
|
|
}
|
|
|
|
public Gtk.ScrollablePolicy HscrollPolicy {
|
|
get; set;
|
|
}
|
|
|
|
public Gtk.ScrollablePolicy VscrollPolicy {
|
|
get; set;
|
|
}
|
|
|
|
private void UpdateAdjustments ()
|
|
{
|
|
int layoutWidth, layoutHeight;
|
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
|
|
|
if (hadjustment != null) {
|
|
hadjustment.Upper = ContentArea.Width;
|
|
hadjustment.StepIncrement = 10.0;
|
|
if (hadjustment.Value + hadjustment.PageSize > hadjustment.Upper) {
|
|
hadjustment.Value = hadjustment.Upper - hadjustment.PageSize;
|
|
}
|
|
hadjustment.Change ();
|
|
}
|
|
|
|
if (vadjustment != null) {
|
|
vadjustment.Upper = ContentArea.Height;
|
|
vadjustment.StepIncrement = layoutHeight;
|
|
if (vadjustment.Value + vadjustment.PageSize > vadjustment.Upper) {
|
|
vadjustment.Value = vadjustment.Upper - vadjustment.PageSize;
|
|
}
|
|
vadjustment.Change ();
|
|
}
|
|
}
|
|
|
|
private void OnHadjustmentChanged (object o, EventArgs args)
|
|
{
|
|
UpdateAdjustments ();
|
|
QueueDraw ();
|
|
}
|
|
|
|
private void OnVadjustmentChanged (object o, EventArgs args)
|
|
{
|
|
UpdateAdjustments ();
|
|
QueueDraw ();
|
|
}
|
|
}
|