summaryrefslogtreecommitdiff
path: root/wikipedia/widgets/scaled_image.js
diff options
context:
space:
mode:
Diffstat (limited to 'wikipedia/widgets/scaled_image.js')
-rw-r--r--wikipedia/widgets/scaled_image.js159
1 files changed, 159 insertions, 0 deletions
diff --git a/wikipedia/widgets/scaled_image.js b/wikipedia/widgets/scaled_image.js
new file mode 100644
index 0000000..9808914
--- /dev/null
+++ b/wikipedia/widgets/scaled_image.js
@@ -0,0 +1,159 @@
+const Format = imports.format;
+const GdkPixbuf = imports.gi.GdkPixbuf;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+
+String.prototype.format = Format.format;
+GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE;
+
+const BACKGROUND_CSS_TEMPLATE = "\
+Gjs_ScaledImage {\n\
+ background-image: url('resource://%s');\n\
+ background-size: %s;\n\
+ background-position: %s %s;\n\
+ background-repeat: no-repeat;\n\
+}";
+
+const ScaledImage = new Lang.Class({
+ Name: 'ScaledImage',
+ Extends: Gtk.EventBox,
+ Properties: {
+ 'constraint': GObject.ParamSpec.enum('constraint',
+ 'Constraint direction',
+ 'Orientation in which the size of the image should be constrained',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
+ Gtk.Orientation, Gtk.Orientation.HORIZONTAL),
+ 'resource': GObject.ParamSpec.string('resource',
+ 'Resource path',
+ 'Resource path for the image',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
+ '')
+ },
+
+ _init: function(props) {
+ this._constraint = null;
+ this._resource_path = null;
+ this._pixbuf = null;
+ this._css_provider = null;
+ this.parent(props);
+ },
+
+ // OVERRIDES
+
+ vfunc_get_request_mode: function() {
+ if(this._constraint == Gtk.Orientation.HORIZONTAL)
+ return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;
+ return Gtk.SizeRequestMode.WIDTH_FOR_HEIGHT;
+ },
+
+ vfunc_get_preferred_width_for_height: function(height) {
+ if(!this._pixbuf)
+ return this.parent(height);
+ let source_width = this._pixbuf.width;
+ let source_height = this._pixbuf.height;
+ let width = (height / source_height) * source_width;
+ return [width, width];
+ },
+
+ vfunc_get_preferred_height_for_width: function(width) {
+ if(!this._pixbuf)
+ return this.parent(width);
+ let source_width = this._pixbuf.width;
+ let source_height = this._pixbuf.height;
+ let height = (width / source_width) * source_height;
+ return [height, height];
+ },
+
+ vfunc_size_allocate: function(allocation) {
+ if(this._constraint == Gtk.Orientation.VERTICAL
+ && this.valign != Gtk.Align.FILL) {
+ printerr("ScaledImage Warning: Setting constraint to VERTICAL and\
+ valign to anything but FILL makes no sense");
+ this.valign = Gtk.Align.FILL;
+ }
+ if(this._constraint == Gtk.Orientation.HORIZONTAL
+ && this.halign != Gtk.Align.FILL) {
+ printerr("ScaledImage Warning: Setting constraint to HORIZONTAL and\
+ halign to anything but FILL makes no sense");
+ this.halign = Gtk.Align.FILL;
+ }
+ this.parent(allocation);
+ },
+
+ // PROPERTIES
+
+ get constraint() {
+ return this._constraint;
+ },
+
+ set constraint(value) {
+ this._constraint = value;
+ },
+
+ get resource() {
+ return this._resource_path;
+ },
+
+ set resource(value) {
+ this._resource_path = value;
+ this._pixbuf = GdkPixbuf.Pixbuf.new_from_resource(this._resource_path);
+ this._updateImage();
+ },
+
+ // PRIVATE
+
+ _gtk_align_to_css_align: function(align, orientation) {
+ switch(align) {
+ case Gtk.Align.START:
+ if(orientation == Gtk.Orientation.VERTICAL)
+ return "top";
+ return "left";
+ case Gtk.Align.END:
+ if(orientation == Gtk.Orientation.VERTICAL)
+ return "bottom";
+ return "right";
+ }
+ return "center";
+ },
+
+ _updateImage: function() {
+ if(this._resource_path === null)
+ return;
+
+ let context = this.get_style_context();
+
+ if(this._css_provider !== null)
+ context.remove_provider(this._css_provider);
+
+ let scaling;
+ if(this._constraint == Gtk.Orientation.HORIZONTAL)
+ scaling = "100% auto";
+ else
+ scaling = "auto 100%";
+
+ let css = BACKGROUND_CSS_TEMPLATE.format(this._resource_path, scaling,
+ this._gtk_align_to_css_align(this.valign, Gtk.Orientation.VERTICAL),
+ this._gtk_align_to_css_align(this.halign,
+ Gtk.Orientation.HORIZONTAL));
+ this._css_provider = new Gtk.CssProvider();
+ this._css_provider.load_from_data(css);
+ context.add_provider(this._css_provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_USER);
+ }
+});
+
+// const Gio = imports.gi.Gio;
+// Gtk.init(null);
+// let resource = Gio.Resource.load('data/endless_brazil.gresource');
+// resource._register();
+// let w = new Gtk.Window();
+// let i = new ScaledImage({
+// resource: '/com/endlessm/brazil/category_images/cuisine.jpg',
+// constraint: Gtk.Orientation.HORIZONTAL,
+// valign: Gtk.Align.END,
+// });
+// w.add(i);
+// w.connect('destroy', Gtk.main_quit);
+// w.show_all();
+// Gtk.main();