mirror of
				https://github.com/Ryujinx/GtkSharp.git
				synced 2025-11-04 13:24:48 +00:00 
			
		
		
		
	Upper values having higher values than PageSize or PageIncrement cause rendering issues. This commit is a small adaptation of a fix from one of the edge cases pointed out in this commit in hyena: https://git.gnome.org/browse/hyena/commit/?h=gtk3&id=0745bfb75809886925dfa49a57c79e5f71565d08
		
			
				
	
	
		
			218 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			4.9 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, IScrollableImplementor {
 | 
						|
	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;
 | 
						|
			}
 | 
						|
			if (hadjustment.Upper > 0 && hadjustment.Upper < hadjustment.PageSize) {
 | 
						|
				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;
 | 
						|
			}
 | 
						|
			if (vadjustment.Upper > 0 && vadjustment.Upper < vadjustment.PageSize) {
 | 
						|
				vadjustment.Upper = vadjustment.PageSize;
 | 
						|
			}
 | 
						|
			vadjustment.Change ();
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	private void OnHadjustmentChanged (object o, EventArgs args)
 | 
						|
	{
 | 
						|
		UpdateAdjustments ();
 | 
						|
		QueueDraw ();
 | 
						|
	}
 | 
						|
	
 | 
						|
	private void OnVadjustmentChanged (object o, EventArgs args)
 | 
						|
	{
 | 
						|
		UpdateAdjustments ();
 | 
						|
		QueueDraw ();
 | 
						|
	}
 | 
						|
}
 |