1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-06 03:50:19 +02:00

Merge branch '2.6' into 2.6-kindle

This commit is contained in:
Nikolay Pultsin 2015-08-22 14:45:41 +01:00
commit 31ad7c3a1e
47 changed files with 1185 additions and 74 deletions

View file

@ -2,8 +2,8 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="org.geometerplus.zlibrary.ui.android"
android:versionCode="2050520"
android:versionName="2.5.5-kindlehd"
android:versionCode="2055520"
android:versionName="2.6 beta 5"
android:installLocation="auto"
>
<uses-sdk
@ -229,6 +229,10 @@
<action android:name="android.fbreader.action.LIBRARY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.fbreader.action.EXTERNAL_INTERNAL_LIBRARY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.TOCActivity" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.preferences.PreferenceActivity" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize" android:process=":preferences">
@ -242,6 +246,7 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.preferences.menu.ConfigurationActivity" android:process=":preferences" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize" android:exported="false"/>
<activity android:name="org.geometerplus.android.fbreader.preferences.EditBookInfoActivity" android:process=":library" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.sync.MissingBookActivity" android:process=":networkLibrary" android:theme="@style/FBReader.Dialog" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.network.BookDownloader" android:process=":networkLibrary" android:theme="@android:style/Theme.NoDisplay">
@ -375,6 +380,17 @@
<activity android:name="org.geometerplus.android.util.FolderListDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<activity android:name="org.geometerplus.android.util.EditTagsDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<activity android:name="org.geometerplus.android.util.EditAuthorsDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<receiver android:name="org.geometerplus.android.fbreader.widget.simple.Provider" android:label="FBReader widget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_simple"/>
</receiver>
<activity android:name="org.geometerplus.android.fbreader.widget.simple.ConfigurationActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog.NoTitle" android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<service android:name="com.yotadevices.fbreader.FBReaderYotaService" android:exported="false" android:launchMode="singleTask"/>
<uses-library android:required="false" android:name="com.yotadevices.platinum"/>
<meta-data android:name="com.yotadevices.BS_ICON" android:resource="@drawable/fbreader_bs_icon"/>

View file

@ -229,6 +229,10 @@
<action android:name="android.fbreader.action.LIBRARY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.fbreader.action.EXTERNAL_INTERNAL_LIBRARY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.TOCActivity" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.preferences.PreferenceActivity" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize" android:process=":preferences">
@ -242,6 +246,7 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.preferences.menu.ConfigurationActivity" android:process=":preferences" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize" android:exported="false"/>
<activity android:name="org.geometerplus.android.fbreader.preferences.EditBookInfoActivity" android:process=":library" android:theme="@style/FBReader.Activity" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.sync.MissingBookActivity" android:process=":networkLibrary" android:theme="@style/FBReader.Dialog" android:configChanges="orientation|keyboardHidden|screenSize"/>
<activity android:name="org.geometerplus.android.fbreader.network.BookDownloader" android:process=":networkLibrary" android:theme="@android:style/Theme.NoDisplay">
@ -375,6 +380,17 @@
<activity android:name="org.geometerplus.android.util.FolderListDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<activity android:name="org.geometerplus.android.util.EditTagsDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<activity android:name="org.geometerplus.android.util.EditAuthorsDialogActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog" android:exported="false"/>
<receiver android:name="org.geometerplus.android.fbreader.widget.simple.Provider" android:label="FBReader widget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_simple"/>
</receiver>
<activity android:name="org.geometerplus.android.fbreader.widget.simple.ConfigurationActivity" android:configChanges="orientation|screenSize|keyboard|keyboardHidden" android:theme="@style/FBReader.Dialog.NoTitle" android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<service android:name="com.yotadevices.fbreader.FBReaderYotaService" android:exported="false" android:launchMode="singleTask"/>
<uses-library android:required="false" android:name="com.yotadevices.platinum"/>
<meta-data android:name="com.yotadevices.BS_ICON" android:resource="@drawable/fbreader_bs_icon"/>

View file

@ -8,6 +8,7 @@
* Customisable main menu
* New (material design style) icon
* Simple widgets
* More brightness levels
===== 2.5.5 (Aug 14, 2015) =====
* Compatibility with new versions of LEO dictionary

View file

@ -1 +1 @@
2.5.5
2.6 beta 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:layout_marginTop="10dp"
>
<ImageView
android:id="@+id/icon_checkbox_icon"
android:minWidth="60dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentTop="true"
/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/icon_checkbox_icon"
android:layout_marginTop="7dp"
>
<CheckBox
android:id="@+id/icon_checkbox_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:focusable="false"
android:clickable="false"
/>
</RelativeLayout>
</RelativeLayout>

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
>
<CheckBox
android:id="@+id/menu_configure_item_checkbox"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text=""
android:gravity="center|center_vertical"
/>
<ImageView
android:id="@+id/menu_configure_item_icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:adjustViewBounds="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
/>
<TextView
android:id="@+id/menu_configure_item_title"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:layout_marginLeft="5dp"
android:layout_marginRight="35dp"
android:gravity="center_vertical"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<ImageView
android:id="@+id/menu_configure_item_drag_icon"
android:src="@drawable/drag_icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
/>
</RelativeLayout>
</LinearLayout>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="6dp"
android:paddingBottom="6dp"
>
<TextView
android:id="@+id/menu_configure_section_head_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
/>
</LinearLayout>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mobeta.android.dslv.DragSortListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dslv="http://schemas.android.com/apk/res-auto"
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="3dp"
android:choiceMode="multipleChoice"
android:dividerHeight="1px"
android:padding="3dp"
dslv:collapsed_height="1px"
dslv:drag_enabled="true"
dslv:drag_handle_id="@id/menu_configure_item_drag_icon"
dslv:drag_scroll_start="0.33"
dslv:drag_start_mode="onDown"
dslv:float_alpha="0.6"
dslv:slide_shuffle_speed="0.3"
/>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_simple"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/fbreader"
/>

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp"
>
<TextView
android:id="@+id/widget_simple_config_icon_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<include
layout="@layout/icon_checkbox"
android:id="@+id/widget_simple_config_fbreader"
/>
<include
layout="@layout/icon_checkbox"
android:id="@+id/widget_simple_config_classic"
/>
<include
layout="@layout/icon_checkbox"
android:id="@+id/widget_simple_config_library"
/>
<include
layout="@layout/icon_checkbox"
android:id="@+id/widget_simple_config_library_old"
/>
</LinearLayout>
<TextView
android:id="@+id/widget_simple_config_action_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:paddingTop="12dp"
/>
<Spinner
android:id="@+id/widget_simple_config_actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:spinnerMode="dropdown"
/>
<include
layout="@layout/ok_cancel_buttons"
android:id="@+id/widget_simple_config_buttons"
android:paddingTop="12dp"
/>
</LinearLayout>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">0dp</dimen>
</resources>

