Some work on settings

tempwork
Floens 11 years ago
parent 28c81e6662
commit c8c89345e9
  1. 4
      Clover/app/build.gradle
  2. 11
      Clover/app/src/main/java/org/floens/chan/ChanApplication.java
  3. 2
      Clover/app/src/main/java/org/floens/chan/core/loader/ChanParser.java
  4. 2
      Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
  5. 2
      Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java
  6. 14
      Clover/app/src/main/java/org/floens/chan/core/preferences/ChanPreferences.java
  7. 19
      Clover/app/src/main/java/org/floens/chan/core/preferences/Preference.java
  8. 19
      Clover/app/src/main/java/org/floens/chan/core/preferences/StringPreference.java
  9. 2
      Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java
  10. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/AdvancedSettingsActivity.java
  11. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/BoardEditor.java
  12. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/ChanActivity.java
  13. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/ImageViewActivity.java
  14. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/PassSettingsActivity.java
  15. 2
      Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
  16. 2
      Clover/app/src/main/java/org/floens/chan/ui/adapter/PinnedAdapter.java
  17. 48
      Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java
  18. 106
      Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java
  19. 38
      Clover/app/src/main/java/org/floens/chan/ui/controller/SettingsController.java
  20. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ImageViewFragment.java
  21. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/PostRepliesFragment.java
  22. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
  23. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/SettingsFragment.java
  24. 2
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ThreadFragment.java
  25. 2
      Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
  26. 40
      Clover/app/src/main/java/org/floens/chan/ui/preferences/BooleanPreference.java
  27. 23
      Clover/app/src/main/java/org/floens/chan/ui/preferences/LinkPreference.java
  28. 87
      Clover/app/src/main/java/org/floens/chan/ui/preferences/ListPreference.java
  29. 14
      Clover/app/src/main/java/org/floens/chan/ui/preferences/PreferenceGroup.java
  30. 29
      Clover/app/src/main/java/org/floens/chan/ui/preferences/PreferenceItem.java
  31. 137
      Clover/app/src/main/java/org/floens/chan/ui/preferences/PreferencesController.java
  32. 2
      Clover/app/src/main/java/org/floens/chan/ui/service/WatchNotifier.java
  33. 4
      Clover/app/src/main/java/org/floens/chan/ui/toolbar/NavigationItem.java
  34. 3
      Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java
  35. 12
      Clover/app/src/main/java/org/floens/chan/ui/toolbar/ToolbarMenuItem.java
  36. 54
      Clover/app/src/main/java/org/floens/chan/ui/view/FloatingMenu.java
  37. 10
      Clover/app/src/main/java/org/floens/chan/ui/view/FloatingMenuItem.java
  38. 2
      Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java
  39. 25
      Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java
  40. 2
      Clover/app/src/main/java/org/floens/chan/utils/ImageSaver.java
  41. 2
      Clover/app/src/main/java/org/floens/chan/utils/ThemeHelper.java
  42. 28
      Clover/app/src/main/res/layout/preference_boolean.xml
  43. 25
      Clover/app/src/main/res/layout/preference_description.xml
  44. 6
      Clover/app/src/main/res/layout/preference_divider.xml
  45. 25
      Clover/app/src/main/res/layout/preference_group.xml
  46. 13
      Clover/app/src/main/res/layout/preference_link.xml
  47. 2
      Clover/app/src/main/res/layout/root_layout.xml
  48. 14
      Clover/app/src/main/res/layout/settings_layout.xml

