diff --git a/Clover/app/proguard.cfg b/Clover/app/proguard.cfg
index 9c87b09f..810d3043 100644
--- a/Clover/app/proguard.cfg
+++ b/Clover/app/proguard.cfg
@@ -103,5 +103,6 @@
#-keep public class * extends android.support.design.**
-# Some reflection is used on RecyclerView
+# Some reflection is used on RecyclerView and SlidingPaneLayout
-keep public class android.support.v7.widget.RecyclerView
+-keep public class android.support.v4.widget.SlidingPaneLayout
diff --git a/Clover/app/src/main/java/org/floens/chan/controller/Controller.java b/Clover/app/src/main/java/org/floens/chan/controller/Controller.java
index 42f9853b..9dffa588 100644
--- a/Clover/app/src/main/java/org/floens/chan/controller/Controller.java
+++ b/Clover/app/src/main/java/org/floens/chan/controller/Controller.java
@@ -27,7 +27,7 @@ import android.view.ViewGroup;
import org.floens.chan.controller.transition.FadeInTransition;
import org.floens.chan.controller.transition.FadeOutTransition;
import org.floens.chan.ui.activity.StartActivity;
-import org.floens.chan.ui.controller.SplitNavigationController;
+import org.floens.chan.ui.controller.DoubleNavigationController;
import org.floens.chan.ui.toolbar.NavigationItem;
import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.Logger;
@@ -51,7 +51,7 @@ public abstract class Controller {
public Controller previousSiblingController;
public NavigationController navigationController;
- public SplitNavigationController splitNavigationController;
+ public DoubleNavigationController doubleNavigationController;
/**
* Controller that this controller is presented by.
@@ -127,7 +127,12 @@ public abstract class Controller {
public void addChildController(Controller controller) {
childControllers.add(controller);
controller.parentController = this;
- controller.splitNavigationController = splitNavigationController;
+ if (doubleNavigationController != null) {
+ controller.doubleNavigationController = doubleNavigationController;
+ }
+ if (navigationController != null) {
+ controller.navigationController = navigationController;
+ }
controller.onCreate();
}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java
index a0aa103c..4f3a35c3 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java
@@ -71,6 +71,7 @@ public class ChanSettings {
public enum LayoutMode implements OptionSettingItem {
AUTO("auto"),
PHONE("phone"),
+ SLIDE("slide"),
SPLIT("split");
String name;
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 fd1f80bc..39b9cbb3 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
@@ -44,9 +44,11 @@ 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.controller.BrowseController;
+import org.floens.chan.ui.controller.DoubleNavigationController;
import org.floens.chan.ui.controller.DrawerController;
import org.floens.chan.ui.controller.SplitNavigationController;
import org.floens.chan.ui.controller.StyledToolbarNavigationController;
+import org.floens.chan.ui.controller.ThreadSlideController;
import org.floens.chan.ui.controller.ViewThreadController;
import org.floens.chan.ui.helper.ImagePickDelegate;
import org.floens.chan.ui.helper.PreviousVersionHandler;
@@ -95,35 +97,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
drawerController.onCreate();
drawerController.onShow();
- StyledToolbarNavigationController toolbarNavigationController = new StyledToolbarNavigationController(this);
-
- ChanSettings.LayoutMode layoutMode = ChanSettings.layoutMode.get();
- if (layoutMode == ChanSettings.LayoutMode.AUTO) {
- if (AndroidUtils.isTablet(this)) {
- layoutMode = ChanSettings.LayoutMode.SPLIT;
- } else {
- layoutMode = ChanSettings.LayoutMode.PHONE;
- }
- }
-
- switch (layoutMode) {
- case SPLIT:
- SplitNavigationController splitNavigationController = new SplitNavigationController(this);
- splitNavigationController.setEmptyView((ViewGroup) LayoutInflater.from(this).inflate(R.layout.layout_split_empty, null));
-
- drawerController.setChildController(splitNavigationController);
-
- splitNavigationController.setLeftController(toolbarNavigationController);
- mainNavigationController = toolbarNavigationController;
- break;
- case PHONE:
- drawerController.setChildController(toolbarNavigationController);
- mainNavigationController = toolbarNavigationController;
- break;
- }
-
- browseController = new BrowseController(this);
- mainNavigationController.pushController(browseController, false);
+ setupLayout();
setContentView(drawerController.view);
addController(drawerController);
@@ -190,6 +164,45 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
previousVersionHandler.run(this);
}
+ private void setupLayout() {
+ mainNavigationController = new StyledToolbarNavigationController(this);
+
+ ChanSettings.LayoutMode layoutMode = ChanSettings.layoutMode.get();
+ if (layoutMode == ChanSettings.LayoutMode.AUTO) {
+ if (AndroidUtils.isTablet(this)) {
+ layoutMode = ChanSettings.LayoutMode.SPLIT;
+ } else {
+ layoutMode = ChanSettings.LayoutMode.PHONE;
+ }
+ }
+
+ switch (layoutMode) {
+ case SPLIT:
+ SplitNavigationController split = new SplitNavigationController(this);
+ split.setEmptyView((ViewGroup) LayoutInflater.from(this).inflate(R.layout.layout_split_empty, null));
+
+ drawerController.setChildController(split);
+
+ split.setLeftController(mainNavigationController);
+ break;
+ case PHONE:
+ case SLIDE:
+ drawerController.setChildController(mainNavigationController);
+ break;
+ }
+
+ browseController = new BrowseController(this);
+
+ if (layoutMode == ChanSettings.LayoutMode.SLIDE) {
+ ThreadSlideController slideController = new ThreadSlideController(this);
+ slideController.setEmptyView((ViewGroup) LayoutInflater.from(this).inflate(R.layout.layout_split_empty, null));
+ mainNavigationController.pushController(slideController, false);
+ slideController.setLeftController(browseController);
+ } else {
+ mainNavigationController.pushController(browseController, false);
+ }
+ }
+
public void restart() {
Intent intent = getIntent();
finish();
@@ -237,9 +250,9 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
Loadable thread = null;
if (drawerController.childControllers.get(0) instanceof SplitNavigationController) {
- SplitNavigationController splitNavigationController = (SplitNavigationController) drawerController.childControllers.get(0);
- if (splitNavigationController.rightController instanceof NavigationController) {
- NavigationController rightNavigationController = (NavigationController) splitNavigationController.rightController;
+ SplitNavigationController doubleNav = (SplitNavigationController) drawerController.childControllers.get(0);
+ if (doubleNav.getRightController() instanceof NavigationController) {
+ NavigationController rightNavigationController = (NavigationController) doubleNav.getRightController();
for (Controller controller : rightNavigationController.childControllers) {
if (controller instanceof ViewThreadController) {
thread = ((ViewThreadController) controller).getLoadable();
@@ -254,6 +267,12 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
if (controller instanceof ViewThreadController) {
thread = ((ViewThreadController) controller).getLoadable();
break;
+ } else if (controller instanceof ThreadSlideController) {
+ ThreadSlideController slideNav = (ThreadSlideController) controller;
+ if (slideNav.getRightController() instanceof ViewThreadController) {
+ thread = ((ViewThreadController) slideNav.getRightController()).getLoadable();
+ break;
+ }
}
}
}
@@ -270,7 +289,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
Controller threadController = null;
- if (drawerController.childControllers.get(0) instanceof SplitNavigationController) {
+ if (drawerController.childControllers.get(0) instanceof DoubleNavigationController) {
SplitNavigationController splitNavigationController = (SplitNavigationController) drawerController.childControllers.get(0);
if (splitNavigationController.rightController instanceof NavigationController) {
NavigationController rightNavigationController = (NavigationController) splitNavigationController.rightController;
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java
index 64ffa1b2..03b9b4b6 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java
@@ -168,7 +168,7 @@ public class AlbumDownloadController extends Controller implements ToolbarMenuIt
private void updateTitle() {
navigationItem.title = context.getString(R.string.album_download_screen, getCheckCount(), items.size());
- navigationItem.updateTitle();
+ ((ToolbarNavigationController) navigationController).toolbar.updateTitle(navigationItem);
}
private void updateAllChecked() {
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java
index c36a3c0a..41ef9068 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java
@@ -135,11 +135,21 @@ public class AlbumViewController extends Controller implements ImageViewerContro
@Override
public ImageViewerController.ImageViewerCallback goToPost(PostImage postImage) {
+ ThreadController threadController = null;
+
if (previousSiblingController instanceof ThreadController) {
- ThreadController sibling = (ThreadController) previousSiblingController;
- sibling.selectPostImage(postImage);
+ threadController = (ThreadController) previousSiblingController;
+ } else if (previousSiblingController instanceof DoubleNavigationController) {
+ DoubleNavigationController doubleNav = (DoubleNavigationController) previousSiblingController;
+ if (doubleNav.getRightController() instanceof ThreadController) {
+ threadController = (ThreadController) doubleNav.getRightController();
+ }
+ }
+
+ if (threadController != null) {
+ threadController.selectPostImage(postImage);
navigationController.popController(false);
- return sibling;
+ return threadController;
} else {
return null;
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java
index 6b1d040e..4c4377bc 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java
@@ -216,8 +216,8 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte
loadBoard(((FloatingMenuItemBoard) item).board);
} else {
BoardEditController boardEditController = new BoardEditController(context);
- if (splitNavigationController != null) {
- splitNavigationController.pushController(boardEditController);
+ if (doubleNavigationController != null) {
+ doubleNavigationController.pushController(boardEditController);
} else {
navigationController.pushController(boardEditController);
}
@@ -240,22 +240,55 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte
showThread(threadLoadable, true);
}
+ // Creates or updates the target ThreadViewController
+ // This controller can be in various places depending on the layout
+ // We dynamically search for it
public void showThread(Loadable threadLoadable, boolean animated) {
- if (splitNavigationController != null) {
- if (splitNavigationController.rightController instanceof StyledToolbarNavigationController) {
- StyledToolbarNavigationController navigationController = (StyledToolbarNavigationController) splitNavigationController.rightController;
+ // The target ThreadViewController is in a split nav
+ // (BrowseController -> ToolbarNavigationController -> SplitNavigationController)
+ SplitNavigationController splitNav = null;
+
+ // The target ThreadViewController is in a slide nav
+ // (BrowseController -> SlideController -> ToolbarNavigationController)
+ ThreadSlideController slideNav = null;
+
+ if (doubleNavigationController instanceof SplitNavigationController) {
+ splitNav = (SplitNavigationController) doubleNavigationController;
+ }
+
+ if (doubleNavigationController instanceof ThreadSlideController) {
+ slideNav = (ThreadSlideController) doubleNavigationController;
+ }
+
+ if (splitNav != null) {
+ // Create a threadview inside a toolbarnav in the right part of the split layout
+ if (splitNav.getRightController() instanceof StyledToolbarNavigationController) {
+ StyledToolbarNavigationController navigationController = (StyledToolbarNavigationController) splitNav.getRightController();
if (navigationController.getTop() instanceof ViewThreadController) {
((ViewThreadController) navigationController.getTop()).loadThread(threadLoadable);
}
} else {
StyledToolbarNavigationController navigationController = new StyledToolbarNavigationController(context);
- splitNavigationController.setRightController(navigationController);
+ splitNav.setRightController(navigationController);
ViewThreadController viewThreadController = new ViewThreadController(context);
viewThreadController.setLoadable(threadLoadable);
navigationController.pushController(viewThreadController, false);
}
+ splitNav.switchToController(false);
+ } else if (slideNav != null) {
+ // Create a threadview in the right part of the slide nav *without* a toolbar
+ if (slideNav.getRightController() instanceof ViewThreadController) {
+ ((ViewThreadController) slideNav.getRightController()).loadThread(threadLoadable);
+ } else {
+ ViewThreadController viewThreadController = new ViewThreadController(context);
+ viewThreadController.setLoadable(threadLoadable);
+ slideNav.setRightController(viewThreadController);
+ }
+ slideNav.switchToController(false);
} else {
+ // the target ThreadNav must be pushed to the parent nav controller
+ // (BrowseController -> ToolbarNavigationController)
ViewThreadController viewThreadController = new ViewThreadController(context);
viewThreadController.setLoadable(threadLoadable);
navigationController.pushController(viewThreadController, animated);
@@ -282,7 +315,7 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte
break;
}
}
- navigationItem.updateTitle();
+ ((ToolbarNavigationController) navigationController).toolbar.updateTitle(navigationItem);
}
private void loadBoards() {
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/DoubleNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/DoubleNavigationController.java
new file mode 100644
index 00000000..a711e927
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/DoubleNavigationController.java
@@ -0,0 +1,49 @@
+/*
+ * 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.view.ViewGroup;
+
+import org.floens.chan.controller.Controller;
+import org.floens.chan.controller.ControllerTransition;
+
+public interface DoubleNavigationController {
+ void setEmptyView(ViewGroup emptyView);
+
+ void setLeftController(Controller leftController);
+
+ void setRightController(Controller rightController);
+
+ Controller getLeftController();
+
+ Controller getRightController();
+
+ void switchToController(boolean leftController);
+
+ boolean pushController(Controller to);
+
+ boolean pushController(Controller to, boolean animated);
+
+ boolean pushController(Controller to, ControllerTransition controllerTransition);
+
+ boolean popController();
+
+ boolean popController(boolean animated);
+
+ boolean popController(ControllerTransition controllerTransition);
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java
index c4c367ce..91b9a59b 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java
@@ -120,7 +120,7 @@ public class DrawerController extends Controller implements PinAdapter.Callback,
}
public void onMenuClicked() {
- if (getStyledToolbarNavigationController().getTop().navigationItem.hasDrawer) {
+ if (getMainToolbarNavigationController().getTop().navigationItem.hasDrawer) {
drawerLayout.openDrawer(drawer);
}
}
@@ -138,12 +138,8 @@ public class DrawerController extends Controller implements PinAdapter.Callback,
@Override
public void onPinClicked(Pin pin) {
drawerLayout.closeDrawer(Gravity.LEFT);
-
- StyledToolbarNavigationController navigationController = getStyledToolbarNavigationController();
- if (navigationController.getTop() instanceof ThreadController) {
- ThreadController threadController = (ThreadController) navigationController.getTop();
- threadController.openPin(pin);
- }
+ ThreadController threadController = getTopThreadController();
+ threadController.openPin(pin);
}
@Override
@@ -277,7 +273,7 @@ public class DrawerController extends Controller implements PinAdapter.Callback,
}
if (getTop() != null) {
- getStyledToolbarNavigationController().toolbar.getArrowMenuDrawable().setBadge(count, color);
+ getMainToolbarNavigationController().toolbar.getArrowMenuDrawable().setBadge(count, color);
}
}
@@ -285,29 +281,45 @@ public class DrawerController extends Controller implements PinAdapter.Callback,
Controller top = getTop();
if (top instanceof NavigationController) {
((NavigationController) top).pushController(controller);
- } else if (top instanceof SplitNavigationController) {
- ((SplitNavigationController) top).pushController(controller);
+ } else if (top instanceof DoubleNavigationController) {
+ ((DoubleNavigationController) top).pushController(controller);
}
drawerLayout.closeDrawer(Gravity.LEFT);
}
- private StyledToolbarNavigationController getStyledToolbarNavigationController() {
- StyledToolbarNavigationController navigationController = null;
+ private ThreadController getTopThreadController() {
+ ToolbarNavigationController nav = getMainToolbarNavigationController();
+ if (nav.getTop() instanceof ThreadController) {
+ return (ThreadController) nav.getTop();
+ } else if (nav.getTop() instanceof ThreadSlideController) {
+ ThreadSlideController slideNav = (ThreadSlideController) nav.getTop();
+ if (slideNav.leftController instanceof ThreadController) {
+ return (ThreadController) slideNav.leftController;
+ }
+ }
+ throw new IllegalStateException();
+ }
+
+ private ToolbarNavigationController getMainToolbarNavigationController() {
+ ToolbarNavigationController navigationController = null;
Controller top = getTop();
if (top instanceof StyledToolbarNavigationController) {
navigationController = (StyledToolbarNavigationController) top;
} else if (top instanceof SplitNavigationController) {
- SplitNavigationController splitNavigationController = (SplitNavigationController) top;
- if (splitNavigationController.leftController instanceof StyledToolbarNavigationController) {
- navigationController = (StyledToolbarNavigationController) splitNavigationController.leftController;
+ SplitNavigationController splitNav = (SplitNavigationController) top;
+ if (splitNav.getLeftController() instanceof StyledToolbarNavigationController) {
+ navigationController = (StyledToolbarNavigationController) splitNav.getLeftController();
}
+ } else if (top instanceof ThreadSlideController) {
+ ThreadSlideController slideNav = (ThreadSlideController) top;
+ navigationController = (StyledToolbarNavigationController) slideNav.leftController;
}
if (navigationController == null) {
throw new IllegalStateException("The child controller of a DrawerController must either be StyledToolbarNavigationController" +
- "or an SplitNavigationController that has a StyledToolbarNavigationController.");
+ "or an DoubleNavigationController that has a ToolbarNavigationController.");
}
return navigationController;
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java
index 85104b2a..e08b8ed9 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java
@@ -173,6 +173,8 @@ public class ImageViewerController extends Controller implements ImageViewerPres
return false;
}
});
+ } else {
+ presenter.onExit();
}
break;
case SAVE_ID:
@@ -281,7 +283,7 @@ public class ImageViewerController extends Controller implements ImageViewerPres
navigationItem.title = postImage.filename + "." + postImage.extension;
}
navigationItem.subtitle = (index + 1) + "/" + count;
- navigationItem.updateTitle();
+ ((ToolbarNavigationController) navigationController).toolbar.updateTitle(navigationItem);
}
public void scrollToImage(PostImage postImage) {
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 80dc0c88..49742ba4 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
@@ -218,6 +218,9 @@ public class MainSettingsController extends SettingsController implements Toolba
case PHONE:
name = R.string.setting_layout_mode_phone;
break;
+ case SLIDE:
+ name = R.string.setting_layout_mode_slide;
+ break;
case SPLIT:
name = R.string.setting_layout_mode_split;
break;
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java
index 935153b2..86e10f5e 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java
@@ -55,7 +55,7 @@ public class PopupController extends Controller implements View.OnClickListener
}
public void dismiss() {
- if (presentingByController instanceof SplitNavigationController) {
+ if (presentingByController instanceof DoubleNavigationController) {
((SplitNavigationController) presentingByController).popAll();
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java
index 4ee4dcf1..788c6c12 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java
@@ -32,7 +32,7 @@ import org.floens.chan.ui.layout.SplitNavigationControllerLayout;
import static org.floens.chan.utils.AndroidUtils.getAttrColor;
-public class SplitNavigationController extends Controller {
+public class SplitNavigationController extends Controller implements DoubleNavigationController {
public Controller leftController;
public Controller rightController;
@@ -52,7 +52,7 @@ public class SplitNavigationController extends Controller {
public void onCreate() {
super.onCreate();
- splitNavigationController = this;
+ doubleNavigationController = this;
SplitNavigationControllerLayout container = new SplitNavigationControllerLayout(context);
view = container;
@@ -72,10 +72,12 @@ public class SplitNavigationController extends Controller {
setRightController(null);
}
+ @Override
public void setEmptyView(ViewGroup emptyView) {
this.emptyView = emptyView;
}
+ @Override
public void setLeftController(Controller leftController) {
if (this.leftController != null) {
this.leftController.onHide();
@@ -91,6 +93,7 @@ public class SplitNavigationController extends Controller {
}
}
+ @Override
public void setRightController(Controller rightController) {
if (this.rightController != null) {
this.rightController.onHide();
@@ -110,14 +113,32 @@ public class SplitNavigationController extends Controller {
}
}
+ @Override
+ public Controller getLeftController() {
+ return leftController;
+ }
+
+ @Override
+ public Controller getRightController() {
+ return rightController;
+ }
+
+ @Override
+ public void switchToController(boolean leftController) {
+ // both are always visible
+ }
+
+ @Override
public boolean pushController(final Controller to) {
return pushController(to, true);
}
+ @Override
public boolean pushController(final Controller to, boolean animated) {
return pushController(to, animated ? new PushControllerTransition() : null);
}
+ @Override
public boolean pushController(Controller to, ControllerTransition controllerTransition) {
if (popup == null) {
popup = new PopupController(context);
@@ -132,14 +153,17 @@ public class SplitNavigationController extends Controller {
return true;
}
+ @Override
public boolean popController() {
return popController(true);
}
+ @Override
public boolean popController(boolean animated) {
return popController(animated ? new PopControllerTransition() : null);
}
+ @Override
public boolean popController(ControllerTransition controllerTransition) {
if (popup != null) {
if (popupChild.childControllers.size() == 1) {
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java
index ffad563c..7da1965c 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java
@@ -87,9 +87,9 @@ public class StyledToolbarNavigationController extends ToolbarNavigationControll
} else if (parentController instanceof PopupController && childControllers.size() == 1) {
((PopupController) parentController).dismiss();
return true;
- } else if (splitNavigationController != null && childControllers.size() == 1) {
- if (splitNavigationController.rightController == this) {
- splitNavigationController.setRightController(null);
+ } else if (doubleNavigationController != null && childControllers.size() == 1) {
+ if (doubleNavigationController.getRightController() == this) {
+ doubleNavigationController.setRightController(null);
return true;
} else {
return false;
@@ -110,9 +110,10 @@ public class StyledToolbarNavigationController extends ToolbarNavigationControll
private DrawerController getDrawerController() {
if (parentController instanceof DrawerController) {
return (DrawerController) parentController;
- } else if (splitNavigationController != null) {
- if (splitNavigationController.parentController instanceof DrawerController) {
- return (DrawerController) splitNavigationController.parentController;
+ } else if (doubleNavigationController != null) {
+ Controller doubleNav = (Controller) doubleNavigationController;
+ if (doubleNav.parentController instanceof DrawerController) {
+ return (DrawerController) doubleNav.parentController;
}
}
return null;
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java
index 5c977eca..6403cb30 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java
@@ -36,10 +36,12 @@ import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostImage;
+import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.ui.helper.RefreshUIMessage;
import org.floens.chan.ui.layout.ThreadLayout;
import org.floens.chan.ui.toolbar.Toolbar;
import org.floens.chan.ui.view.ThumbnailView;
+import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.Logger;
import java.util.List;
@@ -64,7 +66,7 @@ public abstract class ThreadController extends Controller implements ThreadLayou
EventBus.getDefault().register(this);
- navigationItem.collapseToolbar = true;
+ navigationItem.handlesToolbarInset = true;
threadLayout = (ThreadLayout) LayoutInflater.from(context).inflate(R.layout.layout_thread, null);
threadLayout.setCallback(this);
@@ -79,7 +81,7 @@ public abstract class ThreadController extends Controller implements ThreadLayou
swipeRefreshLayout.setOnRefreshListener(this);
- if (navigationItem.collapseToolbar) {
+ if (navigationItem.handlesToolbarInset) {
int toolbarHeight = getToolbar().getToolbarHeight();
swipeRefreshLayout.setProgressViewOffset(false, toolbarHeight - dp(40), toolbarHeight + dp(64 - 40));
}
@@ -207,7 +209,12 @@ public abstract class ThreadController extends Controller implements ThreadLayou
if (threadLayout.getPresenter().getChanThread() != null) {
AlbumViewController albumViewController = new AlbumViewController(context);
albumViewController.setImages(getLoadable(), images, index, navigationItem.title);
- navigationController.pushController(albumViewController);
+
+ if (doubleNavigationController != null) {
+ doubleNavigationController.pushController(albumViewController);
+ } else {
+ navigationController.pushController(albumViewController);
+ }
}
}
@@ -222,7 +229,16 @@ public abstract class ThreadController extends Controller implements ThreadLayou
@Override
public Toolbar getToolbar() {
- return ((ToolbarNavigationController) navigationController).getToolbar();
+ if (navigationController instanceof ToolbarNavigationController) {
+ return ((ToolbarNavigationController) navigationController).getToolbar();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean shouldToolbarCollapse() {
+ return !AndroidUtils.isTablet(context) && !ChanSettings.neverHideToolbar.get();
}
@Override
@@ -238,8 +254,8 @@ public abstract class ThreadController extends Controller implements ThreadLayou
@Override
public void openFilterForTripcode(String tripcode) {
FiltersController filtersController = new FiltersController(context);
- if (splitNavigationController != null) {
- splitNavigationController.pushController(filtersController);
+ if (doubleNavigationController != null) {
+ doubleNavigationController.pushController(filtersController);
} else {
navigationController.pushController(filtersController);
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadSlideController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadSlideController.java
new file mode 100644
index 00000000..4fee6eb4
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadSlideController.java
@@ -0,0 +1,281 @@
+/*
+ * 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.v4.widget.SlidingPaneLayout;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.floens.chan.R;
+import org.floens.chan.controller.Controller;
+import org.floens.chan.controller.ControllerTransition;
+import org.floens.chan.ui.layout.ThreadSlidingPaneLayout;
+import org.floens.chan.ui.toolbar.NavigationItem;
+import org.floens.chan.ui.toolbar.Toolbar;
+import org.floens.chan.utils.Logger;
+
+import java.lang.reflect.Field;
+
+import static org.floens.chan.utils.AndroidUtils.dp;
+import static org.floens.chan.utils.AndroidUtils.getAttrColor;
+
+public class ThreadSlideController extends Controller implements DoubleNavigationController, SlidingPaneLayout.PanelSlideListener, ToolbarNavigationController.ToolbarSearchCallback {
+ private static final String TAG = "ThreadSlideController";
+
+ public Controller leftController;
+ public Controller rightController;
+
+ private boolean leftOpen = true;
+ private ViewGroup emptyView;
+ private ThreadSlidingPaneLayout slidingPaneLayout;
+
+ public ThreadSlideController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ doubleNavigationController = this;
+
+ navigationItem.swipeable = false;
+ navigationItem.handlesToolbarInset = true;
+ navigationItem.hasDrawer = true;
+
+ view = inflateRes(R.layout.controller_thread_slide);
+
+ slidingPaneLayout = (ThreadSlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
+ slidingPaneLayout.setThreadSlideController(this);
+ slidingPaneLayout.setPanelSlideListener(this);
+ slidingPaneLayout.setParallaxDistance(dp(100));
+ slidingPaneLayout.setShadowResourceLeft(R.drawable.panel_shadow);
+ int fadeColor = (getAttrColor(context, R.attr.backcolor) & 0xffffff) + 0xCC000000;
+ slidingPaneLayout.setSliderFadeColor(fadeColor);
+ slidingPaneLayout.openPane();
+
+ setLeftController(null);
+ setRightController(null);
+ }
+
+ public void onSlidingPaneLayoutStateRestored() {
+ // SlidingPaneLayout does some annoying things for state restoring and incorrectly
+ // tells us if the restored state was open or closed
+ // We need to use reflection to get the private field that stores this correct state
+ boolean restoredOpen = false;
+ try {
+ Field field = SlidingPaneLayout.class.getDeclaredField("mPreservedOpenState");
+ field.setAccessible(true);
+ restoredOpen = field.getBoolean(slidingPaneLayout);
+ } catch (Exception e) {
+ Logger.e(TAG, "Error getting restored open state with reflection", e);
+ }
+ if (restoredOpen != leftOpen) {
+ leftOpen = restoredOpen;
+ slideStateChanged(leftOpen);
+ }
+ }
+
+ @Override
+ public void onPanelSlide(View panel, float slideOffset) {
+ }
+
+ @Override
+ public void onPanelOpened(View panel) {
+ if (this.leftOpen != leftOpen()) {
+ this.leftOpen = leftOpen();
+ slideStateChanged(leftOpen());
+ }
+ }
+
+ @Override
+ public void onPanelClosed(View panel) {
+ if (this.leftOpen != leftOpen()) {
+ this.leftOpen = leftOpen();
+ slideStateChanged(leftOpen());
+ }
+ }
+
+ @Override
+ public void switchToController(boolean leftController) {
+ if (leftController != leftOpen()) {
+ if (leftController) {
+ slidingPaneLayout.openPane();
+ } else {
+ slidingPaneLayout.closePane();
+ }
+ Toolbar toolbar = ((ToolbarNavigationController) navigationController).toolbar;
+ toolbar.processScrollCollapse(Toolbar.TOOLBAR_COLLAPSE_SHOW, true);
+ }
+ }
+
+ @Override
+ public void setEmptyView(ViewGroup emptyView) {
+ this.emptyView = emptyView;
+ }
+
+ public void setLeftController(Controller leftController) {
+ if (this.leftController != null) {
+ this.leftController.onHide();
+ removeChildController(this.leftController);
+ }
+
+ this.leftController = leftController;
+
+ if (leftController != null) {
+ addChildController(leftController);
+ leftController.attachToParentView(slidingPaneLayout.leftPane);
+ leftController.onShow();
+ if (leftOpen()) {
+ setParentNavigationItem(true);
+ }
+ }
+ }
+
+ public void setRightController(Controller rightController) {
+ if (this.rightController != null) {
+ this.rightController.onHide();
+ removeChildController(this.rightController);
+ } else {
+ this.slidingPaneLayout.rightPane.removeAllViews();
+ }
+
+ this.rightController = rightController;
+
+ if (rightController != null) {
+ addChildController(rightController);
+ rightController.attachToParentView(slidingPaneLayout.rightPane);
+ rightController.onShow();
+ if (!leftOpen()) {
+ setParentNavigationItem(false);
+ }
+ } else {
+ slidingPaneLayout.rightPane.addView(emptyView);
+ }
+ }
+
+ @Override
+ public Controller getLeftController() {
+ return leftController;
+ }
+
+ @Override
+ public Controller getRightController() {
+ return rightController;
+ }
+
+ @Override
+ public boolean pushController(Controller to) {
+ return navigationController.pushController(to);
+ }
+
+ @Override
+ public boolean pushController(Controller to, boolean animated) {
+ return navigationController.pushController(to, animated);
+ }
+
+ @Override
+ public boolean pushController(Controller to, ControllerTransition controllerTransition) {
+ return navigationController.pushController(to, controllerTransition);
+ }
+
+ @Override
+ public boolean popController() {
+ return navigationController.popController();
+ }
+
+ @Override
+ public boolean popController(boolean animated) {
+ return navigationController.popController(animated);
+ }
+
+ @Override
+ public boolean popController(ControllerTransition controllerTransition) {
+ return navigationController.popController(controllerTransition);
+ }
+
+ @Override
+ public boolean onBack() {
+ if (!leftOpen()) {
+ if (rightController != null && rightController.onBack()) {
+ return true;
+ } else {
+ switchToController(true);
+ return true;
+ }
+ } else {
+ if (leftController != null && leftController.onBack()) {
+ return true;
+ }
+ }
+
+ return super.onBack();
+ }
+
+ @Override
+ public void onSearchVisibilityChanged(boolean visible) {
+ if (leftOpen() && leftController != null && leftController instanceof ToolbarNavigationController.ToolbarSearchCallback) {
+ ((ToolbarNavigationController.ToolbarSearchCallback) leftController).onSearchVisibilityChanged(visible);
+ }
+ if (!leftOpen() && rightController != null && rightController instanceof ToolbarNavigationController.ToolbarSearchCallback) {
+ ((ToolbarNavigationController.ToolbarSearchCallback) rightController).onSearchVisibilityChanged(visible);
+ }
+ }
+
+ @Override
+ public void onSearchEntered(String entered) {
+ if (leftOpen() && leftController != null && leftController instanceof ToolbarNavigationController.ToolbarSearchCallback) {
+ ((ToolbarNavigationController.ToolbarSearchCallback) leftController).onSearchEntered(entered);
+ }
+ if (!leftOpen() && rightController != null && rightController instanceof ToolbarNavigationController.ToolbarSearchCallback) {
+ ((ToolbarNavigationController.ToolbarSearchCallback) rightController).onSearchEntered(entered);
+ }
+ }
+
+ private boolean leftOpen() {
+ return slidingPaneLayout.isOpen();
+ }
+
+ private void slideStateChanged(boolean leftOpen) {
+ setParentNavigationItem(leftOpen);
+ }
+
+ private void setParentNavigationItem(boolean left) {
+ Toolbar toolbar = ((ToolbarNavigationController) navigationController).toolbar;
+
+ NavigationItem item = null;
+ if (left) {
+ if (leftController != null) {
+ item = leftController.navigationItem;
+ }
+ } else {
+ if (rightController != null) {
+ item = rightController.navigationItem;
+ }
+ }
+
+ if (item != null) {
+ navigationItem = item;
+ navigationItem.swipeable = false;
+ navigationItem.handlesToolbarInset = true;
+ navigationItem.hasDrawer = true;
+ toolbar.setNavigationItem(false, true, navigationItem);
+ }
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java
index ec2b4a64..9ac14bcd 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java
@@ -123,7 +123,7 @@ public abstract class ToolbarNavigationController extends NavigationController i
}
protected void updateToolbarCollapse(Controller controller, boolean animate) {
- if (!controller.navigationItem.collapseToolbar) {
+ if (!controller.navigationItem.handlesToolbarInset) {
FrameLayout.LayoutParams toViewParams = (FrameLayout.LayoutParams) controller.view.getLayoutParams();
toViewParams.topMargin = toolbar.getToolbarHeight();
controller.view.setLayoutParams(toViewParams);
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java
index 1dafed3b..71c773c3 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java
@@ -145,7 +145,7 @@ public class ViewThreadController extends ThreadController implements ThreadLayo
presenter.bindLoadable(loadable);
this.loadable = presenter.getLoadable();
navigationItem.title = loadable.title;
- navigationItem.updateTitle();
+ ((ToolbarNavigationController) navigationController).toolbar.updateTitle(navigationItem);
setPinIconState(presenter.isPinned());
updateDrawerHighlighting(loadable);
updateLeftPaneHighlighting(loadable);
@@ -165,7 +165,7 @@ public class ViewThreadController extends ThreadController implements ThreadLayo
super.onShowPosts();
navigationItem.title = loadable.title;
- navigationItem.updateTitle();
+ ((ToolbarNavigationController) navigationController).toolbar.updateTitle(navigationItem);
}
@Override
@@ -221,27 +221,31 @@ public class ViewThreadController extends ThreadController implements ThreadLayo
if (navigationController.parentController instanceof DrawerController) {
((DrawerController) navigationController.parentController).setPinHighlighted(pin);
- } else if (splitNavigationController != null) {
- if (splitNavigationController.parentController instanceof DrawerController) {
- ((DrawerController) splitNavigationController.parentController).setPinHighlighted(pin);
+ } else if (doubleNavigationController != null) {
+ Controller doubleNav = (Controller) doubleNavigationController;
+ if (doubleNav.parentController instanceof DrawerController) {
+ ((DrawerController) doubleNav.parentController).setPinHighlighted(pin);
}
}
}
private void updateLeftPaneHighlighting(Loadable loadable) {
- if (splitNavigationController != null) {
- if (splitNavigationController.leftController instanceof NavigationController) {
- NavigationController leftNavigationController = (NavigationController) splitNavigationController.leftController;
- ThreadController threadController = null;
+ if (doubleNavigationController != null) {
+ ThreadController threadController = null;
+ Controller leftController = doubleNavigationController.getLeftController();
+ if (leftController instanceof ThreadController) {
+ threadController = (ThreadController) leftController;
+ } else if (leftController instanceof NavigationController) {
+ NavigationController leftNavigationController = (NavigationController) leftController;
for (Controller controller : leftNavigationController.childControllers) {
if (controller instanceof ThreadController) {
threadController = (ThreadController) controller;
break;
}
}
- if (threadController != null) {
- threadController.selectPost(loadable != null ? loadable.no : -1);
- }
+ }
+ if (threadController != null) {
+ threadController.selectPost(loadable != null ? loadable.no : -1);
}
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
index 535859b7..48fcb578 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
@@ -201,6 +201,11 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
return callback.getToolbar();
}
+ @Override
+ public boolean shouldToolbarCollapse() {
+ return callback.shouldToolbarCollapse();
+ }
+
@Override
public void showPosts(ChanThread thread, PostsFilter filter) {
threadListLayout.showPosts(thread, filter, visible != Visible.THREAD);
@@ -565,6 +570,8 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
Toolbar getToolbar();
+ boolean shouldToolbarCollapse();
+
void openFilterForTripcode(String tripcode);
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java
index 93d1106e..389df6e4 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java
@@ -454,7 +454,7 @@ public class ThreadListLayout extends FrameLayout implements ReplyLayout.ReplyLa
}
private void attachToolbarScroll(boolean attach) {
- if (!AndroidUtils.isTablet(getContext()) && !ChanSettings.neverHideToolbar.get()) {
+ if (threadListLayoutCallback.shouldToolbarCollapse()) {
Toolbar toolbar = threadListLayoutCallback.getToolbar();
if (attach) {
toolbar.attachRecyclerViewScrollStateListener(recyclerView);
@@ -537,5 +537,7 @@ public class ThreadListLayout extends FrameLayout implements ReplyLayout.ReplyLa
void replyLayoutOpen(boolean open);
Toolbar getToolbar();
+
+ boolean shouldToolbarCollapse();
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadSlidingPaneLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadSlidingPaneLayout.java
new file mode 100644
index 00000000..69758f3c
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadSlidingPaneLayout.java
@@ -0,0 +1,88 @@
+/*
+ * 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.layout;
+
+import android.content.Context;
+import android.os.Parcelable;
+import android.support.v4.widget.SlidingPaneLayout;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+
+import org.floens.chan.R;
+import org.floens.chan.ui.controller.ThreadSlideController;
+
+import static org.floens.chan.utils.AndroidUtils.dp;
+
+public class ThreadSlidingPaneLayout extends SlidingPaneLayout {
+ public ViewGroup leftPane;
+ public ViewGroup rightPane;
+
+ private ThreadSlideController threadSlideController;
+
+ public ThreadSlidingPaneLayout(Context context) {
+ this(context, null);
+ }
+
+ public ThreadSlidingPaneLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ThreadSlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ leftPane = (ViewGroup) findViewById(R.id.left_pane);
+ rightPane = (ViewGroup) findViewById(R.id.right_pane);
+ }
+
+ public void setThreadSlideController(ThreadSlideController threadSlideController) {
+ this.threadSlideController = threadSlideController;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ super.onRestoreInstanceState(state);
+ if (threadSlideController != null) {
+ threadSlideController.onSlidingPaneLayoutStateRestored();
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+
+ ViewGroup.LayoutParams leftParams = leftPane.getLayoutParams();
+ ViewGroup.LayoutParams rightParams = rightPane.getLayoutParams();
+
+ if (width < dp(400)) {
+ leftParams.width = width - dp(30);
+ rightParams.width = width;
+ } else {
+ leftParams.width = width - dp(60);
+ rightParams.width = width;
+ }
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+}
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 fb86a8f9..8f538bbe 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
@@ -19,7 +19,6 @@ package org.floens.chan.ui.toolbar;
import android.content.Context;
import android.view.View;
-import android.widget.LinearLayout;
import org.floens.chan.ui.view.FloatingMenu;
import org.floens.chan.ui.view.FloatingMenuItem;
@@ -36,13 +35,11 @@ public class NavigationItem {
public FloatingMenu middleMenu;
public View rightView;
public boolean hasDrawer = false;
- public boolean collapseToolbar = false;
+ public boolean handlesToolbarInset = false;
public boolean swipeable = true;
boolean search = false;
String searchText;
- Toolbar toolbar;
- LinearLayout view;
public ToolbarMenuItem createOverflow(Context context, ToolbarMenuItem.ToolbarMenuItemCallback callback, List items) {
ToolbarMenuItem overflow = menu.createOverflow(callback);
@@ -51,12 +48,6 @@ public class NavigationItem {
return overflow;
}
- public void updateTitle() {
- if (toolbar != null) {
- 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 d5341327..c072defd 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
@@ -30,6 +30,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
@@ -51,6 +52,7 @@ import java.util.List;
import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getAttrColor;
+import static org.floens.chan.utils.AndroidUtils.removeFromParentView;
import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground;
public class Toolbar extends LinearLayout implements View.OnClickListener {
@@ -90,7 +92,9 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
private boolean transitioning = false;
private NavigationItem fromItem;
+ private LinearLayout fromView;
private NavigationItem toItem;
+ private LinearLayout toView;
public Toolbar(Context context) {
super(context);
@@ -107,6 +111,11 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
init();
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ return transitioning || super.dispatchTouchEvent(ev);
+ }
+
public int getToolbarHeight() {
return getHeight() == 0 ? getLayoutParams().height : getHeight();
}
@@ -189,7 +198,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
attachNavigationItem(newItem);
- navigationItemContainer.addView(toItem.view, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ navigationItemContainer.addView(toView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
transitioning = true;
}
@@ -203,12 +212,12 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
final int offset = dp(16);
- toItem.view.setTranslationY((pushing ? offset : -offset) * (1f - progress));
- toItem.view.setAlpha(progress);
+ toView.setTranslationY((pushing ? offset : -offset) * (1f - progress));
+ toView.setAlpha(progress);
if (fromItem != null) {
- fromItem.view.setTranslationY((pushing ? -offset : offset) * progress);
- fromItem.view.setAlpha(1f - progress);
+ fromView.setTranslationY((pushing ? -offset : offset) * progress);
+ fromView.setAlpha(1f - progress);
}
float arrowEnd = toItem.hasBack || toItem.search ? 1f : 0f;
@@ -226,17 +235,20 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
if (fromItem != null) {
// From a search otherwise
if (fromItem != toItem) {
- removeNavigationItem(fromItem);
+ removeNavigationItem(fromItem, fromView);
+ fromView = null;
}
}
setArrowMenuProgress(toItem.hasBack || toItem.search ? 1f : 0f);
} else {
- removeNavigationItem(toItem);
+ removeNavigationItem(toItem, toView);
setArrowMenuProgress(fromItem.hasBack || fromItem.search ? 1f : 0f);
toItem = fromItem;
+ toView = fromView;
}
fromItem = null;
+ fromView = null;
transitioning = false;
}
@@ -259,15 +271,16 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
return arrowMenuDrawable;
}
- void setTitle(NavigationItem navigationItem) {
- if (navigationItem.view != null) {
- TextView titleView = (TextView) navigationItem.view.findViewById(R.id.title);
+ public void updateTitle(NavigationItem navigationItem) {
+ LinearLayout view = navigationItem == fromItem ? fromView : (navigationItem == toItem ? toView : null);
+ if (view != null) {
+ TextView titleView = (TextView) view.findViewById(R.id.title);
if (titleView != null) {
titleView.setText(navigationItem.title);
}
if (!TextUtils.isEmpty(navigationItem.subtitle)) {
- TextView subtitleView = (TextView) navigationItem.view.findViewById(R.id.subtitle);
+ TextView subtitleView = (TextView) view.findViewById(R.id.subtitle);
if (subtitleView != null) {
subtitleView.setText(navigationItem.subtitle);
}
@@ -344,14 +357,14 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
navigationItemContainer.setListener(null);
}
});
- navigationItemContainer.setView(toItem.view, animate);
+ navigationItemContainer.setView(toView, animate);
animateArrow(toItem.hasBack || toItem.search);
} else {
- navigationItemContainer.addView(toItem.view, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ navigationItemContainer.addView(toView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
if (animate) {
- toItem.view.setAlpha(0f);
+ toView.setAlpha(0f);
ValueAnimator animator = ObjectAnimator.ofFloat(0f, 1f);
animator.setDuration(300);
@@ -385,25 +398,22 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
}
fromItem = toItem;
+ fromView = toView;
toItem = newItem;
+ toView = createNavigationItemView(toItem);
if (!toItem.search) {
AndroidUtils.hideKeyboard(navigationItemContainer);
}
-
- toItem.toolbar = this;
- toItem.view = createNavigationItemView(toItem);
}
- private void removeNavigationItem(NavigationItem item) {
+ private void removeNavigationItem(NavigationItem item, LinearLayout view) {
if (!transitioning) {
throw new IllegalStateException("removeNavigationItem called while not transitioning");
}
- item.view.removeAllViews();
- navigationItemContainer.removeView(item.view);
- item.view = null;
- item.toolbar = null;
+ view.removeAllViews();
+ navigationItemContainer.removeView(view);
}
private LinearLayout createNavigationItemView(final NavigationItem item) {
@@ -471,11 +481,13 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
}
if (item.rightView != null) {
+ removeFromParentView(item.rightView);
item.rightView.setPadding(0, 0, dp(16), 0);
menu.addView(item.rightView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
}
if (item.menu != null) {
+ removeFromParentView(item.menu);
menu.addView(item.menu, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
}
diff --git a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java
index 6c5d70ff..f8ef0b6e 100644
--- a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java
+++ b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java
@@ -17,7 +17,6 @@
*/
package org.floens.chan.utils;
-import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
@@ -45,7 +44,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
-import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;
@@ -319,7 +317,7 @@ public class AndroidUtils {
if (usingViewTreeObserver.isAlive()) {
usingViewTreeObserver.removeOnPreDrawListener(this);
} else {
- Logger.w(TAG, "ViewTreeObserver not alive, could not remove onPreDrawListener! This will probably not end well");
+ Logger.e(TAG, "ViewTreeObserver not alive, could not remove onPreDrawListener! This will probably not end well");
}
boolean ret;
@@ -331,7 +329,7 @@ public class AndroidUtils {
}
if (!ret) {
- Logger.w(TAG, "waitForLayout requested a re-layout by returning false");
+ Logger.d(TAG, "waitForLayout requested a re-layout by returning false");
}
return ret;
diff --git a/Clover/app/src/main/res/drawable-hdpi/panel_shadow.9.png b/Clover/app/src/main/res/drawable-hdpi/panel_shadow.9.png
new file mode 100644
index 00000000..19ae6630
Binary files /dev/null and b/Clover/app/src/main/res/drawable-hdpi/panel_shadow.9.png differ
diff --git a/Clover/app/src/main/res/drawable-mdpi/panel_shadow.9.png b/Clover/app/src/main/res/drawable-mdpi/panel_shadow.9.png
new file mode 100644
index 00000000..e104117f
Binary files /dev/null and b/Clover/app/src/main/res/drawable-mdpi/panel_shadow.9.png differ
diff --git a/Clover/app/src/main/res/drawable-xhdpi/panel_shadow.9.png b/Clover/app/src/main/res/drawable-xhdpi/panel_shadow.9.png
new file mode 100644
index 00000000..a702c667
Binary files /dev/null and b/Clover/app/src/main/res/drawable-xhdpi/panel_shadow.9.png differ
diff --git a/Clover/app/src/main/res/drawable-xxhdpi/panel_shadow.9.png b/Clover/app/src/main/res/drawable-xxhdpi/panel_shadow.9.png
new file mode 100644
index 00000000..82091c3b
Binary files /dev/null and b/Clover/app/src/main/res/drawable-xxhdpi/panel_shadow.9.png differ
diff --git a/Clover/app/src/main/res/layout/controller_thread_slide.xml b/Clover/app/src/main/res/layout/controller_thread_slide.xml
new file mode 100644
index 00000000..be45958c
--- /dev/null
+++ b/Clover/app/src/main/res/layout/controller_thread_slide.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml
index 8cb0818b..d70c0826 100644
--- a/Clover/app/src/main/res/values/strings.xml
+++ b/Clover/app/src/main/res/values/strings.xml
@@ -358,6 +358,7 @@ along with this program. If not, see .
Layout mode
Auto
Phone layout
+ Slide mode
Split mode
Font size
(default)