4
res/values/dimens.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="widget_margin">8dp</dimen>
</resources>

View file

@ -5,6 +5,9 @@
</style>
<style name="FBReader.Dialog" parent="android:Theme.Dialog">
</style>
<style name="FBReader.Dialog.NoTitle" parent="FBReader.Dialog">
<item name="android:windowNoTitle">true</item>
</style>
<style name="FBReader.Transparent" parent="android:Theme.Translucent.NoTitleBar">
<item name="android:windowBackground">@android:color/transparent</item>
</style>

12
res/xml/widget_simple.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/fbreader"
android:initialLayout="@layout/widget_simple"
android:resizeMode="none"
android:widgetCategory="home_screen"
android:configure="org.geometerplus.android.fbreader.widget.simple.ConfigurationActivity"
/>

View file

@ -235,6 +235,7 @@ public final class FBReader extends FBReaderMainActivity implements ZLApplicatio
config.requestAllValuesForGroup("Fonts");
config.requestAllValuesForGroup("Colors");
config.requestAllValuesForGroup("Files");
config.requestAllValuesForGroup("MainMenu");
}
});
@ -539,7 +540,7 @@ public final class FBReader extends FBReaderMainActivity implements ZLApplicatio
final int brightnessLevel =
getZLibrary().ScreenBrightnessLevelOption.getValue();
if (brightnessLevel != 0) {
setScreenBrightness(brightnessLevel);
getViewWidget().setScreenBrightness(brightnessLevel);
} else {
setScreenBrightnessAuto();
}
@ -976,29 +977,6 @@ public final class FBReader extends FBReaderMainActivity implements ZLApplicatio
}
};
private void setScreenBrightnessAuto() {
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.screenBrightness = -1.0f;
getWindow().setAttributes(attrs);
}
public void setScreenBrightness(int percent) {
if (percent < 1) {
percent = 1;
} else if (percent > 100) {
percent = 100;
}
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.screenBrightness = percent / 100.0f;
getWindow().setAttributes(attrs);
getZLibrary().ScreenBrightnessLevelOption.setValue(percent);
}
public int getScreenBrightness() {
final int level = (int)(100 * getWindow().getAttributes().screenBrightness);
return (level >= 0) ? level : 50;
}
private BookCollectionShadow getCollection() {
return (BookCollectionShadow)myFBReaderApp.Collection;
}

View file