@ -17,6 +17,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7
} }
lintOptions {
abortOnError false
}
/* /*
If you want to sign releases, make a file in app/keys.properties with the following content: If you want to sign releases, make a file in app/keys.properties with the following content:
keystoreFile=yourkey.store keystoreFile=yourkey.store

@ -19,8 +19,6 @@ package org.floens.chan;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import com.android.volley.RequestQueue; import com.android.volley.RequestQueue;
@ -31,11 +29,11 @@ import com.koushikdutta.ion.builder.Builders;
import com.koushikdutta.ion.builder.LoadBuilder; import com.koushikdutta.ion.builder.LoadBuilder;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences;
import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.ReplyManager; import org.floens.chan.core.manager.ReplyManager;
import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.net.BitmapLruImageCache; import org.floens.chan.core.net.BitmapLruImageCache;
import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.database.DatabaseManager; import org.floens.chan.database.DatabaseManager;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.FileCache; import org.floens.chan.utils.FileCache;
@ -71,6 +69,7 @@ public class ChanApplication extends Application {
public ChanApplication() { public ChanApplication() {
instance = this; instance = this;
con = this;
} }
public static ChanApplication getInstance() { public static ChanApplication getInstance() {
@ -109,16 +108,10 @@ public class ChanApplication extends Application {
return Ion.getDefault(getInstance()).build(getInstance()); return Ion.getDefault(getInstance()).build(getInstance());
} }
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(instance);
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
con = this;
// Force the overflow button to show, even on devices that have a // Force the overflow button to show, even on devices that have a
// physical button. // physical button.
try { try {

@ -31,7 +31,7 @@ import android.text.style.TypefaceSpan;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.model.PostLinkable;
import org.floens.chan.utils.ThemeHelper; import org.floens.chan.utils.ThemeHelper;

@ -40,7 +40,7 @@ import com.android.volley.VolleyError;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.core.loader.ChanLoader;
import org.floens.chan.core.loader.LoaderPool; import org.floens.chan.core.loader.LoaderPool;
import org.floens.chan.core.manager.ReplyManager.DeleteListener; import org.floens.chan.core.manager.ReplyManager.DeleteListener;

@ -21,7 +21,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;

@ -15,18 +15,28 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.core; package org.floens.chan.core.preferences;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Environment; import android.os.Environment;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.utils.AndroidUtils;
import java.io.File; import java.io.File;
public class ChanPreferences { public class ChanPreferences {
public static StringPreference defaultName;
public static StringPreference testTheme;
static {
SharedPreferences p = AndroidUtils.getPreferences();
defaultName = new StringPreference(p, "preference_default_name", "");
testTheme = new StringPreference(p, "preference_test_theme", "dark");
}
private static SharedPreferences p() { private static SharedPreferences p() {
return ChanApplication.getPreferences(); return AndroidUtils.getPreferences();
} }
public static boolean getOpenLinkConfirmation() { public static boolean getOpenLinkConfirmation() {

@ -0,0 +1,19 @@
package org.floens.chan.core.preferences;
import android.content.SharedPreferences;
public abstract class Preference<T> {
protected final SharedPreferences sharedPreferences;
protected final String key;
protected final T def;
public Preference(SharedPreferences sharedPreferences, String key, T def) {
this.sharedPreferences = sharedPreferences;
this.key = key;
this.def = def;
}
public abstract T get();
public abstract void set(T value);
}

@ -0,0 +1,19 @@
package org.floens.chan.core.preferences;
import android.content.SharedPreferences;
public class StringPreference extends Preference<String> {
public StringPreference(SharedPreferences sharedPreferences, String key, String def) {
super(sharedPreferences, key, def);
}
@Override
public String get() {
return sharedPreferences.getString(key, def);
}
@Override
public void set(String value) {
sharedPreferences.edit().putString(key, value).apply();
}
}

@ -25,7 +25,7 @@ import com.android.volley.VolleyError;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.core.loader.ChanLoader;
import org.floens.chan.core.loader.LoaderPool; import org.floens.chan.core.loader.LoaderPool;
import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.ChanThread;

@ -24,7 +24,7 @@ import android.preference.PreferenceFragment;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.ui.ThemeActivity; import org.floens.chan.ui.ThemeActivity;
import org.floens.chan.ui.fragment.FolderPickFragment; import org.floens.chan.ui.fragment.FolderPickFragment;

@ -47,7 +47,7 @@ import com.mobeta.android.dslv.DragSortListView;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Board;
import org.floens.chan.ui.SwipeDismissListViewTouchListener; import org.floens.chan.ui.SwipeDismissListViewTouchListener;

@ -43,7 +43,7 @@ import android.widget.TextView;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.core.loader.ChanLoader;
import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.ThreadManager; import org.floens.chan.core.manager.ThreadManager;

@ -29,7 +29,7 @@ import android.widget.ProgressBar;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ImageSearch; import org.floens.chan.chan.ImageSearch;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.manager.ThreadManager; import org.floens.chan.core.manager.ThreadManager;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.ui.ThemeActivity; import org.floens.chan.ui.ThemeActivity;

@ -37,7 +37,7 @@ import android.widget.TextView;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.manager.ReplyManager; import org.floens.chan.core.manager.ReplyManager;
import org.floens.chan.core.manager.ReplyManager.PassResponse; import org.floens.chan.core.manager.ReplyManager.PassResponse;
import org.floens.chan.core.model.Pass; import org.floens.chan.core.model.Pass;

@ -34,7 +34,7 @@ import android.widget.TextView;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.ui.ThemeActivity; import org.floens.chan.ui.ThemeActivity;
public class WatchSettingsActivity extends ThemeActivity implements OnCheckedChangeListener { public class WatchSettingsActivity extends ThemeActivity implements OnCheckedChangeListener {

@ -32,7 +32,7 @@ import android.widget.TextView;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Pin;
import org.floens.chan.ui.view.CustomNetworkImageView; import org.floens.chan.ui.view.CustomNetworkImageView;

@ -35,14 +35,14 @@ import org.floens.chan.core.model.Loadable;
import org.floens.chan.ui.layout.ThreadLayout; import org.floens.chan.ui.layout.ThreadLayout;
import org.floens.chan.ui.toolbar.ToolbarMenu; import org.floens.chan.ui.toolbar.ToolbarMenu;
import org.floens.chan.ui.toolbar.ToolbarMenuItem; import org.floens.chan.ui.toolbar.ToolbarMenuItem;
import org.floens.chan.ui.toolbar.ToolbarMenuSubItem; import org.floens.chan.ui.view.FloatingMenu;
import org.floens.chan.ui.toolbar.ToolbarMenuSubMenu; import org.floens.chan.ui.view.FloatingMenuItem;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class BrowseController extends Controller implements ToolbarMenuItem.ToolbarMenuItemCallback, ThreadLayout.ThreadLayoutCallback, ToolbarMenuSubMenu.ToolbarMenuItemSubMenuCallback, BoardManager.BoardChangeListener { public class BrowseController extends Controller implements ToolbarMenuItem.ToolbarMenuItemCallback, ThreadLayout.ThreadLayoutCallback, FloatingMenu.FloatingMenuCallback, BoardManager.BoardChangeListener {
private static final int REFRESH_ID = 1; private static final int REFRESH_ID = 1;
private static final int POST_ID = 2; private static final int POST_ID = 2;
private static final int SEARCH_ID = 101; private static final int SEARCH_ID = 101;
@ -50,7 +50,7 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
private static final int SETTINGS_ID = 103; private static final int SETTINGS_ID = 103;
private ThreadLayout threadLayout; private ThreadLayout threadLayout;
private List<ToolbarMenuSubItem> boardItems; private List<FloatingMenuItem> boardItems;
public BrowseController(Context context) { public BrowseController(Context context) {
super(context); super(context);
@ -62,7 +62,7 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
ChanApplication.getBoardManager().addListener(this); ChanApplication.getBoardManager().addListener(this);
navigationItem.middleMenu = new ToolbarMenuSubMenu(context); navigationItem.middleMenu = new FloatingMenu(context);
navigationItem.middleMenu.setCallback(this); navigationItem.middleMenu.setCallback(this);
loadBoards(); loadBoards();
@ -76,12 +76,12 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
ToolbarMenuItem overflow = menu.createOverflow(this); ToolbarMenuItem overflow = menu.createOverflow(this);
List<ToolbarMenuSubItem> items = new ArrayList<>(); List<FloatingMenuItem> items = new ArrayList<>();
items.add(new ToolbarMenuSubItem(SEARCH_ID, context.getString(R.string.action_search))); items.add(new FloatingMenuItem(SEARCH_ID, context.getString(R.string.action_search)));
items.add(new ToolbarMenuSubItem(SHARE_ID, context.getString(R.string.action_share))); items.add(new FloatingMenuItem(SHARE_ID, context.getString(R.string.action_share)));
items.add(new ToolbarMenuSubItem(SETTINGS_ID, context.getString(R.string.action_settings))); items.add(new FloatingMenuItem(SETTINGS_ID, context.getString(R.string.action_settings)));
overflow.setSubMenu(new ToolbarMenuSubMenu(context, overflow.getView(), items)); overflow.setSubMenu(new FloatingMenu(context, overflow.getView(), items));
threadLayout = new ThreadLayout(context); threadLayout = new ThreadLayout(context);
threadLayout.setCallback(this); threadLayout.setCallback(this);
@ -111,8 +111,8 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
} }
@Override @Override
public void onSubMenuItemClicked(ToolbarMenuItem parent, ToolbarMenuSubItem item) { public void onSubMenuItemClicked(ToolbarMenuItem parent, FloatingMenuItem item) {
switch (item.getId()) { switch ((Integer) item.getId()) {
case SEARCH_ID: case SEARCH_ID:
// TODO // TODO
break; break;
@ -121,17 +121,17 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
AndroidUtils.shareLink(link); AndroidUtils.shareLink(link);
break; break;
case SETTINGS_ID: case SETTINGS_ID:
SettingsController settingsController = new SettingsController(context); MainSettingsController mainSettingsController = new MainSettingsController(context);
navigationController.pushController(settingsController); navigationController.pushController(mainSettingsController);
break; break;
} }
} }
@Override @Override
public void onSubMenuItemClicked(ToolbarMenuSubMenu menu, ToolbarMenuSubItem item) { public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) {
if (menu == navigationItem.middleMenu) { if (menu == navigationItem.middleMenu) {
if (item instanceof ToolbarMenuSubItemBoard) { if (item instanceof FloatingMenuItemBoard) {
loadBoard(((ToolbarMenuSubItemBoard) item).board); loadBoard(((FloatingMenuItemBoard) item).board);
navigationController.toolbar.updateNavigation(); navigationController.toolbar.updateNavigation();
} else { } else {
// TODO start board editor // TODO start board editor
@ -161,8 +161,8 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
threadLayout.getPresenter().bindLoadable(loadable); threadLayout.getPresenter().bindLoadable(loadable);
threadLayout.getPresenter().requestData(); threadLayout.getPresenter().requestData();
for (ToolbarMenuSubItem item : boardItems) { for (FloatingMenuItem item : boardItems) {
if (((ToolbarMenuSubItemBoard) item).board == board) { if (((FloatingMenuItemBoard) item).board == board) {
navigationItem.middleMenu.setSelectedItem(item); navigationItem.middleMenu.setSelectedItem(item);
} }
} }
@ -172,7 +172,7 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
List<Board> boards = ChanApplication.getBoardManager().getSavedBoards(); List<Board> boards = ChanApplication.getBoardManager().getSavedBoards();
boardItems = new ArrayList<>(); boardItems = new ArrayList<>();
for (Board board : boards) { for (Board board : boards) {
ToolbarMenuSubItem item = new ToolbarMenuSubItemBoard(board); FloatingMenuItem item = new FloatingMenuItemBoard(board);
boardItems.add(item); boardItems.add(item);
} }
@ -180,10 +180,10 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
navigationItem.middleMenu.setAdapter(new BoardsAdapter(context, boardItems)); navigationItem.middleMenu.setAdapter(new BoardsAdapter(context, boardItems));
} }
private static class ToolbarMenuSubItemBoard extends ToolbarMenuSubItem { private static class FloatingMenuItemBoard extends FloatingMenuItem {
public Board board; public Board board;
public ToolbarMenuSubItemBoard(Board board) { public FloatingMenuItemBoard(Board board) {
super(board.id, board.key); super(board.id, board.key);
this.board = board; this.board = board;
} }
@ -191,9 +191,9 @@ public class BrowseController extends Controller implements ToolbarMenuItem.Tool
private static class BoardsAdapter extends BaseAdapter { private static class BoardsAdapter extends BaseAdapter {
private final Context context; private final Context context;
private List<ToolbarMenuSubItem> items; private List<FloatingMenuItem> items;
public BoardsAdapter(Context context, List<ToolbarMenuSubItem> items) { public BoardsAdapter(Context context, List<FloatingMenuItem> items) {
this.context = context; this.context = context;
this.items = items; this.items = items;
} }

@ -0,0 +1,106 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.ui.controller;
import android.app.AlertDialog;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
import org.floens.chan.R;
import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.ui.preferences.LinkPreference;
import org.floens.chan.ui.preferences.ListPreference;
import org.floens.chan.ui.preferences.PreferenceGroup;
import org.floens.chan.ui.preferences.PreferenceItem;
import org.floens.chan.ui.preferences.PreferencesController;
public class MainSettingsController extends PreferencesController {
private ListPreference theme;
private LinkPreference link;
public MainSettingsController(Context context) {
super(context);
}
@Override
public void onCreate() {
super.onCreate();
//TODO correct header colors, background, themeing
navigationItem.title = context.getString(R.string.action_settings);
view = inflateRes(R.layout.settings_layout);
content = (LinearLayout) view.findViewById(R.id.scrollview_content);
populatePreferences();
buildPreferences();
}
@Override
public void onPreferenceChange(PreferenceItem item) {
super.onPreferenceChange(item);
if (item == theme) {
link.setEnabled(((ListPreference)item).getPreference().get().equals("dark"));
}
}
private void populatePreferences() {
PreferenceGroup settings = new PreferenceGroup("Settings");
ListPreference.Item[] themeItems = new ListPreference.Item[2];
themeItems[0] = new ListPreference.Item<>("Light", "light");
themeItems[1] = new ListPreference.Item<>("Dark", "dark");
theme = new ListPreference(this, ChanPreferences.testTheme, "Theme", themeItems);
settings.preferenceItems.add(theme);
// BooleanPreference bool = new BooleanPreference(p, "A name", "akey", false);
// settings.preferenceItems.add(bool);
link = new LinkPreference(this, "A link", new View.OnClickListener() {
public void onClick(View v) {
new AlertDialog.Builder(context).setMessage("click").setPositiveButton(R.string.ok, null).show();
}
});
settings.preferenceItems.add(link);
groups.add(settings);
/*PreferenceGroup posting = new PreferenceGroup("Posting");
ListPreference.Item[] postItems = new ListPreference.Item[4];
postItems[0] = new ListPreference.Item<>("Top", "one");
postItems[1] = new ListPreference.Item<>("Top", "two");
postItems[2] = new ListPreference.Item<>("Top", "three");
postItems[3] = new ListPreference.Item<>("Top", "four");
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
posting.preferenceItems.add(new ListPreference(p, "Something", "something", postItems));
groups.add(posting);*/
}
}

