From c26c84148e5c3bac1b33585f1aeb3164dc8a7220 Mon Sep 17 00:00:00 2001 From: Rory MacQueen Date: Fri, 31 Jan 2014 10:51:52 -0800 Subject: Reorganize category page, add drop shadows The code to build the category page was getting a little cluttered, to the point that it was hard to make changes. Restructured the gtk code to make it a bit cleaner, and added new drop shadows as per design -Rory & Matt [endlessm/eos-sdk#533] --- wikipedia/EndlessWikipedia.js | 2 + wikipedia/Makefile.am.inc | 2 - wikipedia/PrebuiltCategoryPage.js | 141 +++++++++++++-------------------- wikipedia/widgets/BoxWithBg.js | 21 ----- wikipedia/widgets/scaled_image.js | 159 -------------------------------------- 5 files changed, 57 insertions(+), 268 deletions(-) delete mode 100644 wikipedia/widgets/BoxWithBg.js delete mode 100644 wikipedia/widgets/scaled_image.js (limited to 'wikipedia') diff --git a/wikipedia/EndlessWikipedia.js b/wikipedia/EndlessWikipedia.js index cba5c3e..c6e003b 100644 --- a/wikipedia/EndlessWikipedia.js +++ b/wikipedia/EndlessWikipedia.js @@ -17,4 +17,6 @@ const STYLE_CLASS_CATEGORY_CLICKABLE = 'clickable'; const STYLE_CLASS_ARTICLE = 'article'; const STYLE_CLASS_FRONT_PAGE = 'front-page'; const STYLE_CLASS_CATEGORY_PAGE = 'category-page'; +const STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR = 'category-vertical-separator'; +const STYLE_CLASS_CATEGORY_HORIZONTAL_SEPARATOR = 'category-horizontal-separator'; const STYLE_CLASS_ARTICLES_PAGE = 'articles-page'; diff --git a/wikipedia/Makefile.am.inc b/wikipedia/Makefile.am.inc index 00e5984..e4d1ad5 100644 --- a/wikipedia/Makefile.am.inc +++ b/wikipedia/Makefile.am.inc @@ -23,7 +23,6 @@ EXTRA_DIST += wikipedia/config.js.in js_sources = \ wikipedia/ArticleList.js \ wikipedia/widgets/BackButton.js \ - wikipedia/widgets/BoxWithBg.js \ wikipedia/widgets/category_back_button.js \ wikipedia/widgets/composite_button.js \ wikipedia/widgets/FixedSizeTextView.js \ @@ -34,7 +33,6 @@ js_sources = \ wikipedia/PrebuiltWikipediaApplication.js \ wikipedia/widgets/ListTextButton.js \ wikipedia/config.js \ - wikipedia/widgets/scaled_image.js \ wikipedia/utils.js \ wikipedia/WikipediaApplication.js \ wikipedia/models/article_model.js \ diff --git a/wikipedia/PrebuiltCategoryPage.js b/wikipedia/PrebuiltCategoryPage.js index 3211c59..43de97f 100644 --- a/wikipedia/PrebuiltCategoryPage.js +++ b/wikipedia/PrebuiltCategoryPage.js @@ -3,23 +3,11 @@ const GObject = imports.gi.GObject; const Gtk = imports.gi.Gtk; const Lang = imports.lang; -const BoxWithBg = imports.wikipedia.widgets.BoxWithBg; const CategoryBackButton = imports.wikipedia.widgets.category_back_button; const FixedSizeTextView = imports.wikipedia.widgets.FixedSizeTextView; -const ScaledImage = imports.wikipedia.widgets.scaled_image; - -const SHADOW_SEPARATOR_RESOURCE_PATH = "/com/endlessm/wikipedia-domain/assets/submenu_separator_shadow_a.png"; -const INTRO_TITLE_SEPARATOR_URI = "/com/endlessm/wikipedia-domain/assets/introduction_title_separator.png"; -const LEFT_MARGIN_FOR_TEXT = 45; GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; -function _resourceUriToPath(uri) { - if(uri.startsWith('resource://')) - return uri.slice('resource://'.length); - throw new Error('Resource URI did not start with "resource://"'); -} - const PrebuiltCategoryPage = new Lang.Class({ Name: 'PrebuiltCategoryPage', Extends: Gtk.Frame, @@ -46,106 +34,86 @@ const PrebuiltCategoryPage = new Lang.Class({ 'go-back-home':{} }, - _init: function(props) { - this._shaded_box = new BoxWithBg.BoxWithBg({ - name: "category_info", - orientation: Gtk.Orientation.VERTICAL, - vexpand: true - }); - - this._title = null; - this._description = null; - - this._layout_grid = new Gtk.Grid({ - orientation: Gtk.Orientation.HORIZONTAL, - hexpand: true, - halign: Gtk.Align.END - }); - + _get_info_box: function(){ this._title_label = new Gtk.Label({ - name:"category_title", + name: 'category-title', expand: false, halign: Gtk.Align.START, - margin_left: LEFT_MARGIN_FOR_TEXT, xalign: 0.0, // deprecated Gtk.Misc property; necessary because wrap: true, // "wrap" doesn't respect "halign" width_chars: 15, max_width_chars: 18 }); - this._submenu_separator = new ScaledImage.ScaledImage({ - resource: SHADOW_SEPARATOR_RESOURCE_PATH, - constraint: Gtk.Orientation.VERTICAL, - halign: Gtk.Align.END - }); - - this._splash_separator = new ScaledImage.ScaledImage({ - resource: SHADOW_SEPARATOR_RESOURCE_PATH, - constraint: Gtk.Orientation.VERTICAL, - halign: Gtk.Align.END - }); - - this._description_separator = new ScaledImage.ScaledImage({ - resource: INTRO_TITLE_SEPARATOR_URI, - constraint: Gtk.Orientation.HORIZONTAL - }); + let description_separator = new Gtk.Frame(); + description_separator.get_style_context().add_class( + EndlessWikipedia.STYLE_CLASS_CATEGORY_HORIZONTAL_SEPARATOR); this._description_text_view = new FixedSizeTextView.FixedSizeTextView({ - name:"category_description", + name: 'category-description', sensitive: false, editable: false, - cursor_visible: false + cursor_visible: false, + pixels_inside_wrap: 10, + wrap_mode: Gtk.WrapMode.WORD }); - this._description_text_view.set_pixels_inside_wrap(10); - this._description_text_view.set_wrap_mode(Gtk.WrapMode.WORD); - this._description_text_view.right_margin = 20; - - this._description_scrolled_window = new Gtk.ScrolledWindow({ - name: 'category_scrolled_window', + let description_scrolled_window = new Gtk.ScrolledWindow({ + name: 'category-scrolled-window', halign: Gtk.Align.FILL, vexpand: true, - margin_left: LEFT_MARGIN_FOR_TEXT + hscrollbar_policy: Gtk.PolicyType.NEVER, + vscrollbar_policy: Gtk.PolicyType.AUTOMATIC + }); + description_scrolled_window.add(this._description_text_view); + + let vertical_separator = new Gtk.Frame(); + vertical_separator.get_style_context().add_class( + EndlessWikipedia.STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR); + + let grid = new Gtk.Grid(); + grid.attach(this._title_label, 0, 0, 1, 1); + grid.attach(description_separator, 0, 1, 1, 1); + grid.attach(description_scrolled_window, 0, 2, 1, 1); + grid.attach(vertical_separator, 1, 0, 1, 3); + + let frame = new Gtk.Frame({ + name: 'category-info', + vexpand: true }); + frame.add(grid); + return frame; + }, - this._description_scrolled_window.add(this._description_text_view); + _init: function(props) { + this._title = null; + this._description = null; + this._category_provider = new Gtk.CssProvider(); + this.parent(props); - this._description_scrolled_window.set_policy(Gtk.PolicyType.NEVER, - Gtk.PolicyType.AUTOMATIC); + let info_box = this._get_info_box(); - this._back_button = new CategoryBackButton.CategoryBackButton({ - name: "category-back-button", + let back_button = new CategoryBackButton.CategoryBackButton({ + name: 'category-back-button', expand: true, halign: Gtk.Align.START, valign: Gtk.Align.FILL }); - this._back_button.connect('clicked', Lang.bind(this, function() { + back_button.connect('clicked', Lang.bind(this, function() { this.emit('go-back-home'); })); - - this.parent(props); - - this._shaded_box.add(this._title_label); - this._shaded_box.add(this._description_separator); - this._shaded_box.add(this._description_scrolled_window); - - this._layout_grid.add(this._splash_separator); - this._layout_grid.add(this._shaded_box); - this._overlay = new Gtk.Overlay({ - halign: Gtk.Align.END - }); - this._overlay.add(this._layout_grid); - this._overlay.add_overlay(this._submenu_separator); + let vertical_separator = new Gtk.Frame(); + vertical_separator.get_style_context().add_class( + EndlessWikipedia.STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR); - this._outer_most_grid = new Gtk.Grid({ + let grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL }); - this._outer_most_grid.add(this._back_button); - this._outer_most_grid.add(this._overlay); - - this.add(this._outer_most_grid); - this._category_provider = new Gtk.CssProvider(); + grid.add(back_button); + grid.add(vertical_separator); + grid.add(info_box); + this.add(grid); // Add style contexts for CSS let context = this.get_style_context(); @@ -177,10 +145,11 @@ const PrebuiltCategoryPage = new Lang.Class({ }, set image_uri(value){ - this._image_uri = value; - let frame_css = "#category_frame{background-image: url('" + value + "');background-repeat:no-repeat;background-size:cover;}"; - this._category_provider.load_from_data(frame_css); - let context = this.get_style_context(); - context.add_provider(this._category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + if (value) { + let frame_css = "#category_frame{background-image: url('" + value + "');background-repeat:no-repeat;background-size:cover;}"; + this._category_provider.load_from_data(frame_css); + let context = this.get_style_context(); + context.add_provider(this._category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } } }); diff --git a/wikipedia/widgets/BoxWithBg.js b/wikipedia/widgets/BoxWithBg.js deleted file mode 100644 index 6d38bd3..0000000 --- a/wikipedia/widgets/BoxWithBg.js +++ /dev/null @@ -1,21 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const BoxWithBg = new Lang.Class({ - Name: "BoxWithBg", - Extends: Gtk.Box, - - vfunc_draw: function(cr) { - let width = this.get_allocated_width(); - let height = this.get_allocated_height(); - let context = this.get_style_context(); - Gtk.render_background(context, cr, 0, 0, width, height); - Gtk.render_frame(context, cr, 0, 0, width, height); - - let ret = this.parent(cr); - cr.$dispose(); - return ret; - } -}); - diff --git a/wikipedia/widgets/scaled_image.js b/wikipedia/widgets/scaled_image.js deleted file mode 100644 index 9808914..0000000 --- a/wikipedia/widgets/scaled_image.js +++ /dev/null @@ -1,159 +0,0 @@ -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(); -- cgit v1.2.3