From 541264aa07df694efcb38508f883b8d8167709b1 Mon Sep 17 00:00:00 2001 From: Floens Date: Mon, 1 Jun 2015 17:26:01 +0200 Subject: [PATCH] Add theme selector --- .../java/org/floens/chan/chan/ChanParser.java | 20 +- .../java/org/floens/chan/core/model/Post.java | 2 +- .../chan/ui/activity/StartActivity.java | 2 +- .../chan/ui/adapter/ImageViewerAdapter.java | 2 +- .../floens/chan/ui/cell/ThreadStatusCell.java | 1 + .../ui/controller/MainSettingsController.java | 17 +- .../controller/ThemeSettingsController.java | 214 ++++++++++++++++++ .../java/org/floens/chan/ui/theme/Theme.java | 4 +- .../org/floens/chan/ui/theme/ThemeHelper.java | 12 +- .../chan/ui/toolbar/NavigationItem.java | 6 + .../org/floens/chan/ui/toolbar/Toolbar.java | 6 + .../floens/chan/ui/view/ViewPagerAdapter.java | 4 +- .../main/res/layout/cell_thread_status.xml | 2 +- .../layout/controller_navigation_drawer.xml | 1 - .../controller_navigation_image_viewer.xml | 1 - .../src/main/res/layout/settings_theme.xml | 42 ++++ Clover/app/src/main/res/values/strings.xml | 5 +- 17 files changed, 307 insertions(+), 34 deletions(-) create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java create mode 100644 Clover/app/src/main/res/layout/settings_theme.xml diff --git a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java index bfa508b2..feef5cb9 100644 --- a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java @@ -36,9 +36,9 @@ import org.floens.chan.R; import org.floens.chan.core.model.Post; import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.settings.ChanSettings; +import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.Logger; -import org.floens.chan.ui.theme.ThemeHelper; import org.jsoup.Jsoup; import org.jsoup.helper.StringUtil; import org.jsoup.nodes.Document; @@ -71,7 +71,15 @@ public class ChanParser { public ChanParser() { } - public void parse(Post post) { + public void parse(Context context, Post post) { + if (context == null) { + context = ThemeHelper.getInstance().getThemedContext(); + } + + if (context == null) { + context = AndroidUtils.getAppRes(); + } + try { if (!TextUtils.isEmpty(post.name)) { post.name = Parser.unescapeEntities(post.name, false); @@ -86,7 +94,7 @@ public class ChanParser { if (!post.parsedSpans) { post.parsedSpans = true; - parseSpans(post); + parseSpans(context, post); } if (post.rawComment != null) { @@ -94,7 +102,7 @@ public class ChanParser { } } - private void parseSpans(Post post) { + private void parseSpans(Context context, Post post) { boolean anonymize = ChanSettings.anonymize.get(); boolean anonymizeIds = ChanSettings.anonymizeIds.get(); @@ -108,10 +116,6 @@ public class ChanParser { } int detailsSizePx = sp(Integer.parseInt(ChanSettings.fontSize.get()) - 4); - Context context = ThemeHelper.getInstance().getThemedContext(); - if (context == null) { - context = AndroidUtils.getAppRes(); - } TypedArray ta = context.obtainStyledAttributes(new int[]{ R.attr.post_subject_color, diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java index b6d59a8b..3638f7b6 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java @@ -133,7 +133,7 @@ public class Post { countryUrl = b.trollFlags ? ChanUrls.getTrollCountryFlagUrl(country) : ChanUrls.getCountryFlagUrl(country); } - ChanParser.getInstance().parse(this); + ChanParser.getInstance().parse(null, this); return true; } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java index 0d28c5d5..e76119a9 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java @@ -33,11 +33,11 @@ import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Pin; import org.floens.chan.core.settings.ChanSettings; -import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.controller.BrowseController; import org.floens.chan.ui.controller.RootNavigationController; import org.floens.chan.ui.controller.ViewThreadController; import org.floens.chan.ui.state.ChanState; +import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.utils.Logger; import java.util.ArrayList; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java index 5fb6f653..c567ce42 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/adapter/ImageViewerAdapter.java @@ -46,7 +46,7 @@ public class ImageViewerAdapter extends ViewPagerAdapter { } @Override - public View getView(int position) { + public View getView(int position, ViewGroup parent) { PostImage postImage = images.get(position); MultiImageView view = new MultiImageView(context); view.bindPostImage(postImage, multiImageViewCallback); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/ThreadStatusCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/ThreadStatusCell.java index a1172287..14f03cfc 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/ThreadStatusCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/ThreadStatusCell.java @@ -143,6 +143,7 @@ public class ThreadStatusCell extends LinearLayout implements View.OnClickListen public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if (hasWindowFocus) { + update(); schedule(); } else { unschedule(); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java index 6b39cc1d..71b9d8b2 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java @@ -25,7 +25,6 @@ import android.widget.Toast; import org.floens.chan.R; import org.floens.chan.core.settings.ChanSettings; -import org.floens.chan.ui.activity.StartActivity; import org.floens.chan.ui.settings.BooleanSettingView; import org.floens.chan.ui.settings.LinkSettingView; import org.floens.chan.ui.settings.ListSettingView; @@ -51,7 +50,6 @@ public class MainSettingsController extends SettingsController implements Toolba private LinkSettingView passLink; private int clickCount; private SettingView developerView; - private SettingView theme; public MainSettingsController(Context context) { super(context); @@ -101,8 +99,6 @@ public class MainSettingsController extends SettingsController implements Toolba if (item == imageAutoLoadView) { videoAutoLoadView.setEnabled(ChanSettings.imageAutoLoad.get()); - } else if (item == theme) { - ((StartActivity)context).restart(); } } @@ -140,17 +136,18 @@ public class MainSettingsController extends SettingsController implements Toolba } })); + general.add(new LinkSettingView(this, s(R.string.settings_screen_theme), null, new View.OnClickListener() { + @Override + public void onClick(View v) { + navigationController.pushController(new ThemeSettingsController(context)); + } + })); + groups.add(general); // Browsing group SettingsGroup browsing = new SettingsGroup(s(R.string.settings_group_browsing)); - theme = browsing.add(new ListSettingView(this, ChanSettings.theme, s(R.string.setting_theme), new ListSettingView.Item[]{ - new ListSettingView.Item(s(R.string.setting_theme_light), "light"), - new ListSettingView.Item(s(R.string.setting_theme_dark), "dark"), - new ListSettingView.Item(s(R.string.setting_theme_black), "black") - })); - List fontSizes = new ArrayList<>(); for (int size = 10; size <= 19; size++) { String name = size + (String.valueOf(size).equals(ChanSettings.fontSize.getDefault()) ? " " + s(R.string.setting_font_size_default) : ""); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java new file mode 100644 index 00000000..7668d489 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java @@ -0,0 +1,214 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.floens.chan.ui.controller; + +import android.content.Context; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.view.ViewPager; +import android.support.v7.internal.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import org.floens.chan.R; +import org.floens.chan.chan.ChanParser; +import org.floens.chan.controller.Controller; +import org.floens.chan.core.model.Loadable; +import org.floens.chan.core.model.Post; +import org.floens.chan.core.model.PostLinkable; +import org.floens.chan.core.settings.ChanSettings; +import org.floens.chan.ui.activity.StartActivity; +import org.floens.chan.ui.cell.PostCell; +import org.floens.chan.ui.theme.Theme; +import org.floens.chan.ui.theme.ThemeHelper; +import org.floens.chan.ui.toolbar.NavigationItem; +import org.floens.chan.ui.toolbar.Toolbar; +import org.floens.chan.ui.view.FloatingMenuItem; +import org.floens.chan.ui.view.ThumbnailView; +import org.floens.chan.ui.view.ViewPagerAdapter; +import org.floens.chan.utils.Time; + +import java.util.List; + +import static org.floens.chan.utils.AndroidUtils.getAttrColor; + +public class ThemeSettingsController extends Controller implements View.OnClickListener { + private ViewPager pager; + private FloatingActionButton done; + + private Adapter adapter; + private ThemeHelper themeHelper; + + private PostCell.PostCellCallback DUMMY_POST_CALLBACK; + private Toolbar.ToolbarCallback DUMMY_TOOLBAR_CALLBACK; + + public ThemeSettingsController(Context context) { + super(context); + + DUMMY_POST_CALLBACK = new PostCell.PostCellCallback() { + private Loadable loadable = new Loadable("g", 1234); + + @Override + public Loadable getLoadable() { + return loadable; + } + + @Override + public void onPostClicked(Post post) { + } + + @Override + public void onThumbnailClicked(Post post, ThumbnailView thumbnail) { + } + + @Override + public void onShowPostReplies(Post post) { + } + + @Override + public void onPopulatePostOptions(Post post, List menu) { + menu.add(new FloatingMenuItem(1, "Option")); + } + + @Override + public void onPostOptionClicked(Post post, Object id) { + } + + @Override + public void onPostLinkableClicked(PostLinkable linkable) { + } + }; + + DUMMY_TOOLBAR_CALLBACK = new Toolbar.ToolbarCallback() { + @Override + public void onMenuOrBackClicked(boolean isArrow) { + } + + @Override + public void onSearchVisibilityChanged(boolean visible) { + } + + @Override + public String getSearchHint() { + return null; + } + + @Override + public void onSearchEntered(String entered) { + } + }; + } + + @Override + public void onCreate() { + super.onCreate(); + + navigationItem.setTitle(R.string.settings_screen_theme); + view = inflateRes(R.layout.settings_theme); + + themeHelper = ThemeHelper.getInstance(); + + pager = (ViewPager) view.findViewById(R.id.pager); + done = (FloatingActionButton) view.findViewById(R.id.done); + done.setOnClickListener(this); + + adapter = new Adapter(); + pager.setAdapter(adapter); + + String currentTheme = ChanSettings.theme.get(); + for (int i = 0; i < themeHelper.getThemes().size(); i++) { + Theme theme = themeHelper.getThemes().get(i); + if (theme.name.equals(currentTheme)) { + pager.setCurrentItem(i, false); + break; + } + } + } + + @Override + public void onClick(View v) { + if (v == done) { + Theme currentTheme = themeHelper.getThemes().get(pager.getCurrentItem()); + ChanSettings.theme.set(currentTheme.name); + ((StartActivity) context).restart(); + } + } + + private class Adapter extends ViewPagerAdapter { + private List themes; + + public Adapter() { + themes = themeHelper.getThemes(); + } + + @Override + public CharSequence getPageTitle(int position) { + return super.getPageTitle(position); + } + + @Override + public View getView(int position, ViewGroup parent) { + Theme theme = themes.get(position); + + Context themeContext = new ContextThemeWrapper(context, theme.resValue); + + Post post = new Post(); + post.no = 123456789; + post.time = (Time.get() - (30 * 60 * 1000)) / 1000; + post.repliesFrom.add(1); + post.repliesFrom.add(2); + post.repliesFrom.add(3); + post.subject = "Lorem ipsum"; + post.rawComment = ">>123456789
" + + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
" + + "
" + + ">>123456789
" + + "http://example.com/" + + "
" + + "Phasellus consequat semper sodales. Donec dolor lectus, aliquet nec mollis vel, rutrum vel enim."; + ChanParser.getInstance().parse(themeContext, post); + + LinearLayout linearLayout = new LinearLayout(themeContext); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.setBackgroundColor(getAttrColor(themeContext, R.attr.backcolor)); + + Toolbar toolbar = new Toolbar(themeContext); + toolbar.setCallback(DUMMY_TOOLBAR_CALLBACK); + toolbar.setBackgroundColor(theme.primaryColor.color); + NavigationItem item = new NavigationItem(); + item.title = theme.displayName; + item.hasBack = false; + toolbar.setNavigationItem(false, true, item); + + linearLayout.addView(toolbar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, + themeContext.getResources().getDimensionPixelSize(R.dimen.toolbar_height))); + + PostCell postCell = (PostCell) LayoutInflater.from(themeContext).inflate(R.layout.cell_post, null); + postCell.setPost(post, DUMMY_POST_CALLBACK, false, -1); + linearLayout.addView(postCell, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + return linearLayout; + } + + @Override + public int getCount() { + return themes.size(); + } + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java b/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java index 607219a0..e02751fb 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java @@ -18,12 +18,14 @@ package org.floens.chan.ui.theme; public class Theme { + public final String displayName; public final String name; public final int resValue; public final boolean isLightTheme; public final ThemeHelper.PrimaryColor primaryColor; - public Theme(String name, int resValue, boolean isLightTheme, ThemeHelper.PrimaryColor primaryColor) { + public Theme(String displayName, String name, int resValue, boolean isLightTheme, ThemeHelper.PrimaryColor primaryColor) { + this.displayName = displayName; this.name = name; this.resValue = resValue; this.isLightTheme = isLightTheme; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/theme/ThemeHelper.java b/Clover/app/src/main/java/org/floens/chan/ui/theme/ThemeHelper.java index 5c17b7af..ca889213 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/theme/ThemeHelper.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/theme/ThemeHelper.java @@ -52,9 +52,13 @@ public class ThemeHelper { private int inlineQuoteColor; public ThemeHelper() { - themes.add(new Theme("light", R.style.Chan_Theme, true, PrimaryColor.GREEN)); - themes.add(new Theme("dark", R.style.Chan_Theme_Dark, false, PrimaryColor.DARK)); - themes.add(new Theme("black", R.style.Chan_Theme_Black, false, PrimaryColor.BLACK)); + themes.add(new Theme("Light", "light", R.style.Chan_Theme, true, PrimaryColor.GREEN)); + themes.add(new Theme("Dark", "dark", R.style.Chan_Theme_Dark, false, PrimaryColor.DARK)); + themes.add(new Theme("Black", "black", R.style.Chan_Theme_Black, false, PrimaryColor.BLACK)); + } + + public List getThemes() { + return themes; } public void updateCurrentTheme() { @@ -168,7 +172,7 @@ public class ThemeHelper { PrimaryColor(String name, int color, int dark) { this.name = name; this.color = color; - this.dark= dark; + this.dark = dark; } } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java index 1ecfc495..ae37b7b0 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java @@ -26,6 +26,8 @@ import org.floens.chan.ui.view.FloatingMenuItem; import java.util.List; +import static org.floens.chan.utils.AndroidUtils.getString; + public class NavigationItem { public String title = ""; public String subtitle = ""; @@ -52,4 +54,8 @@ public class NavigationItem { toolbar.setTitle(this); } } + + public void setTitle(int resId) { + title = getString(resId); + } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java index a0542b94..c7999a76 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java @@ -25,6 +25,7 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -157,6 +158,10 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV navigationItemContainer = new LoadView(getContext()); navigationItemContainer.setListener(this); addView(navigationItemContainer, new LayoutParams(0, LayoutParams.MATCH_PARENT, 1f)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setElevation(dp(4f)); + } } private boolean openSearchInternal() { @@ -379,6 +384,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV titleParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; titleView.setLayoutParams(titleParams); subtitleView.setText(item.subtitle); + subtitleView.setTextColor(0xffffffff); titleView.setPadding(titleView.getPaddingLeft(), dp(5f), titleView.getPaddingRight(), titleView.getPaddingBottom()); } else { titleContainer.removeView(subtitleView); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/ViewPagerAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/view/ViewPagerAdapter.java index 4318d76c..88b1250f 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/ViewPagerAdapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/ViewPagerAdapter.java @@ -24,7 +24,7 @@ import android.view.ViewGroup; public abstract class ViewPagerAdapter extends PagerAdapter { @Override public Object instantiateItem(ViewGroup container, int position) { - View view = getView(position); + View view = getView(position, container); container.addView(view); @@ -40,5 +40,5 @@ public abstract class ViewPagerAdapter extends PagerAdapter { return view == object; } - public abstract View getView(int position); + public abstract View getView(int position, ViewGroup parent); } diff --git a/Clover/app/src/main/res/layout/cell_thread_status.xml b/Clover/app/src/main/res/layout/cell_thread_status.xml index c16dba90..7c176711 100644 --- a/Clover/app/src/main/res/layout/cell_thread_status.xml +++ b/Clover/app/src/main/res/layout/cell_thread_status.xml @@ -25,6 +25,6 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" - android:textColor="?text_color_primary" /> + android:textColor="?text_color_secondary" /> diff --git a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml index d251df7e..6d05e8c0 100644 --- a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml +++ b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml @@ -32,7 +32,6 @@ along with this program. If not, see . android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height" - android:elevation="4dp" tools:ignore="UnusedAttribute" /> . android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height" android:background="#e9000000" - android:elevation="4dp" tools:ignore="UnusedAttribute" /> + + + + + + + + diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index 211b883c..afdfb236 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -170,9 +170,6 @@ along with this program. If not, see . Browsing Theme - Light - Dark - Black Font size (default) Ask before opening links @@ -257,6 +254,8 @@ Don't have a 4chan Pass?<br> Using 4chan pass Off + + Themes