@ -1,38 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.ui.controller;
import android.content.Context;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
public class SettingsController extends Controller {
public SettingsController(Context context) {
super(context);
}
@Override
public void onCreate() {
super.onCreate();
navigationItem.title = context.getString(R.string.action_settings);
view = inflateRes(R.layout.settings_layout);
}
}

@ -36,7 +36,7 @@ import android.widget.VideoView;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ImageSearch; import org.floens.chan.chan.ImageSearch;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.ui.activity.ImageViewActivity; import org.floens.chan.ui.activity.ImageViewActivity;
import org.floens.chan.ui.adapter.ImageViewAdapter; import org.floens.chan.ui.adapter.ImageViewAdapter;

@ -30,7 +30,7 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.core.presenter.ThreadPresenter; import org.floens.chan.core.presenter.ThreadPresenter;
import org.floens.chan.ui.helper.PostPopupHelper; import org.floens.chan.ui.helper.PostPopupHelper;

@ -53,7 +53,7 @@ import com.android.volley.toolbox.StringRequest;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.manager.ReplyManager; import org.floens.chan.core.manager.ReplyManager;
import org.floens.chan.core.manager.ReplyManager.ReplyResponse; import org.floens.chan.core.manager.ReplyManager.ReplyResponse;
import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Board;

