diff options
Diffstat (limited to 'wikipedia')
-rw-r--r-- | wikipedia/EndlessWikipedia.js | 1 | ||||
-rw-r--r-- | wikipedia/PrebuiltFrontPage.js | 21 | ||||
-rw-r--r-- | wikipedia/models/category_model.js | 3 | ||||
-rw-r--r-- | wikipedia/models/domain_wiki_model.js | 14 | ||||
-rw-r--r-- | wikipedia/presenters/domain_wiki_presenter.js | 14 | ||||
-rw-r--r-- | wikipedia/views/domain_wiki_view.js | 5 | ||||
-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 |
9 files changed, 118 insertions, 81 deletions
diff --git a/wikipedia/EndlessWikipedia.js b/wikipedia/EndlessWikipedia.js index 25df16c..2767e61 100644 --- a/wikipedia/EndlessWikipedia.js +++ b/wikipedia/EndlessWikipedia.js @@ -10,6 +10,7 @@ this.ArticleList = imports.wikipedia.ArticleList.ArticleList; this.WikipediaWebView = imports.wikipedia.WikipediaWebView.WikipediaWebView; const STYLE_CLASS_TITLE = 'title'; +const STYLE_CLASS_MAIN = 'main-element'; const STYLE_CLASS_PREBUILT = 'prebuilt'; const STYLE_CLASS_CATEGORY = 'category'; const STYLE_CLASS_ARTICLE = 'article'; diff --git a/wikipedia/PrebuiltFrontPage.js b/wikipedia/PrebuiltFrontPage.js index 5da89f0..73f915e 100644 --- a/wikipedia/PrebuiltFrontPage.js +++ b/wikipedia/PrebuiltFrontPage.js @@ -4,7 +4,6 @@ const Lang = imports.lang; const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; const CategorySelectorView = imports.wikipedia.widgets.category_selector_view; -const TitleLabelView = imports.wikipedia.widgets.title_label_view; const TITLE_CATEGORY_COLUMN_SPACING = 10; // pixels @@ -13,18 +12,6 @@ GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags. const PrebuiltFrontPage = new Lang.Class({ Name: 'PrebuiltFrontPage', Extends: Gtk.Grid, - Properties: { - 'title': GObject.ParamSpec.string('title', - 'Front page title', - 'Name of the Wikipedia-based application', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - 'image-uri': GObject.ParamSpec.string('image-uri', - 'Image URI', - 'Image URI for title image', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - '') - }, Signals: { 'category-chosen': { param_types: [GObject.TYPE_STRING, GObject.TYPE_INT] @@ -32,14 +19,7 @@ const PrebuiltFrontPage = new Lang.Class({ }, _init: function(props) { - this._title = null; - this._image_uri = null; - this._title_label = new TitleLabelView.TitleLabelView(); - let context = this._title_label.get_style_context() - context.add_class(EndlessWikipedia.STYLE_CLASS_TITLE); - context.add_class(EndlessWikipedia.STYLE_CLASS_PREBUILT); - context.add_class(EndlessWikipedia.STYLE_CLASS_FRONT_PAGE); this._category_selector = new CategorySelectorView.CategorySelectorView(); props = props || {}; @@ -47,7 +27,6 @@ const PrebuiltFrontPage = new Lang.Class({ props.column_spacing = TITLE_CATEGORY_COLUMN_SPACING; this.parent(props); - this.add(this._title_label); this.add(this._category_selector); this._category_selector.connect('category-chosen', Lang.bind(this, this._onCategoryChosen)); diff --git a/wikipedia/models/category_model.js b/wikipedia/models/category_model.js index 1c981bc..8a1c1ff 100644 --- a/wikipedia/models/category_model.js +++ b/wikipedia/models/category_model.js @@ -21,6 +21,9 @@ const CategoryModel = new Lang.Class({ 'image-thumbnail-uri': GObject.ParamSpec.string('image-thumbnail-uri', 'Category Thumbnail Image URI', 'Path to thumbnail image for this category in the GResource', GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT, ""), + 'is-main-category': GObject.ParamSpec.boolean('is-main-category', 'Is Main Category boolean', 'Flag denoting whether this category is the main category for this app', + GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT, + false), }, _init: function(params) { diff --git a/wikipedia/models/domain_wiki_model.js b/wikipedia/models/domain_wiki_model.js index 87941ba..a387ff9 100644 --- a/wikipedia/models/domain_wiki_model.js +++ b/wikipedia/models/domain_wiki_model.js @@ -12,20 +12,6 @@ const DomainWikiModel = new Lang.Class({ Name: "DomainWikiModel", Extends: GObject.Object, - Properties: { - 'image-uri': GObject.ParamSpec.string('image-uri', - 'Application image URI', - 'URI describing a path to the image for this application.', - GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT_ONLY, - ''), - - // Name of the Wikipedia-based application, e.g. 'Brazil', 'Math' - 'application-name': GObject.ParamSpec.string('application-name', - 'Application name', - 'Name of the Wikipedia-based application', - GObject.ParamFlags.READABLE, - '') - }, //params should have the image-uri for the app's image, and the application name. _init: function(params) { diff --git a/wikipedia/presenters/domain_wiki_presenter.js b/wikipedia/presenters/domain_wiki_presenter.js index 15229ce..b6b432a 100644 --- a/wikipedia/presenters/domain_wiki_presenter.js +++ b/wikipedia/presenters/domain_wiki_presenter.js @@ -46,8 +46,6 @@ const DomainWikiPresenter = new Lang.Class({ initFromJsonFile: function(filename) { let app_content = JSON.parse(Utils.load_file_from_resource(filename)); - this._application_name = app_content['app_name']; - this._image_uri = app_content['app_image_uri']; this._lang_code = filename.substring(0, 2); let categories = app_content['categories']; let cat_length = categories.length @@ -56,18 +54,24 @@ const DomainWikiPresenter = new Lang.Class({ let category = categories[i]; let categoryModel = this.initCategory(category); let articles = category['articles']; - categoryModel.addArticles(this.initArticleModels(articles)); + let articleModels = []; + if(!(articles.length == 0)) { + //if the category has no articles, then we cannot initialize them. + //This happens if the main category isn't clickable. + articleModels = this.initArticleModels(articles); + } + categoryModel.addArticles(articleModels); category_models.push(categoryModel); } this._domain_wiki_model.addCategories(category_models); - this._domain_wiki_view.set_front_page_info(this._application_name, this._image_uri); }, initCategory: function(category){ let image_uri = category['image_file']; let image_thumbnail_uri = category['image_thumb_uri']; let params = {description:category['content_text'], image_uri:image_uri, - image_thumbnail_uri:image_thumbnail_uri, title:category['category_name']}; + image_thumbnail_uri:image_thumbnail_uri, title:category['category_name'], + is_main_category:category['is_main_category']}; return new CategoryModel.CategoryModel(params); }, diff --git a/wikipedia/views/domain_wiki_view.js b/wikipedia/views/domain_wiki_view.js index 9dd8358..a44eaa2 100644 --- a/wikipedia/views/domain_wiki_view.js +++ b/wikipedia/views/domain_wiki_view.js @@ -165,11 +165,6 @@ const DomainWikiView = new Lang.Class({ this._presenter = presenter; }, - set_front_page_info: function(title, image_uri) { - this._front_page.title = title; - this._front_page.image_uri = image_uri; - }, - set_category_info: function(category, articles) { this._category_view.title = category.title; this._category_view.description = category.description; 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); }, |