mirror of https://github.com/kurisufriend/Clover
parent
f9fe6026d1
commit
ef9b1c3392
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
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); |
||||
} |
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
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); |
||||
} |
||||
} |
||||
} |
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
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); |
||||
} |
||||
} |
After Width: | Height: | Size: 111 B |
After Width: | Height: | Size: 100 B |
After Width: | Height: | Size: 119 B |
After Width: | Height: | Size: 144 B |
@ -0,0 +1,34 @@ |
||||
<?xml version="1.0" encoding="utf-8"?><!-- |
||||
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/>. |
||||
--> |
||||
<org.floens.chan.ui.layout.ThreadSlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:id="@+id/sliding_pane_layout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="?backcolor"> |
||||
|
||||
<FrameLayout |
||||
android:id="@+id/left_pane" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
<FrameLayout |
||||
android:id="@+id/right_pane" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
</org.floens.chan.ui.layout.ThreadSlidingPaneLayout> |
Loading…
Reference in new issue