@ -30,7 +30,7 @@ import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.ui.activity.AboutActivity; import org.floens.chan.ui.activity.AboutActivity;
import org.floens.chan.ui.activity.BaseActivity; import org.floens.chan.ui.activity.BaseActivity;
import org.floens.chan.ui.activity.SettingsActivity; import org.floens.chan.ui.activity.SettingsActivity;

@ -44,7 +44,7 @@ import com.android.volley.ServerError;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.core.loader.ChanLoader;
import org.floens.chan.core.loader.EndOfLineException; import org.floens.chan.core.loader.EndOfLineException;
import org.floens.chan.core.manager.ThreadManager; import org.floens.chan.core.manager.ThreadManager;

@ -28,7 +28,7 @@ import android.widget.Toast;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;

@ -0,0 +1,40 @@
package org.floens.chan.ui.preferences;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.CompoundButton;
import org.floens.chan.R;
import org.floens.chan.core.preferences.Preference;
public class BooleanPreference extends PreferenceItem implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private SwitchCompat switcher;
private Preference<Boolean> preference;
public BooleanPreference(PreferencesController preferencesController, Preference<Boolean> preference, String name) {
super(preferencesController, name);
this.preference = preference;
}
@Override
public void setView(View view) {
super.setView(view);
view.setOnClickListener(this);
switcher = (SwitchCompat) view.findViewById(R.id.switcher);
switcher.setOnCheckedChangeListener(this);
switcher.setChecked(preference.get());
}
@Override
public void onClick(View v) {
switcher.toggle();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
preference.set(isChecked);
}
}