@ -22,6 +22,7 @@ package org.geometerplus.android.fbreader;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.WindowManager;
import com.github.johnpersano.supertoasts.SuperActivityToast;
@ -61,6 +62,31 @@ public abstract class FBReaderMainActivity extends Activity {
return FBReaderUtil.getZLibrary(this);
}
/* ++++++ SCREEN BRIGHTNESS ++++++ */
protected void setScreenBrightnessAuto() {
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.screenBrightness = -1.0f;
getWindow().setAttributes(attrs);
}
public void setScreenBrightnessSystem(int percent) {
if (percent < 2) {
percent = 2;
} else if (percent > 100) {
percent = 100;
}
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.screenBrightness = percent / 100.0f;
getWindow().setAttributes(attrs);
getZLibrary().ScreenBrightnessLevelOption.setValue(percent);
}
public int getScreenBrightnessSystem() {
final int level = (int)(100 * getWindow().getAttributes().screenBrightness);
return level >= 0 ? level : 50;
}
/* ------ SCREEN BRIGHTNESS ------ */
/* ++++++ SUPER TOAST ++++++ */
public boolean isToastShown() {
final SuperActivityToast toast = myToast;

View file

@ -22,6 +22,7 @@ package org.geometerplus.android.fbreader;
import java.util.*;
import org.geometerplus.zlibrary.core.library.ZLibrary;
import org.geometerplus.zlibrary.core.options.ZLIntegerOption;
import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.fbreader.fbreader.ActionCode;
@ -31,12 +32,31 @@ import org.geometerplus.android.util.DeviceType;
public abstract class MenuData {
private static List<MenuNode> ourNodes;
private static final Map<String,ZLIntegerOption> ourNodeOptions =
new HashMap<String,ZLIntegerOption>();
private static final Map<String,Integer> ourDefaultValues = new HashMap<String,Integer>();
private static final Map<String,String> ourConfigCodes = new HashMap<String,String>();
private static final Set<String> ourAlwaysEnabledCodes = new HashSet<String>();
private static final String CONFIG_CODE_DAY_NIGHT = "dayNight";
private static final String CONFIG_CODE_CHANGE_FONT_SIZE = "changeFontSize";
private static void addToplevelNode(MenuNode node) {
ourNodes.add(node);
addToplevelNode(node, node.Code, false);
}
public static synchronized List<MenuNode> topLevelNodes() {
private static void addToplevelNode(MenuNode node, String configCode, boolean alwaysEnabled) {
ourConfigCodes.put(node.Code, configCode);
if (!ourDefaultValues.containsKey(configCode)) {
ourDefaultValues.put(configCode, ourDefaultValues.size());
}
ourNodes.add(node);
if (alwaysEnabled) {
ourAlwaysEnabledCodes.add(configCode);
}
}
private static synchronized List<MenuNode> allTopLevelNodes() {
if (ourNodes == null) {
ourNodes = new ArrayList<MenuNode>();
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_LIBRARY, R.drawable.ic_menu_library));
@ -47,11 +67,23 @@ public abstract class MenuData {
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_NETWORK_LIBRARY, R.drawable.ic_menu_networklibrary));
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_TOC, R.drawable.ic_menu_toc));
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_BOOKMARKS, R.drawable.ic_menu_bookmarks));
addToplevelNode(new MenuNode.Item(ActionCode.SWITCH_TO_NIGHT_PROFILE, R.drawable.ic_menu_night));
addToplevelNode(new MenuNode.Item(ActionCode.SWITCH_TO_DAY_PROFILE, R.drawable.ic_menu_day));
addToplevelNode(
new MenuNode.Item(ActionCode.SWITCH_TO_NIGHT_PROFILE, R.drawable.ic_menu_night),
CONFIG_CODE_DAY_NIGHT,
false
);
addToplevelNode(
new MenuNode.Item(ActionCode.SWITCH_TO_DAY_PROFILE, R.drawable.ic_menu_day),
CONFIG_CODE_DAY_NIGHT,
false
);
addToplevelNode(new MenuNode.Item(ActionCode.SEARCH, R.drawable.ic_menu_search));
addToplevelNode(new MenuNode.Item(ActionCode.SHARE_BOOK));
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_PREFERENCES));
addToplevelNode(
new MenuNode.Item(ActionCode.SHOW_PREFERENCES),
ActionCode.SHOW_PREFERENCES,
true
);
addToplevelNode(new MenuNode.Item(ActionCode.SHOW_BOOK_INFO));
final MenuNode.Submenu orientations = new MenuNode.Submenu("screenOrientation");
orientations.Children.add(new MenuNode.Item(ActionCode.SET_SCREEN_ORIENTATION_SYSTEM));
@ -63,8 +95,16 @@ public abstract class MenuData {
orientations.Children.add(new MenuNode.Item(ActionCode.SET_SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
}
addToplevelNode(orientations);
addToplevelNode(new MenuNode.Item(ActionCode.INCREASE_FONT));
addToplevelNode(new MenuNode.Item(ActionCode.DECREASE_FONT));
addToplevelNode(
new MenuNode.Item(ActionCode.INCREASE_FONT),
CONFIG_CODE_CHANGE_FONT_SIZE,
false
);
addToplevelNode(
new MenuNode.Item(ActionCode.DECREASE_FONT),
CONFIG_CODE_CHANGE_FONT_SIZE,
false
);
addToplevelNode(new MenuNode.Item(ActionCode.INSTALL_PLUGINS));
addToplevelNode(new MenuNode.Item(ActionCode.OPEN_WEB_HELP));
addToplevelNode(new MenuNode.Item(ActionCode.OPEN_START_SCREEN));
@ -72,4 +112,88 @@ public abstract class MenuData {
}
return ourNodes;
}
private static String code(MenuNode node) {
return ourConfigCodes.get(node.Code);
}
private static class MenuComparator implements Comparator<MenuNode> {
@Override
public int compare(MenuNode lhs, MenuNode rhs) {
return nodeOption(code(lhs)).getValue() - nodeOption(code(rhs)).getValue();
}
}
private static class CodeComparator implements Comparator<String> {
@Override
public int compare(String lhs, String rhs) {
return nodeOption(lhs).getValue() - nodeOption(rhs).getValue();
}
}
public static ArrayList<String> enabledCodes() {
final ArrayList<String> codes = new ArrayList<String>();
for (MenuNode node : allTopLevelNodes()) {
final String c = code(node);
if (!codes.contains(c) && isCodeEnabled(c)) {
codes.add(c);
}
}
Collections.sort(codes, new CodeComparator());
return codes;
}
public static ArrayList<String> disabledCodes() {
final ArrayList<String> codes = new ArrayList<String>();
for (MenuNode node : allTopLevelNodes()) {
final String c = code(node);
if (!codes.contains(c) && !isCodeEnabled(c)) {
codes.add(c);
}
}
return codes;
}
public static int configIconId(String itemCode) {
final List<MenuNode> allNodes = allTopLevelNodes();
Integer iconId = null;
for (MenuNode node : allNodes) {
if (node instanceof MenuNode.Item && itemCode.equals(code(node))) {
iconId = ((MenuNode.Item)node).IconId;
break;
}
}
return iconId != null ? iconId : R.drawable.ic_menu_none;
}
public static synchronized List<MenuNode> topLevelNodes() {
final List<MenuNode> allNodes = new ArrayList<MenuNode>(allTopLevelNodes());
final List<MenuNode> activeNodes = new ArrayList<MenuNode>(allNodes.size());
for (MenuNode node : allNodes) {
if (isCodeEnabled(code(node))) {
activeNodes.add(node);
}
}
Collections.<MenuNode>sort(activeNodes, new MenuComparator());
return activeNodes;
}
public static ZLIntegerOption nodeOption(String code) {
synchronized (ourNodeOptions) {
ZLIntegerOption option = ourNodeOptions.get(code);
if (option == null) {
option = new ZLIntegerOption("MainMenu", code, ourDefaultValues.get(code));
ourNodeOptions.put(code, option);
}
return option;
}
}
public static boolean isCodeAlwaysEnabled(String code) {
return ourAlwaysEnabledCodes.contains(code);
}
private static boolean isCodeEnabled(String code) {
return ourAlwaysEnabledCodes.contains(code) || nodeOption(code).getValue() >= 0;
}
}

View file

