1/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * 3 * Copyright © 2015 Michael Catanzaro <mcatanzaro@gnome.org> 4 * 5 * This file is part of libgnome-games-support. 6 * 7 * libgnome-games-support is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * libgnome-games-support is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with libgnome-games-support. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21// A container that guarantees that the internal allocated space is a fixed 22// multiple of an integer. This is a fairly literal translation of the LGPLv2+ 23// original by Callum McKenzie, itself based on GtkFrame and GtkAspectFrame. 24 25namespace Games { 26 27public class GridFrame : Gtk.Bin 28{ 29 private int _xpadding = 0; 30 public int xpadding 31 { 32 get { return _xpadding; } 33 34 set 35 { 36 if (value >= 0) 37 { 38 _xpadding = value; 39 queue_resize (); 40 } 41 } 42 } 43 44 private int _ypadding = 0; 45 public int ypadding 46 { 47 get { return _ypadding; } 48 49 set 50 { 51 if (value >= 0) 52 { 53 _ypadding = value; 54 queue_resize (); 55 } 56 } 57 } 58 59 private int _xmult = 1; 60 public int width 61 { 62 get { return _xmult; } 63 64 set 65 { 66 if (value > 0) 67 { 68 _xmult = value; 69 queue_resize (); 70 } 71 } 72 } 73 74 private int _ymult = 1; 75 public int height 76 { 77 get { return _ymult; } 78 79 set 80 { 81 if (value > 0) 82 { 83 _ymult = value; 84 queue_resize (); 85 } 86 } 87 } 88 89 private float _xalign = 0.5f; 90 public float xalign 91 { 92 get { return _xalign; } 93 94 set 95 { 96 _xalign = value.clamp (0.0f, 1.0f); 97 queue_resize (); 98 } 99 } 100 101 private float _yalign = 0.5f; 102 public float yalign 103 { 104 get { return _yalign; } 105 106 set 107 { 108 _yalign = value.clamp (0.0f, 1.0f); 109 queue_resize (); 110 } 111 } 112 113 private Gtk.Allocation old_allocation; 114 115 public GridFrame (int width, int height) 116 { 117 Object (width: width, height: height); 118 } 119 120 public new void @set (int width, int height) 121 { 122 this.width = width; 123 this.height = height; 124 } 125 126 public void set_padding (int xpadding, int ypadding) 127 { 128 this.xpadding = xpadding; 129 this.ypadding = ypadding; 130 } 131 132 public void set_alignment (float xalign, float yalign) 133 { 134 this.xalign = xalign; 135 this.yalign = yalign; 136 } 137 138 public override void size_allocate (Gtk.Allocation allocation) 139 { 140 base.size_allocate (allocation); 141 142 int xsize = int.max (1, (allocation.width - _xpadding) / _xmult); 143 int ysize = int.max (1, (allocation.height - _ypadding) / _ymult); 144 int size = int.min (xsize, ysize); 145 146 Gtk.Allocation child_allocation = { 0, 0, 0, 0 }; 147 child_allocation.width = size * _xmult + _xpadding; 148 child_allocation.height = size * _ymult + _ypadding; 149 child_allocation.x = (int) ((allocation.width - child_allocation.width) * _xalign + allocation.x); 150 child_allocation.y = (int) ((allocation.height - child_allocation.height) * _yalign + allocation.y); 151 152 if (get_mapped () && 153 (child_allocation.x != old_allocation.x || 154 child_allocation.y != old_allocation.y || 155 child_allocation.width != old_allocation.width || 156 child_allocation.height != old_allocation.height)) 157 { 158 get_window ().invalidate_rect (allocation, false); 159 } 160 161 Gtk.Widget child = get_child (); 162 if (child != null && child.get_visible ()) 163 child.size_allocate (child_allocation); 164 165 old_allocation = child_allocation; 166 } 167} 168 169} // namespace Games 170