@ -0,0 +1,23 @@
package org.floens.chan.ui.preferences;
import android.view.View;
public class LinkPreference extends PreferenceItem {
private final View.OnClickListener clickListener;
public LinkPreference(PreferencesController preferencesController, String name, View.OnClickListener clickListener) {
super(preferencesController, name);
this.clickListener = clickListener;
}
@Override
public void setView(View view) {
super.setView(view);
view.setOnClickListener(clickListener);
}
@Override
public void setEnabled(boolean enabled) {
}
}

@ -0,0 +1,87 @@
package org.floens.chan.ui.preferences;
import android.view.Gravity;
import android.view.View;
import org.floens.chan.core.preferences.Preference;
import org.floens.chan.ui.view.FloatingMenu;
import org.floens.chan.ui.view.FloatingMenuItem;
import java.util.ArrayList;
import java.util.List;
import static org.floens.chan.utils.AndroidUtils.dp;
public class ListPreference extends PreferenceItem implements FloatingMenu.FloatingMenuCallback, View.OnClickListener {
public final Item[] items;
private Preference<String> preference;
private int selected;
public ListPreference(PreferencesController preferencesController, Preference<String> preference, String name, Item[] items) {
super(preferencesController, name);
this.preference = preference;
this.items = items;
selectItem();
}
public String getBottomDescription() {
return items[selected].name;
}
public Preference<String> getPreference() {
return preference;
}
@Override
public void setView(View view) {
super.setView(view);
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
List<FloatingMenuItem> menuItems = new ArrayList<>(2);
for (Item item : items) {
menuItems.add(new FloatingMenuItem(item.key, item.name));
}
FloatingMenu menu = new FloatingMenu(v.getContext());
menu.setAnchor(v, Gravity.LEFT, dp(5), dp(5));
menu.setPopupWidth(FloatingMenu.POPUP_WIDTH_ANCHOR);
menu.setCallback(this);
menu.setItems(menuItems);
menu.show();
}
@Override
public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) {
String selectedKey = (String) item.getId();
preference.set(selectedKey);
selectItem();
preferencesController.onPreferenceChange(this);
}
private void selectItem() {
String selectedKey = preference.get();
for (int i = 0; i < items.length; i++) {
if (items[i].key.equals(selectedKey)) {
selected = i;
break;
}
}
}
public static class Item<T> {
public final String name;
public final T key;
public Item(String name, T key) {
this.name = name;
this.key = key;
}
}
}

@ -0,0 +1,14 @@
package org.floens.chan.ui.preferences;
import java.util.ArrayList;
import java.util.List;
public class PreferenceGroup {
public final String name;
public PreferenceGroup(String name) {
this.name = name;
}
public List<PreferenceItem> preferenceItems = new ArrayList<>();
}

@ -0,0 +1,29 @@
package org.floens.chan.ui.preferences;
import android.view.View;
public abstract class PreferenceItem {
public PreferencesController preferencesController;
public final String name;
public View view;
public PreferenceItem(PreferencesController preferencesController, String name) {
this.preferencesController = preferencesController;
this.name = name;
}
public void setView(View view) {
this.view = view;
}
public void setEnabled(boolean enabled) {
}
public String getTopDescription() {
return name;
}
public String getBottomDescription() {
return null;
}
}

