diff options
Diffstat (limited to 'wikipedia/widgets')
-rw-r--r-- | wikipedia/widgets/category_button.js | 88 | ||||
-rw-r--r-- | wikipedia/widgets/category_layout_manager.js | 41 | ||||
-rw-r--r-- | wikipedia/widgets/category_selector_view.js | 12 |
3 files changed, 105 insertions, 36 deletions
diff --git a/wikipedia/widgets/category_button.js b/wikipedia/widgets/category_button.js index 77812f1..4edac83 100644 --- a/wikipedia/widgets/category_button.js +++ b/wikipedia/widgets/category_button.js @@ -12,6 +12,7 @@ const CATEGORY_BUTTON_RIGHT_MARGIN = 20; // pixels const CATEGORY_BUTTON_BOTTOM_MARGIN = 20; // pixels const CATEGORY_LABEL_BENTON_SANS_CORRECTION = 0; // pixels const _HOVER_ARROW_URI = '/com/endlessm/wikipedia-domain/assets/category_hover_arrow.png'; +const MAIN_CATEGORY_SCREEN_WIDTH_PERCENTAGE = 0.37; GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; @@ -31,7 +32,21 @@ const CategoryButton = new Lang.Class({ 'Category title', 'Display name for the category', GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - '') + ''), + + // Boolean whether this button is clickable + 'clickable-category': GObject.ParamSpec.boolean('clickable-category', + 'Clickable Category', + 'Flag whether this category button should be clickable', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + true), + + // Boolean whether this button is the main category + 'is-main-category': GObject.ParamSpec.boolean('is-main-category', + 'Is Main Category', + 'Flag whether this category button is the main category', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + false) }, Signals: { 'clicked': {} @@ -41,6 +56,8 @@ const CategoryButton = new Lang.Class({ // Get ready for property construction this._image_uri = null; this._category_title = null; + this._clickable_category = null; + this._is_main_category = null; this._overlay = new Gtk.Overlay(); this._eventbox = new Gtk.EventBox({ @@ -65,19 +82,6 @@ const CategoryButton = new Lang.Class({ no_show_all: true }); - this._eventbox.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK | - Gdk.EventMask.LEAVE_NOTIFY_MASK); - this._eventbox.connect('enter-notify-event', - Lang.bind(this, function(widget, event) { - this._eventbox.set_state_flags(Gtk.StateFlags.PRELIGHT, false); - this._arrow.show(); - })); - this._eventbox.connect('leave-notify-event', - Lang.bind(this, function(widget, event) { - this._eventbox.unset_state_flags(Gtk.StateFlags.PRELIGHT); - this._arrow.hide(); - })); - let context = this._label.get_style_context(); context.add_class(EndlessWikipedia.STYLE_CLASS_TITLE); context.add_class(EndlessWikipedia.STYLE_CLASS_CATEGORY); @@ -129,13 +133,63 @@ const CategoryButton = new Lang.Class({ this._label.set_text(value.toUpperCase()); }, + get clickable_category() { + return this._clickable_category; + }, + + set clickable_category(value) { + this._clickable_category = value; + if(this._clickable_category) { + //Hover events/effects only trigger if the button is clickable. + this._eventbox.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK | + Gdk.EventMask.LEAVE_NOTIFY_MASK); + this._eventbox.connect('enter-notify-event', + Lang.bind(this, function(widget, event) { + this._eventbox.set_state_flags(Gtk.StateFlags.PRELIGHT, false); + this._arrow.show(); + })); + this._eventbox.connect('leave-notify-event', + Lang.bind(this, function(widget, event) { + this._eventbox.unset_state_flags(Gtk.StateFlags.PRELIGHT); + this._arrow.hide(); + })); + } + }, + + get is_main_category() { + return this._is_main_category; + }, + + set is_main_category(value) { + this._is_main_category = value; + if(this._is_main_category) { + let context = this._label.get_style_context(); + context.add_class(EndlessWikipedia.STYLE_CLASS_MAIN); + this._label.margin_bottom = 0; + } + }, + // OVERRIDES + vfunc_get_preferred_width: function() { + if(this._is_main_category) { + let toplevel = this.get_toplevel(); + if(toplevel == null) + return this.parent(); + let width = toplevel.get_allocated_width() * MAIN_CATEGORY_SCREEN_WIDTH_PERCENTAGE; + return [width, width]; + } else { + return this.parent(); + } + }, + vfunc_size_allocate: function(allocation) { this.parent(allocation); - let new_pixbuf = Utils.load_pixbuf_cover(Utils.resourceUriToPath(this._image_uri), - allocation.width, allocation.height); - this._image.set_from_pixbuf(new_pixbuf); + if(this._image_uri !== "" && this._image_uri != null) { + let new_pixbuf = Utils.load_pixbuf_cover(Utils.resourceUriToPath(this._image_uri), + allocation.width, allocation.height); + this._image.set_from_pixbuf(new_pixbuf); + } }, // HANDLERS diff --git a/wikipedia/widgets/category_layout_manager.js b/wikipedia/widgets/category_layout_manager.js index a7be3bb..d49661c 100644 --- a/wikipedia/widgets/category_layout_manager.js +++ b/wikipedia/widgets/category_layout_manager.js @@ -7,11 +7,13 @@ const CategoryLayoutManager = new Lang.Class({ _init: function(props) { props = props || {}; - props.column_homogeneous = true; props.row_homogeneous = true; + //we don't make the columns homogenous because the 0th column + //needs to be 37% of the screen, according to designs. this.parent(props); this._childWidgets = []; + this._mainWidget = null; }, // Distribute children in two columns, except for the last one if an odd @@ -19,23 +21,41 @@ const CategoryLayoutManager = new Lang.Class({ _redistributeChildren: function() { let numChildren = this._childWidgets.length; let oddNumber = numChildren % 2 == 1; + + let numRows = 1; + this._childWidgets.forEach(function(child, index) { - let column = index % 2; + let column = (index % 2) + 1; //plus 1 because the mainWidget is the 0 column. let row = Math.floor(index / 2); + if(numRows < row + 1) + numRows = row + 1; //our running count of how many rows we have, which we + //need when we add the main widget. + if(child.get_parent() === this) Gtk.Container.prototype.remove.call(this, this._childWidgets[index]); if(oddNumber && index == numChildren - 1) - this.attach(child, 0, row, 2, 1); + this.attach(child, 1, row, 2, 1); else this.attach(child, column, row, 1, 1); }, this); + + if(this._mainWidget) { + if(this._mainWidget.get_parent() === this) { + Gtk.Container.prototype.remove.call(this, this._mainWidget); + } + this.attach(this._mainWidget, 0, 0, 1, numRows); + } }, add: function(child) { - this._childWidgets.push(child); + if(child.is_main_category) { + this._mainWidget = child; + } else { + this._childWidgets.push(child); + } this._redistributeChildren(); }, @@ -50,16 +70,3 @@ const CategoryLayoutManager = new Lang.Class({ this._redistributeChildren(); } }); - -// Gtk.init(null); -// let w = new Gtk.Window(); -// let g = new CategoryLayoutManager(); -// let count = 7; -// for(let i = 0; i < count; i++) { -// let widget = new Gtk.Button({label: 'Widget ' + i}); -// g.add(widget); -// } -// w.add(g); -// w.connect('destroy', Gtk.main_quit); -// w.show_all(); -// Gtk.main(); diff --git a/wikipedia/widgets/category_selector_view.js b/wikipedia/widgets/category_selector_view.js index 776bf52..57188ea 100644 --- a/wikipedia/widgets/category_selector_view.js +++ b/wikipedia/widgets/category_selector_view.js @@ -27,12 +27,20 @@ const CategorySelectorView = new Lang.Class({ // Takes an array of dictionaries with keys 'title' and 'image_uri' setCategories: function(categories) { categories.forEach(function(category, index, obj) { + let isClickable = !category.getArticles().length == 0; let button = new CategoryButton.CategoryButton({ category_title: category.title, - image_uri: category.image_thumbnail_uri + image_uri: category.image_thumbnail_uri, + clickable_category: isClickable, + is_main_category: category.is_main_category, + hexpand: !category.is_main_category }); button.index = index; - button.connect('clicked', Lang.bind(this, this._onButtonClicked)); + //if the category has no articles, you shouldn't be able to click on it. + if(isClickable) { + button.connect('clicked', Lang.bind(this, this._onButtonClicked)); + } + this.add(button); }, this); }, |