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