@ -58,7 +58,12 @@ public class LibraryActivity extends TreeActivity<LibraryTree> implements MenuIt
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mySelectedBook = FBReaderIntents.getBookExtra(getIntent(), myCollection);
final Intent intent = getIntent();
if (intent != null && "android.fbreader.action.EXTERNAL_INTERNAL_LIBRARY".equals(intent.getAction())) {
runOrInstallExternalView(false);
}
mySelectedBook = FBReaderIntents.getBookExtra(intent, myCollection);
new LibraryTreeAdapter(this);
@ -72,7 +77,7 @@ public class LibraryActivity extends TreeActivity<LibraryTree> implements MenuIt
showProgress(!myCollection.status().IsComplete);
myRootTree = new RootTree(myCollection, PluginCollection.Instance(Paths.systemInfo(LibraryActivity.this)));
myCollection.addListener(LibraryActivity.this);
init(getIntent());
init(intent);
}
});
}
@ -119,7 +124,7 @@ public class LibraryActivity extends TreeActivity<LibraryTree> implements MenuIt
protected void onListItemClick(ListView listView, View view, int position, long rowId) {
final LibraryTree tree = (LibraryTree)getListAdapter().getItem(position);
if (tree instanceof ExternalViewTree) {
runOrInstallExternalView();
runOrInstallExternalView(true);
} else {
final Book book = tree.getBook();
if (book != null) {
@ -374,19 +379,21 @@ public class LibraryActivity extends TreeActivity<LibraryTree> implements MenuIt
return true;
}
case OptionsItemId.ExternalView:
runOrInstallExternalView();
runOrInstallExternalView(true);
return true;
default:
return true;
}
}
private void runOrInstallExternalView() {
private void runOrInstallExternalView(boolean install) {
try {
startActivity(new Intent(FBReaderIntents.Action.EXTERNAL_LIBRARY));
finish();
} catch (ActivityNotFoundException e) {
PackageUtil.installFromMarket(this, "org.fbreader.plugin.library");
if (install) {
PackageUtil.installFromMarket(this, "org.fbreader.plugin.library");
}
}
}

View file

@ -48,21 +48,26 @@ import org.geometerplus.fbreader.network.sync.SyncUtil;
import org.geometerplus.fbreader.tips.TipsManager;
import org.geometerplus.android.fbreader.FBReader;
import org.geometerplus.android.fbreader.MenuData;
import org.geometerplus.android.fbreader.dict.DictionaryUtil;
import org.geometerplus.android.fbreader.libraryService.BookCollectionShadow;
import org.geometerplus.android.fbreader.network.auth.ActivityNetworkContext;
import org.geometerplus.android.fbreader.preferences.fileChooser.FileChooserCollection;
import org.geometerplus.android.fbreader.preferences.background.BackgroundPreference;
import org.geometerplus.android.fbreader.preferences.fileChooser.FileChooserCollection;
import org.geometerplus.android.fbreader.preferences.menu.MenuPreference;
import org.geometerplus.android.fbreader.sync.SyncOperations;
import org.geometerplus.android.util.UIUtil;
import org.geometerplus.android.util.DeviceType;
public class PreferenceActivity extends ZLPreferenceActivity {
private static final int BACKGROUND_REQUEST_CODE = 3000;
private static final int MENU_REQUEST_CODE = 3001;
private final ActivityNetworkContext myNetworkContext = new ActivityNetworkContext(this);
private final FileChooserCollection myChooserCollection = new FileChooserCollection(this, 2000);
private static final int BACKGROUND_REQUEST_CODE = 3000;
private BackgroundPreference myBackgroundPreference;
private MenuPreference myMenuPreference;
public PreferenceActivity() {
super("Preferences");
@ -91,6 +96,13 @@ public class PreferenceActivity extends ZLPreferenceActivity {
return;
}
if (MENU_REQUEST_CODE == requestCode) {
if (myMenuPreference != null) {
myMenuPreference.update(data);
}
return;
}
myChooserCollection.update(requestCode, data);
}
@ -105,6 +117,7 @@ public class PreferenceActivity extends ZLPreferenceActivity {
config.requestAllValuesForGroup("Scrolling");
config.requestAllValuesForGroup("Colors");
config.requestAllValuesForGroup("Sync");
config.requestAllValuesForGroup("MainMenu");
setResult(FBReader.RESULT_REPAINT);
final ViewOptions viewOptions = new ViewOptions();
@ -717,6 +730,13 @@ public class PreferenceActivity extends ZLPreferenceActivity {
imagesScreen.addOption(imageOptions.ImageViewBackground, "backgroundColor");
imagesScreen.addOption(imageOptions.MatchBackground, "matchBackground");
myMenuPreference = new MenuPreference(
this,
Resource.getResource("menu"),
MENU_REQUEST_CODE
);
addPreference(myMenuPreference);
final CancelMenuHelper cancelMenuHelper = new CancelMenuHelper();
final Screen cancelMenuScreen = createPreferenceScreen("cancelMenu");
cancelMenuScreen.addOption(cancelMenuHelper.ShowLibraryItemOption, "library");

View file

@ -0,0 +1,227 @@
/*
* Copyright (C) 2009-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.preferences.menu;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import com.mobeta.android.dslv.DragSortListView;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.android.fbreader.MenuData;
import org.geometerplus.android.util.ViewUtil;
public class ConfigurationActivity extends ListActivity {
static final String ENABLED_MENU_IDS_KEY = "enabledMenuIds";
static final String DISABLED_MENU_IDS_KEY = "disabledMenuIds";
private final List<Item> myAllItems = new ArrayList<Item>();
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.menu_configure_view);
}
@Override
protected void onStart() {
super.onStart();
myAllItems.clear();
final Intent intent = getIntent();
myAllItems.add(new SectionItem("enabled"));
final List<String> enabledIds =
intent.getStringArrayListExtra(ENABLED_MENU_IDS_KEY);
if (enabledIds.size() > 0) {
for (String id : enabledIds) {
myAllItems.add(new MenuNodeItem(id, true));
}
}
myAllItems.add(new SectionItem("disabled"));
final List<String> disabledIds =
intent.getStringArrayListExtra(DISABLED_MENU_IDS_KEY);
if (disabledIds.size() > 0) {
for (String id : disabledIds) {
myAllItems.add(new MenuNodeItem(id, false));
}
}
setListAdapter(new MenuListAdapter());
}
@Override
public DragSortListView getListView() {
return (DragSortListView)super.getListView();
}
private static interface Item {
}
private static class SectionItem implements Item {
private final String Title;
public SectionItem(String key) {
Title = ZLResource.resource("Preferences").getResource("menu").getResource(key).getValue();
}
}
private static class MenuNodeItem implements Item {
private final String Id;
private boolean IsChecked;
private final boolean IsEnabled;
public MenuNodeItem(String id, boolean checked) {
Id = id;
IsChecked = checked;
IsEnabled = !MenuData.isCodeAlwaysEnabled(id);
}
public String getTitle() {
return ZLResource.resource("menu").getResource(Id).getValue();
}
}
private class MenuListAdapter extends ArrayAdapter<Item> implements DragSortListView.DropListener, DragSortListView.RemoveListener {
public MenuListAdapter() {
super(ConfigurationActivity.this, R.layout.menu_configure_item, myAllItems);
}
private int indexOfDisabledSectionItem() {
for (int i = 1; i < getCount(); i++) {
if (getItem(i) instanceof SectionItem) {
return i;
}
}
// should be impossible
return 0;
}
private void setResultIds() {
final ArrayList<String> eIds = new ArrayList<String>();
final ArrayList<String> dIds = new ArrayList<String>();
for (int i = 1; i < getCount(); ++i) {
final Item item = getItem(i);
if (item instanceof SectionItem) {
continue;
}
final MenuNodeItem menuItem = (MenuNodeItem)item;
if (menuItem.IsChecked) {
eIds.add(menuItem.Id);
} else {
dIds.add(menuItem.Id);
}
}
setResult(RESULT_OK, new Intent()
.putStringArrayListExtra(ENABLED_MENU_IDS_KEY, eIds)
.putStringArrayListExtra(DISABLED_MENU_IDS_KEY, dIds));
}
@Override
public View getView(int position, View convertView, final ViewGroup parent) {
final Item item = getItem(position);
final View view;
if (convertView != null && item.getClass().equals(convertView.getTag())) {
view = convertView;
} else {
view = getLayoutInflater().inflate(
item instanceof SectionItem
? R.layout.menu_configure_section_head : R.layout.menu_configure_item,
null
);
view.setTag(item.getClass());
}
if (item instanceof SectionItem) {
ViewUtil.setSubviewText(
view, R.id.menu_configure_section_head_title, ((SectionItem)item).Title
);
} else /* if (item instanceof MenuNodeItem) */ {
final MenuNodeItem menuItem = (MenuNodeItem)item;
final TextView titleView =
ViewUtil.findTextView(view, R.id.menu_configure_item_title);
titleView.setText(menuItem.getTitle());
final ImageView iconView =
ViewUtil.findImageView(view, R.id.menu_configure_item_icon);
iconView.setImageResource(MenuData.configIconId(menuItem.Id));
final CheckBox checkBox =
(CheckBox)ViewUtil.findView(view, R.id.menu_configure_item_checkbox);
checkBox.setChecked(menuItem.IsChecked);
checkBox.setEnabled(menuItem.IsEnabled);
if (menuItem.IsEnabled) {
final View.OnClickListener updateCheckbox = new View.OnClickListener() {
public void onClick(View v) {
if (v != checkBox) {
checkBox.performClick();
}
menuItem.IsChecked = checkBox.isChecked();
setResultIds();
}
};
checkBox.setOnClickListener(updateCheckbox);
iconView.setOnClickListener(updateCheckbox);
titleView.setOnClickListener(updateCheckbox);
}
}
return view;
}
// method from DragSortListView.DropListener
public void drop(int from, int to) {
to = Math.max(to, 1);
if (from == to) {
return;
}
final Item item = getItem(from);
if (item instanceof MenuNodeItem) {
remove(item);
insert(item, to);
if (((MenuNodeItem)item).IsEnabled) {
((MenuNodeItem)item).IsChecked = to < indexOfDisabledSectionItem();
}
getListView().moveCheckState(from, to);
setResultIds();
}
}
// method from DragSortListView.RemoveListener
public void remove(int which) {
final Item item = getItem(which);
if (item instanceof MenuNodeItem) {
remove(item);
getListView().removeCheckState(which);
}
}
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2010-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.preferences.menu;
import java.util.*;
import android.app.Activity;
import android.content.Intent;
import android.preference.Preference;
import org.geometerplus.android.fbreader.MenuData;
import org.geometerplus.zlibrary.core.resources.ZLResource;
public class MenuPreference extends Preference {
private final int myRequestCode;
public MenuPreference(Activity activity, ZLResource resource, int requestCode) {
super(activity);
setTitle(resource.getValue());
setSummary(resource.getResource("summary").getValue());
myRequestCode = requestCode;
}
@Override
protected void onClick() {
((Activity)getContext()).startActivityForResult(
new Intent(getContext(), ConfigurationActivity.class)
.putStringArrayListExtra(ConfigurationActivity.ENABLED_MENU_IDS_KEY, MenuData.enabledCodes())
.putStringArrayListExtra(ConfigurationActivity.DISABLED_MENU_IDS_KEY, MenuData.disabledCodes()),
myRequestCode
);
}
public void update(Intent data) {
int i = 0;
for (String s : data.getStringArrayListExtra(ConfigurationActivity.ENABLED_MENU_IDS_KEY)) {
MenuData.nodeOption(s).setValue(i);
++i;
}
for (String s : data.getStringArrayListExtra(ConfigurationActivity.DISABLED_MENU_IDS_KEY)) {
MenuData.nodeOption(s).setValue(-1);
}
}
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (C) 2009-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.widget.simple;
import java.util.*;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.ui.android.R;
public class ConfigurationActivity extends Activity {
private int myWidgetId;
private SharedPreferences myPrefs;
private Button myOkButton;
private View[] myIconContainers;
private Spinner myActionsCombo;
private final View.OnClickListener myIconCheckboxListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (findCheckbox(view).isChecked()) {
return;
}
final int icon = (Integer)view.getTag();
myPrefs.edit().putInt(Provider.Key.ICON, icon).apply();
for (View c : myIconContainers) {
findCheckbox(c).setChecked(c == view);
}
myActionsCombo.setSelection(Provider.Action.ALL.indexOf(Provider.defaultAction(icon)));
updateOkButton();
}
private CheckBox findCheckbox(View v) {
return (CheckBox)v.findViewById(R.id.icon_checkbox_checkbox);
}
};
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.widget_simple_config);
final ZLResource widgetResource = ZLResource.resource("widget").getResource("simple");
myWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
final Bundle extras = getIntent().getExtras();
if (extras != null) {
myWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
);
}
if (myWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
myPrefs = Provider.getSharedPreferences(this, myWidgetId);
myPrefs.edit().clear().apply();
setResult(RESULT_CANCELED);
final View buttons = findViewById(R.id.widget_simple_config_buttons);
final ZLResource buttonResource = ZLResource.resource("dialog").getResource("button");
myOkButton = (Button)buttons.findViewById(R.id.ok_button);
myOkButton.setText(buttonResource.getResource("ok").getValue());
myOkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Provider.setupViews(
AppWidgetManager.getInstance(ConfigurationActivity.this),
ConfigurationActivity.this,
myWidgetId
);
setResult(
RESULT_OK,
new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, myWidgetId)
);
finish();
}
});
myOkButton.setEnabled(false);
final Button cancelButton = (Button)buttons.findViewById(R.id.cancel_button);
cancelButton.setText(buttonResource.getResource("cancel").getValue());
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myPrefs.edit().clear().apply();
finish();
}
});
final TextView iconLabel = (TextView)findViewById(R.id.widget_simple_config_icon_label);
iconLabel.setText(widgetResource.getResource("selectIcon").getValue());
myIconContainers = new View[] {
iconContainer(R.id.widget_simple_config_fbreader, Provider.Icon.FBREADER),
iconContainer(R.id.widget_simple_config_classic, Provider.Icon.CLASSIC),
iconContainer(R.id.widget_simple_config_library, Provider.Icon.LIBRARY),
iconContainer(R.id.widget_simple_config_library_old, Provider.Icon.LIBRARY_OLD)
};
final List<String> actionCodes = Provider.Action.ALL;
final List<String> actionNames = new ArrayList<String>(actionCodes.size());
for (String code : actionCodes) {
actionNames.add(widgetResource.getResource(code).getValue());
}
final TextView actionLabel = (TextView)findViewById(R.id.widget_simple_config_action_label);
actionLabel.setText(widgetResource.getResource("selectAction").getValue());
myActionsCombo = (Spinner)findViewById(R.id.widget_simple_config_actions);
myActionsCombo.setAdapter(new ArrayAdapter<String>(
this, android.R.layout.select_dialog_item, actionNames
));
myActionsCombo.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
myPrefs.edit().putString(
Provider.Key.ACTION, actionCodes.get(position)
).apply();
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private void updateOkButton() {
final Set<String> keys = myPrefs.getAll().keySet();
myOkButton.setEnabled(
keys.contains(Provider.Key.ICON) &&
keys.contains(Provider.Key.ACTION)
);
}
private View iconContainer(final int viewId, final int icon) {
final View container = findViewById(viewId);
container.setTag(icon);
((ImageView)container.findViewById(R.id.icon_checkbox_icon))
.setImageResource(Provider.iconId(icon));
container.setOnClickListener(myIconCheckboxListener);
return container;
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (C) 2009-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.widget.simple;
import java.util.Arrays;
import java.util.List;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.*;
import android.widget.RemoteViews;
import org.geometerplus.zlibrary.ui.android.R;
import org.geometerplus.android.fbreader.FBReader;
import org.geometerplus.android.fbreader.library.LibraryActivity;
public class Provider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int id : appWidgetIds) {
setupViews(appWidgetManager, context, id);
}
}
// ++++ these constants are used for storing widget state persistently ++++
// ++++ never change them, just add new values ++++
interface Key {
String ICON = "icon";
String ACTION = "action";
}
interface Icon {
int FBREADER = 0;
int CLASSIC = 1;
int LIBRARY = 2;
int LIBRARY_OLD = 3;
}
interface Action {
String BOOK = "book";
String LIBRARY = "library";
List<String> ALL = Arrays.asList(BOOK, LIBRARY);
}
// ---- these constants are used for storing widget state persistently ----
static int iconId(int icon) {
switch (icon) {
default:
case Icon.FBREADER:
return R.drawable.fbreader;
case Icon.CLASSIC:
return R.drawable.classic;
case Icon.LIBRARY:
return R.drawable.library_old;
case Icon.LIBRARY_OLD:
return R.drawable.library_old;
}
}
static String defaultAction(int icon) {
switch (icon) {
default:
case Icon.FBREADER:
case Icon.CLASSIC:
return Action.BOOK;
case Icon.LIBRARY:
case Icon.LIBRARY_OLD:
return Action.LIBRARY;
}
}
static void setupViews(AppWidgetManager appWidgetManager, Context context, int widgetId) {
final SharedPreferences prefs = getSharedPreferences(context, widgetId);
final RemoteViews views =
new RemoteViews(context.getPackageName(), R.layout.widget_simple);
views.setImageViewResource(
R.id.widget_simple, iconId(prefs.getInt(Key.ICON, Icon.FBREADER))
);
final String action = prefs.getString(Key.ACTION, Action.BOOK);
final Intent intent;
if (Action.LIBRARY.equals(action)) {
intent = new Intent(context, LibraryActivity.class);
intent.setAction("android.fbreader.action.EXTERNAL_INTERNAL_LIBRARY");
} else /* if Action.BOOK.equals(action) */ {
intent = FBReader.defaultIntent(context);
}
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.widget_simple, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, views);
}
static SharedPreferences getSharedPreferences(Context context, int widgetId) {
return context.getApplicationContext().getSharedPreferences(
"SimpleWidget" + widgetId, Context.MODE_PRIVATE
);
}
}