@ -0,0 +1,137 @@
package org.floens.chan.ui.preferences;
import android.content.Context;
import android.content.res.Configuration;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
import org.floens.chan.utils.AndroidUtils;
import java.util.ArrayList;
import java.util.List;
import static org.floens.chan.utils.AndroidUtils.dp;
public class PreferencesController extends Controller implements AndroidUtils.OnMeasuredCallback {
protected LinearLayout content;
protected List<PreferenceGroup> groups = new ArrayList<>();
public PreferencesController(Context context) {
super(context);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onShow() {
super.onShow();
AndroidUtils.waitForLayout(view, this);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
AndroidUtils.waitForLayout(view, this);
}
@Override
public void onMeasured(View view, int width, int height) {
setMargins();
}
public void onPreferenceChange(PreferenceItem item) {
if (item instanceof ListPreference) {
setDescriptionText(item.view, item.getTopDescription(), item.getBottomDescription());
}
}
private void setMargins() {
boolean tablet = view.getWidth() > dp(500); // TODO is tablet
int margin = 0;
if (tablet) {
margin = (int) (view.getWidth() * 0.1);
}
int itemMargin = 0;
if (tablet) {
itemMargin = dp(16);
}
List<View> groups = AndroidUtils.findViewsById(content, R.id.group);
for (View group : groups) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) group.getLayoutParams();
params.leftMargin = margin;
params.rightMargin = margin;
group.setLayoutParams(params);
}
List<View> items = AndroidUtils.findViewsById(content, R.id.preference_item);
for (View item : items) {
item.setPadding(itemMargin, item.getPaddingTop(), itemMargin, item.getPaddingBottom());
}
}
protected void buildPreferences() {
LayoutInflater inf = LayoutInflater.from(context);
boolean firstGroup = true;
for (PreferenceGroup group : groups) {
LinearLayout groupLayout = (LinearLayout) inf.inflate(R.layout.preference_group, content, false);
((TextView) groupLayout.findViewById(R.id.header)).setText(group.name);
if (firstGroup) {
firstGroup = false;
((LinearLayout.LayoutParams) groupLayout.getLayoutParams()).topMargin = 0;
}
content.addView(groupLayout);
for (int i = 0; i < group.preferenceItems.size(); i++) {
PreferenceItem preferenceItem = group.preferenceItems.get(i);
ViewGroup preferenceView = null;
String topValue = preferenceItem.getTopDescription();
String bottomValue = preferenceItem.getBottomDescription();
if ((preferenceItem instanceof ListPreference) || (preferenceItem instanceof LinkPreference)) {
preferenceView = (ViewGroup) inf.inflate(R.layout.preference_link, groupLayout, false);
} else if (preferenceItem instanceof BooleanPreference) {
preferenceView = (ViewGroup) inf.inflate(R.layout.preference_boolean, groupLayout, false);
}
setDescriptionText(preferenceView, topValue, bottomValue);
groupLayout.addView(preferenceView);
preferenceItem.setView(preferenceView);
if (i < group.preferenceItems.size() - 1) {
inf.inflate(R.layout.preference_divider, groupLayout, true);
}
}
}
}
private void setDescriptionText(View view, String topText, String bottomText) {
((TextView) view.findViewById(R.id.top)).setText(topText);
TextView bottom = ((TextView) view.findViewById(R.id.bottom));
if (bottom != null) {
if (bottomText == null) {
ViewGroup parent = (ViewGroup) bottom.getParent();
parent.removeView(bottom);
} else {
bottom.setText(bottomText);
}
}
}
}

@ -28,7 +28,7 @@ import android.support.v4.app.NotificationCompat;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;

@ -19,10 +19,12 @@ package org.floens.chan.ui.toolbar;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import org.floens.chan.ui.view.FloatingMenu;
public class NavigationItem { public class NavigationItem {
public String title = ""; public String title = "";
public ToolbarMenu menu; public ToolbarMenu menu;
public boolean hasBack = true; public boolean hasBack = true;
public LinearLayout view; public LinearLayout view;
public ToolbarMenuSubMenu middleMenu; public FloatingMenu middleMenu;
} }

@ -26,7 +26,6 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.support.v4.view.GravityCompat;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -228,7 +227,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
// black: titleView.setTextColor(Color.argb((int)(0.87 * 255.0), 0, 0, 0)); // black: titleView.setTextColor(Color.argb((int)(0.87 * 255.0), 0, 0, 0));
if (item.middleMenu != null) { if (item.middleMenu != null) {
item.middleMenu.setAnchor(titleView, GravityCompat.END | Gravity.TOP, dp(5), dp(5)); // TODO gravity left doesn't work item.middleMenu.setAnchor(titleView, Gravity.LEFT, dp(5), dp(5));
Drawable drawable = new DropdownArrowDrawable(); Drawable drawable = new DropdownArrowDrawable();
titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null); titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);

