diff --git a/res/layout/slider_preference_dialog.xml b/res/layout/slider_preference_dialog.xml new file mode 100644 index 000000000..7e2eafce6 --- /dev/null +++ b/res/layout/slider_preference_dialog.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml index dc108fa98..fb1e59c2f 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -55,4 +55,8 @@ + + + + diff --git a/res/xml/font_preferences.xml b/res/xml/font_preferences.xml index c0486e64a..cce4a7007 100644 --- a/res/xml/font_preferences.xml +++ b/res/xml/font_preferences.xml @@ -153,6 +153,12 @@ android:entryValues="@array/font_values_webview" android:dialogTitle="@string/font_size_message_view_content" /> + + = android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + ((PreferenceGroup) findPreference(PREFERENCE_SCREEN_MESSAGE_VIEW_FONTS)). + removePreference(mMessageViewContent); + } else { + ((PreferenceGroup) findPreference(PREFERENCE_SCREEN_MESSAGE_VIEW_FONTS)). + removePreference(mMessageViewContentSlider); + } + mMessageComposeInput = setupListPreference( PREFERENCE_MESSAGE_COMPOSE_INPUT_FONT, Integer.toString(fontSizes.getMessageComposeInput())); @@ -150,6 +190,10 @@ public class FontSizeSettings extends K9PreferenceActivity { fontSizes.setMessageViewSubject(Integer.parseInt(mMessageViewSubject.getValue())); fontSizes.setMessageViewDate(Integer.parseInt(mMessageViewDate.getValue())); fontSizes.setMessageViewContent(Integer.parseInt(mMessageViewContent.getValue())); + // Scale from [0, 1] + fontSizes.setMessageViewContentAsPercent((int)(FONT_PERCENT_MIN + + mMessageViewContentSlider.getValue() * + (FONT_PERCENT_MAX - FONT_PERCENT_MIN))); fontSizes.setMessageComposeInput(Integer.parseInt(mMessageComposeInput.getValue())); diff --git a/src/com/fsck/k9/activity/setup/SliderPreference.java b/src/com/fsck/k9/activity/setup/SliderPreference.java new file mode 100644 index 000000000..3342138c2 --- /dev/null +++ b/src/com/fsck/k9/activity/setup/SliderPreference.java @@ -0,0 +1,172 @@ +/* + * Copyright 2012 Jay Weisskopf + * + * Licensed under the MIT License (see LICENSE.txt) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Source: https://github.com/jayschwa/AndroidSliderPreference + */ + +package com.fsck.k9.activity.setup; + +import android.content.Context; +import android.content.res.TypedArray; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.View; +import android.widget.SeekBar; +import com.fsck.k9.*; + + +/** + * @author Jay Weisskopf + */ +public class SliderPreference extends DialogPreference { + + protected final static int SEEKBAR_RESOLUTION = 10000; + + protected float mValue; + protected int mSeekBarValue; + protected CharSequence[] mSummaries; + + /** + * @param context + * @param attrs + */ + public SliderPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setup(context, attrs); + } + + /** + * @param context + * @param attrs + * @param defStyle + */ + public SliderPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setup(context, attrs); + } + + private void setup(Context context, AttributeSet attrs) { + setDialogLayoutResource(R.layout.slider_preference_dialog); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference); + try { + setSummary(a.getTextArray(R.styleable.SliderPreference_android_summary)); + } catch (Exception e) { + // Do nothing + } + a.recycle(); + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getFloat(index, 0); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setValue(restoreValue ? getPersistedFloat(mValue) : (Float) defaultValue); + } + + @Override + public CharSequence getSummary() { + if (mSummaries != null && mSummaries.length > 0) { + int index = (int) (mValue * mSummaries.length); + index = Math.min(index, mSummaries.length - 1); + return mSummaries[index]; + } else { + return super.getSummary(); + } + } + + public void setSummary(CharSequence[] summaries) { + mSummaries = summaries; + } + + @Override + public void setSummary(CharSequence summary) { + super.setSummary(summary); + mSummaries = null; + } + + @Override + public void setSummary(int summaryResId) { + try { + setSummary(getContext().getResources().getStringArray(summaryResId)); + } catch (Exception e) { + super.setSummary(summaryResId); + } + } + + public float getValue() { + return mValue; + } + + public void setValue(float value) { + value = Math.max(0, Math.min(value, 1)); // clamp to [0, 1] + if (shouldPersist()) { + persistFloat(value); + } + if (value != mValue) { + mValue = value; + notifyChanged(); + } + } + + @Override + protected View onCreateDialogView() { + mSeekBarValue = (int) (mValue * SEEKBAR_RESOLUTION); + View view = super.onCreateDialogView(); + SeekBar seekbar = (SeekBar) view.findViewById(R.id.slider_preference_seekbar); + seekbar.setMax(SEEKBAR_RESOLUTION); + seekbar.setProgress(mSeekBarValue); + seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) { + SliderPreference.this.mSeekBarValue = progress; + callChangeListener((float) SliderPreference.this.mSeekBarValue / SEEKBAR_RESOLUTION); + } + } + }); + return view; + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + final float newValue = (float) mSeekBarValue / SEEKBAR_RESOLUTION; + if (positiveResult && callChangeListener(newValue)) { + setValue(newValue); + } else { + callChangeListener(mValue); + } + super.onDialogClosed(positiveResult); + } + + // TODO: Save and restore preference state. +} diff --git a/src/com/fsck/k9/view/MessageWebView.java b/src/com/fsck/k9/view/MessageWebView.java index 95aada387..192165dcd 100644 --- a/src/com/fsck/k9/view/MessageWebView.java +++ b/src/com/fsck/k9/view/MessageWebView.java @@ -109,7 +109,11 @@ public class MessageWebView extends RigidWebView { disableOverscrolling(); - webSettings.setTextSize(K9.getFontSizes().getMessageViewContent()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + webSettings.setTextZoom(K9.getFontSizes().getMessageViewContentAsPercent()); + } else { + webSettings.setTextSize(K9.getFontSizes().getMessageViewContent()); + } // Disable network images by default. This is overridden by preferences. blockNetworkData(true);