View file

@ -158,6 +158,7 @@ public final class ZLTextParagraphCursor {
if (index > 0 && spaceState == NO_SPACE) {
addWord(data, offset + wordStart, index - wordStart, myOffset + wordStart, hyperlink);
}
elements.add(nbSpace);
if (spaceState != SPACE) {
spaceState = NON_BREAKABLE_SPACE;
}
@ -170,7 +171,6 @@ public final class ZLTextParagraphCursor {
wordStart = index;
break;
case NON_BREAKABLE_SPACE:
elements.add(nbSpace);
wordStart = index;
break;
case NO_SPACE:

View file

@ -227,7 +227,8 @@ abstract class ZLTextViewBase extends ZLView {
}
final int getElementHeight(ZLTextElement element) {
if (element instanceof ZLTextWord ||
if (element == ZLTextElement.NBSpace ||
element instanceof ZLTextWord ||
element instanceof ZLTextFixedHSpaceElement) {
return getWordHeight();
} else if (element instanceof ZLTextImageElement) {

View file

@ -0,0 +1,67 @@
/*
* Copyright (C) 2007-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.zlibrary.ui.android.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import org.geometerplus.android.fbreader.FBReaderMainActivity;
public abstract class MainView extends View {
protected Integer myColorLevel;
public MainView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MainView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MainView(Context context) {
super(context);
}
public final void setScreenBrightness(int percent) {
final Context context = getContext();
if (!(context instanceof FBReaderMainActivity)) {
return;
}
((FBReaderMainActivity)context).setScreenBrightnessSystem(percent);
if (percent >= 50) {
myColorLevel = null;
} else {
myColorLevel = 0x60 + (0xFF - 0x60) * Math.max(percent, 0) / 50;
}
updateColorLevel();
postInvalidate();
}
public final int getScreenBrightness() {
final Context context = getContext();
if (!(context instanceof FBReaderMainActivity)) {
return 50;
}
return ((FBReaderMainActivity)context).getScreenBrightnessSystem();
}
protected abstract void updateColorLevel();
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2007-2015 FBReader.ORG Limited <contact@fbreader.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.zlibrary.ui.android.view;
import android.graphics.*;
public abstract class ViewUtil {
public static void setColorLevel(Paint paint, Integer level) {
if (level != null) {
paint.setColorFilter(new PorterDuffColorFilter(
Color.rgb(level, level, level), PorterDuff.Mode.MULTIPLY
));
} else {
paint.setColorFilter(null);
}
}
}

View file

@ -47,10 +47,11 @@ import org.geometerplus.fbreader.fbreader.options.PageTurningOptions;
import org.geometerplus.android.fbreader.FBReader;
public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongClickListener {
public class ZLAndroidWidget extends MainView implements ZLViewWidget, View.OnLongClickListener {
public final ExecutorService PrepareService = Executors.newSingleThreadExecutor();
private final Paint myPaint = new Paint();
private final BitmapManagerImpl myBitmapManager = new BitmapManagerImpl(this);
private Bitmap myFooterBitmap;
private final SystemInfo mySystemInfo;
@ -277,7 +278,7 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl
@Override
public void startManualScrolling(int x, int y, ZLView.Direction direction) {
final AnimationProvider animator = getAnimationProvider();
animator.setup(direction, getWidth(), getMainAreaHeight());
animator.setup(direction, getWidth(), getMainAreaHeight(), myColorLevel);
animator.startManualScrolling(x, y);
}
@ -298,7 +299,7 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl
return;
}
final AnimationProvider animator = getAnimationProvider();
animator.setup(direction, getWidth(), getMainAreaHeight());
animator.setup(direction, getWidth(), getMainAreaHeight(), myColorLevel);
animator.startAnimatedScrolling(pageIndex, x, y, speed);
if (animator.getMode().Auto) {
postInvalidate();
@ -312,7 +313,7 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl
return;
}
final AnimationProvider animator = getAnimationProvider();
animator.setup(direction, getWidth(), getMainAreaHeight());
animator.setup(direction, getWidth(), getMainAreaHeight(), myColorLevel);
animator.startAnimatedScrolling(pageIndex, null, null, speed);
if (animator.getMode().Auto) {
postInvalidate();
@ -667,19 +668,8 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl
return resourceId > 0 ? res.getDimensionPixelSize(resourceId) : 0;
}
public void setScreenBrightness(int percent) {
final Context context = getContext();
if (!(context instanceof FBReader)) {
return;
}
((FBReader)context).setScreenBrightness(percent);
}
public int getScreenBrightness() {
final Context context = getContext();
if (!(context instanceof FBReader)) {
return 50;
}
return ((FBReader)context).getScreenBrightness();
@Override
protected void updateColorLevel() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
}
}

View file

@ -55,6 +55,7 @@ public abstract class AnimationProvider {
protected int myWidth;
protected int myHeight;
protected Integer myColorLevel;
protected AnimationProvider(BitmapManager bitmapManager) {
myBitmapManager = bitmapManager;
@ -209,10 +210,11 @@ public abstract class AnimationProvider {
return myDirection.IsHorizontal ? myEndX - myStartX : myEndY - myStartY;
}
public final void setup(ZLViewEnums.Direction direction, int width, int height) {
public final void setup(ZLViewEnums.Direction direction, int width, int height, Integer colorLevel) {
myDirection = direction;
myWidth = width;
myHeight = height;
myColorLevel = colorLevel;
}
public abstract void doStep();
@ -240,6 +242,7 @@ public abstract class AnimationProvider {
public final void draw(Canvas canvas) {
final long start = System.currentTimeMillis();
setFilter();
drawInternal(canvas);
myDrawInfos.add(new DrawInfo(myEndX, myEndY, start, System.currentTimeMillis()));
if (myDrawInfos.size() > 3) {
@ -247,7 +250,14 @@ public abstract class AnimationProvider {
}
}
public final void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
setFilter();
drawFooterBitmapInternal(canvas, footerBitmap, voffset);
}
protected abstract void setFilter();
protected abstract void drawInternal(Canvas canvas);
protected abstract void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset);
public abstract ZLViewEnums.PageIndex getPageToScrollTo(int x, int y);
@ -270,6 +280,4 @@ public abstract class AnimationProvider {
protected void drawBitmapTo(Canvas canvas, int x, int y, Paint paint) {
myBitmapManager.drawBitmap(canvas, x, y, getPageToScrollTo(), paint);
}
public abstract void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset);
}

View file

@ -24,7 +24,9 @@ import android.util.FloatMath;
import org.geometerplus.zlibrary.core.util.BitmapUtil;
import org.geometerplus.zlibrary.core.view.ZLViewEnums;
import org.geometerplus.zlibrary.ui.android.util.ZLAndroidColorUtil;
import org.geometerplus.zlibrary.ui.android.view.ViewUtil;
public final class CurlAnimationProvider extends AnimationProvider {
private final Paint myPaint = new Paint();
@ -327,7 +329,14 @@ public final class CurlAnimationProvider extends AnimationProvider {
}
@Override
public void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
public void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset) {
canvas.drawBitmap(footerBitmap, 0, voffset, myPaint);
}
@Override
protected void setFilter() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
ViewUtil.setColorLevel(myBackPaint, myColorLevel);
ViewUtil.setColorLevel(myEdgePaint, myColorLevel);
}
}

View file

@ -23,6 +23,8 @@ import android.graphics.*;
import org.geometerplus.zlibrary.core.view.ZLViewEnums;
import org.geometerplus.zlibrary.ui.android.view.ViewUtil;
public final class NoneAnimationProvider extends AnimationProvider {
private final Paint myPaint = new Paint();
@ -79,7 +81,12 @@ public final class NoneAnimationProvider extends AnimationProvider {
}
@Override
public void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
public void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset) {
canvas.drawBitmap(footerBitmap, 0, voffset, myPaint);
}
@Override
protected void setFilter() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
}
}

View file

@ -21,6 +21,8 @@ package org.geometerplus.zlibrary.ui.android.view.animation;
import android.graphics.*;
import org.geometerplus.zlibrary.ui.android.view.ViewUtil;
public final class ShiftAnimationProvider extends SimpleAnimationProvider {
private final Paint myPaint = new Paint();
{
@ -55,7 +57,7 @@ public final class ShiftAnimationProvider extends SimpleAnimationProvider {
}
@Override
public void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
public void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset) {
canvas.drawBitmap(footerBitmap, 0, voffset, myPaint);
if (myDirection.IsHorizontal) {
final int dX = myEndX - myStartX;
@ -66,4 +68,9 @@ public final class ShiftAnimationProvider extends SimpleAnimationProvider {
}
}
}
@Override
protected void setFilter() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
}
}

View file

@ -22,6 +22,8 @@ package org.geometerplus.zlibrary.ui.android.view.animation;
import android.graphics.*;
import android.graphics.drawable.GradientDrawable;
import org.geometerplus.zlibrary.ui.android.view.ViewUtil;
public final class SlideAnimationProvider extends SimpleAnimationProvider {
private final Paint myDarkPaint = new Paint();
private final Paint myPaint = new Paint();
@ -31,10 +33,16 @@ public final class SlideAnimationProvider extends SimpleAnimationProvider {
}
private void setDarkFilter(int visible, int full) {
final int color = 145 + 100 * Math.abs(visible) / full;
myDarkPaint.setColorFilter(new PorterDuffColorFilter(
Color.rgb(color, color, color), PorterDuff.Mode.MULTIPLY
));
int darkColorLevel = 145 + 100 * Math.abs(visible) / full;
if (myColorLevel != null) {
darkColorLevel = darkColorLevel * myColorLevel / 0xFF;
}
ViewUtil.setColorLevel(myDarkPaint, darkColorLevel);
}
@Override
protected void setFilter() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
}
private void drawShadow(Canvas canvas, int top, int bottom, int dX) {
@ -79,7 +87,7 @@ public final class SlideAnimationProvider extends SimpleAnimationProvider {
}
@Override
public void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
protected void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset) {
if (myDirection.IsHorizontal) {
final int dX = myEndX - myStartX;
setDarkFilter(dX, myWidth);

View file

@ -21,6 +21,8 @@ package org.geometerplus.zlibrary.ui.android.view.animation;
import android.graphics.*;
import org.geometerplus.zlibrary.ui.android.view.ViewUtil;
public final class SlideOldStyleAnimationProvider extends SimpleAnimationProvider {
private final Paint myPaint = new Paint();
@ -52,7 +54,7 @@ public final class SlideOldStyleAnimationProvider extends SimpleAnimationProvide
}
@Override
public void drawFooterBitmap(Canvas canvas, Bitmap footerBitmap, int voffset) {
protected void drawFooterBitmapInternal(Canvas canvas, Bitmap footerBitmap, int voffset) {
canvas.drawBitmap(footerBitmap, 0, voffset, myPaint);
if (myDirection.IsHorizontal) {
final int dX = myEndX - myStartX;
@ -63,4 +65,9 @@ public final class SlideOldStyleAnimationProvider extends SimpleAnimationProvide
}
}
}
@Override
protected void setFilter() {
ViewUtil.setColorLevel(myPaint, myColorLevel);
}
}