@ -25,14 +25,16 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.ui.view.FloatingMenu;
import org.floens.chan.ui.view.FloatingMenuItem;
import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getAttrDrawable; import static org.floens.chan.utils.AndroidUtils.getAttrDrawable;
public class ToolbarMenuItem implements View.OnClickListener, ToolbarMenuSubMenu.ToolbarMenuItemSubMenuCallback { public class ToolbarMenuItem implements View.OnClickListener, FloatingMenu.FloatingMenuCallback {
private ToolbarMenuItemCallback callback; private ToolbarMenuItemCallback callback;
private int id; private int id;
private ToolbarMenuSubMenu subMenu; private FloatingMenu subMenu;
private ImageView imageView; private ImageView imageView;
@ -65,7 +67,7 @@ public class ToolbarMenuItem implements View.OnClickListener, ToolbarMenuSubMenu
} }
} }
public void setSubMenu(ToolbarMenuSubMenu subMenu) { public void setSubMenu(FloatingMenu subMenu) {
this.subMenu = subMenu; this.subMenu = subMenu;
subMenu.setCallback(this); subMenu.setCallback(this);
} }
@ -91,13 +93,13 @@ public class ToolbarMenuItem implements View.OnClickListener, ToolbarMenuSubMenu
} }
@Override @Override
public void onSubMenuItemClicked(ToolbarMenuSubMenu menu, ToolbarMenuSubItem item) { public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) {
callback.onSubMenuItemClicked(this, item); callback.onSubMenuItemClicked(this, item);
} }
public interface ToolbarMenuItemCallback { public interface ToolbarMenuItemCallback {
public void onMenuItemClicked(ToolbarMenuItem item); public void onMenuItemClicked(ToolbarMenuItem item);
public void onSubMenuItemClicked(ToolbarMenuItem parent, ToolbarMenuSubItem item); public void onSubMenuItemClicked(ToolbarMenuItem parent, FloatingMenuItem item);
} }
} }

@ -15,10 +15,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.ui.toolbar; package org.floens.chan.ui.view;
import android.content.Context; import android.content.Context;
import android.support.v4.view.GravityCompat;
import android.support.v7.widget.ListPopupWindow; import android.support.v7.widget.ListPopupWindow;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -39,31 +38,34 @@ import java.util.List;
import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.dp;
public class ToolbarMenuSubMenu { public class FloatingMenu {
public static final int POPUP_WIDTH_AUTO = -1;
public static final int POPUP_WIDTH_ANCHOR = -2;
private final Context context; private final Context context;
private View anchor; private View anchor;
private int anchorGravity; private int anchorGravity = Gravity.LEFT;
private int anchorOffsetX; private int anchorOffsetX;
private int anchorOffsetY; private int anchorOffsetY;
private int popupWidth = -1; private int popupWidth = POPUP_WIDTH_AUTO;
private List<ToolbarMenuSubItem> items; private List<FloatingMenuItem> items;
private ToolbarMenuSubItem selectedItem; private FloatingMenuItem selectedItem;
private ListAdapter adapter; private ListAdapter adapter;
private ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener; private ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener;
private ListPopupWindow popupWindow; private ListPopupWindow popupWindow;
private ToolbarMenuItemSubMenuCallback callback; private FloatingMenuCallback callback;
public ToolbarMenuSubMenu(Context context, View anchor, List<ToolbarMenuSubItem> items) { public FloatingMenu(Context context, View anchor, List<FloatingMenuItem> items) {
this.context = context; this.context = context;
this.anchor = anchor; this.anchor = anchor;
anchorGravity = Gravity.RIGHT | Gravity.TOP;
anchorOffsetX = -dp(5); anchorOffsetX = -dp(5);
anchorOffsetY = dp(5); anchorOffsetY = dp(5);
anchorGravity = Gravity.RIGHT;
this.items = items; this.items = items;
} }
public ToolbarMenuSubMenu(Context context) { public FloatingMenu(Context context) {
this.context = context; this.context = context;
} }
@ -81,14 +83,14 @@ public class ToolbarMenuSubMenu {
} }
} }
public void setItems(List<ToolbarMenuSubItem> items) { public void setItems(List<FloatingMenuItem> items) {
this.items = items; this.items = items;
if (popupWindow != null) { if (popupWindow != null) {
popupWindow.dismiss(); popupWindow.dismiss();
} }
} }
public void setSelectedItem(ToolbarMenuSubItem item) { public void setSelectedItem(FloatingMenuItem item) {
this.selectedItem = item; this.selectedItem = item;
} }
@ -96,7 +98,7 @@ public class ToolbarMenuSubMenu {
this.adapter = adapter; this.adapter = adapter;
} }
public void setCallback(ToolbarMenuItemSubMenuCallback callback) { public void setCallback(FloatingMenuCallback callback) {
this.callback = callback; this.callback = callback;
} }
@ -104,13 +106,15 @@ public class ToolbarMenuSubMenu {
popupWindow = new ListPopupWindow(context); popupWindow = new ListPopupWindow(context);
popupWindow.setAnchorView(anchor); popupWindow.setAnchorView(anchor);
popupWindow.setModal(true); popupWindow.setModal(true);
popupWindow.setDropDownGravity(GravityCompat.END | Gravity.TOP); popupWindow.setDropDownGravity(anchorGravity);
popupWindow.setVerticalOffset(-anchor.getHeight() + anchorOffsetY); popupWindow.setVerticalOffset(-anchor.getHeight() + anchorOffsetY);
popupWindow.setHorizontalOffset(anchorOffsetX); popupWindow.setHorizontalOffset(anchorOffsetX);
if (popupWidth > 0) { if (popupWidth == POPUP_WIDTH_ANCHOR) {
popupWindow.setContentWidth(popupWidth); popupWindow.setContentWidth(Math.min(dp(4 * 56), anchor.getWidth()));
} else { } else if (popupWidth == POPUP_WIDTH_AUTO) {
popupWindow.setContentWidth(dp(3 * 56)); popupWindow.setContentWidth(dp(3 * 56));
} else {
popupWindow.setContentWidth(popupWidth);
} }
List<String> stringItems = new ArrayList<>(items.size()); List<String> stringItems = new ArrayList<>(items.size());
@ -125,17 +129,17 @@ public class ToolbarMenuSubMenu {
if (adapter != null) { if (adapter != null) {
popupWindow.setAdapter(adapter); popupWindow.setAdapter(adapter);
} else { } else {
popupWindow.setAdapter(new SubMenuArrayAdapter(context, R.layout.toolbar_menu_item, stringItems)); popupWindow.setAdapter(new FloatingMenuArrayAdapter(context, R.layout.toolbar_menu_item, stringItems));
} }
popupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() { popupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position >= 0 && position < items.size()) { if (position >= 0 && position < items.size()) {
callback.onSubMenuItemClicked(ToolbarMenuSubMenu.this, items.get(position)); callback.onFloatingMenuItemClicked(FloatingMenu.this, items.get(position));
popupWindow.dismiss(); popupWindow.dismiss();
} else { } else {
callback.onSubMenuItemClicked(ToolbarMenuSubMenu.this, null); callback.onFloatingMenuItemClicked(FloatingMenu.this, null);
} }
} }
}); });
@ -166,12 +170,12 @@ public class ToolbarMenuSubMenu {
popupWindow.setSelection(selectedPosition); popupWindow.setSelection(selectedPosition);
} }
public interface ToolbarMenuItemSubMenuCallback { public interface FloatingMenuCallback {
public void onSubMenuItemClicked(ToolbarMenuSubMenu menu, ToolbarMenuSubItem item); public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item);
} }
private static class SubMenuArrayAdapter extends ArrayAdapter<String> { private static class FloatingMenuArrayAdapter extends ArrayAdapter<String> {
public SubMenuArrayAdapter(Context context, int resource, List<String> objects) { public FloatingMenuArrayAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects); super(context, resource, objects);
} }

@ -15,18 +15,18 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.ui.toolbar; package org.floens.chan.ui.view;
public class ToolbarMenuSubItem { public class FloatingMenuItem {
private int id; private Object id;
private String text; private String text;
public ToolbarMenuSubItem(int id, String text) { public FloatingMenuItem(Object id, String text) {
this.id = id; this.id = id;
this.text = text; this.text = text;
} }
public int getId() { public Object getId() {
return id; return id;
} }

@ -37,7 +37,7 @@ import com.koushikdutta.async.future.Future;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.FileCache; import org.floens.chan.utils.FileCache;
import org.floens.chan.utils.Logger; import org.floens.chan.utils.Logger;

@ -21,6 +21,7 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -28,6 +29,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -38,7 +40,9 @@ import android.widget.Toast;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public class AndroidUtils { public class AndroidUtils {
public final static ViewGroup.LayoutParams MATCH_PARAMS = new ViewGroup.LayoutParams( public final static ViewGroup.LayoutParams MATCH_PARAMS = new ViewGroup.LayoutParams(
@ -67,6 +71,10 @@ public class AndroidUtils {
return ChanApplication.con; return ChanApplication.con;
} }
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(ChanApplication.con);
}
public static void openLink(String link) { public static void openLink(String link) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -209,4 +217,21 @@ public class AndroidUtils {
arr.recycle(); arr.recycle();
view.setBackgroundDrawable(drawable); view.setBackgroundDrawable(drawable);
} }
public static List<View> findViewsById(ViewGroup root, int id) {
List<View> views = new ArrayList<>();
int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = root.getChildAt(i);
if (child instanceof ViewGroup) {
views.addAll(findViewsById((ViewGroup) child, id));
}
if (child.getId() == id) {
views.add(child);
}
}
return views;
}
} }

@ -32,7 +32,7 @@ import com.koushikdutta.async.future.Future;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;

@ -22,7 +22,7 @@ import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences; import org.floens.chan.core.preferences.ChanPreferences;
public class ThemeHelper { public class ThemeHelper {
public enum Theme { public enum Theme {

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/preference_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="horizontal"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:gravity="center_vertical">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<include layout="@layout/preference_description" />
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:id="@+id/switcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="16dp" />
</LinearLayout>

@ -0,0 +1,25 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:singleLine="true"
android:textColor="#ff000000"
android:textSize="16sp" />
<TextView
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:singleLine="true"
android:textColor="#89000000"
android:textSize="14sp" />
</merge>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#22000000" />

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:elevation="4dp"
android:background="#ffffffff"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<TextView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"
android:textSize="16sp"
android:textColor="#89000000" />
</LinearLayout>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/preference_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<include layout="@layout/preference_description" />
</LinearLayout>

@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
android:background="@color/primary" android:background="@color/primary"
android:elevation="8dp" /> android:elevation="4dp" />
<FrameLayout <FrameLayout
android:id="@+id/container" android:id="@+id/container"

@ -15,15 +15,15 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#ffffffff" android:background="#ffe5e5e5">
android:orientation="vertical">
<TextView <LinearLayout
android:id="@+id/scrollview_content"
android:orientation="vertical"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:text="Settings here" />
</LinearLayout> </ScrollView>

Loading…
Cancel
Save