diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java index cd2828c3e0..3c7e8d3946 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -692,7 +692,6 @@ private void showHideActionBar() { final int marginBottom = hide ? 0 : (int) getResources().getDimension(R.dimen.textactions_bar_height); setMarginBottom(editScroll, marginBottom); setMarginBottom(viewScroll, marginBottom); - } } } diff --git a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java index f628333e60..72973cb3ce 100644 --- a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java +++ b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java @@ -44,6 +44,7 @@ import net.gsantner.markor.model.Document; import net.gsantner.markor.util.MarkorContextUtils; import net.gsantner.opoc.format.GsTextUtils; +import net.gsantner.opoc.frontend.GsSearchOrCustomTextDialog; import net.gsantner.opoc.util.GsCollectionUtils; import net.gsantner.opoc.util.GsContextUtils; import net.gsantner.opoc.util.GsFileUtils; @@ -76,6 +77,8 @@ public abstract class ActionButtonBase { protected AppSettings _appSettings; protected int _indent; + private final GsSearchOrCustomTextDialog.DialogState _specialKeyDialogState = new GsSearchOrCustomTextDialog.DialogState(); + public static final String ACTION_ORDER_PREF_NAME = "action_order"; private static final String ORDER_SUFFIX = "_order"; private static final String DISABLED_SUFFIX = "_disabled"; @@ -944,7 +947,7 @@ public void runSpecialKeyAction() { _hlEditor.requestFocus(); _hlEditor.setSelection(sel[0], sel[1]); - MarkorDialogFactory.showSpecialKeyDialog(getActivity(), (callbackPayload) -> { + MarkorDialogFactory.showSpecialKeyDialog(getActivity(), _specialKeyDialogState, (callbackPayload) -> { if (!_hlEditor.hasSelection() && _hlEditor.length() > 0) { _hlEditor.requestFocus(); } diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java index afa051b512..fa76f2fd19 100644 --- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java +++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java @@ -90,7 +90,7 @@ public class MarkdownTextConverter extends TextConverterBase { //######################## //## Injected CSS / JS / HTML //######################## - public static final String CSS_BODY = CSS_S + "body{margin:0;padding:1.25vh 2.5vw}" + CSS_E; + public static final String CSS_BODY = CSS_S + "body{margin:0;padding:0.25vh 3.5vw}" + CSS_E; public static final String CSS_HEADER_UNDERLINE = CSS_S + " .header_no_underline { text-decoration: none; color: " + TOKEN_BW_INVERSE_OF_THEME + "; } h1 < a.header_no_underline { border-bottom: 2px solid #eaecef; } " + CSS_E; public static final String CSS_H1_H2_UNDERLINE = CSS_S + " h1,h2 { border-bottom: 2px solid " + TOKEN_BW_INVERSE_OF_THEME_HEADER_UNDERLINE + "; } " + CSS_E; public static final String CSS_BLOCKQUOTE_VERTICAL_LINE = CSS_S + "blockquote{padding:0px 14px;border-" + TOKEN_TEXT_DIRECTION + ":3.5px solid #dddddd;margin:4px 0}" + CSS_E; diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index 62e44bc3e7..3607d122e9 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -74,18 +74,17 @@ public static AppSettings as() { return ApplicationObject.settings(); } - public static void showSpecialKeyDialog(Activity activity, GsCallback.a1 callback) { + public static void showSpecialKeyDialog(Activity activity, GsSearchOrCustomTextDialog.DialogState state, GsCallback.a1 callback) { DialogOptions dopt = new DialogOptions(); baseConf(activity, dopt); dopt.callback = callback; String[] actions = activity.getResources().getStringArray(R.array.textactions_press_key__text); dopt.data = new ArrayList<>(Arrays.asList(actions)); - dopt.dialogHeightDp = 530; dopt.titleText = R.string.special_key; dopt.isSearchEnabled = false; dopt.okButtonText = 0; - GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt); + GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt, state); } public static void showAsciidocSpecialKeyDialog(Activity activity, GsCallback.a1 callback) { @@ -115,15 +114,20 @@ public static void showInsertTableRowDialog(final Activity activity, final boole baseConf(activity, dopt); dopt.titleText = R.string.table; - dopt.messageText = activity.getString(R.string.how_much_columns_press_table_button_long_to_start_table); + dopt.messageText = activity.getString(R.string.how_much_columns_press_table_button_long_to_start_table) + "\n"; dopt.messageText += activity.getString(R.string.example_of_a_markdown_table) + ":\n\n"; - dopt.messageText += "| id | name | info |\n|-----|-----------|--------|\n| 1 | John | text |\n| 2 | Anna | text |\n"; + dopt.messageText += "" + + "| id | name | info |\n" + + "|----| ---- | ---- |\n" + + "| 1 | John | text |\n" + + "| 2 | Anna | text |"; dopt.callback = colsStr -> { as().setInt(PREF_LAST_USED_TABLE_SIZE, Integer.parseInt(colsStr)); callback.callback(Integer.parseInt(colsStr), isHeader); }; dopt.data = availableData; + dopt.isSoftInputVisible = false; dopt.searchInputType = InputType.TYPE_CLASS_NUMBER; dopt.highlightData = Collections.singletonList(Integer.toString(lastUsedTableSize)); dopt.searchHintText = R.string.search_or_custom; @@ -898,10 +902,11 @@ public static void showFontSizeDialog(final Activity activity, final int current DialogOptions dopt = new DialogOptions(); baseConf(activity, dopt); dopt.callback = (selectedDialogValueAsString -> callback.callback(Integer.parseInt(selectedDialogValueAsString))); - final int minFontSize = 1; + final int minFontSize = 5; final int maxFontSize = 36; final List sizes = new ArrayList<>(); for (int i = minFontSize; i <= maxFontSize; i++) { + if (i == currentSize) dopt.listPosition = i - minFontSize - 2; sizes.add(Integer.toString(i)); } dopt.data = sizes; diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsHorizontalScrollView.java b/app/src/main/java/net/gsantner/opoc/frontend/GsHorizontalScrollView.java new file mode 100644 index 0000000000..a9361862a3 --- /dev/null +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsHorizontalScrollView.java @@ -0,0 +1,45 @@ +package net.gsantner.opoc.frontend; + +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.HorizontalScrollView; + +import androidx.annotation.RequiresApi; + +public class GsHorizontalScrollView extends HorizontalScrollView { + + private int currentScrollX; // Current X scroll value in pixels + + public GsHorizontalScrollView(Context context) { + super(context); + } + + public GsHorizontalScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public GsHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public GsHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + if (currentScrollX > 0) { + // Restore previous X scroll value (horizontal position) + scrollTo(currentScrollX, 0); + } + } + + @Override + protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { + currentScrollX = scrollX; + super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); + } +} diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java index 1814a7e401..9d435cd6e8 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java @@ -18,6 +18,7 @@ import android.graphics.Color; import android.graphics.Typeface; import android.os.Build; +import android.os.Parcelable; import android.text.InputFilter; import android.text.InputType; import android.text.Spannable; @@ -125,6 +126,12 @@ public static class DialogOptions { public int dialogStyle = 0; } + public static class DialogState { + public int listPosition = -1; + public String defaultText = ""; + public Parcelable instanceState; + } + public static class Adapter extends BaseAdapter { @LayoutRes private final int _layout; @@ -241,7 +248,7 @@ public static boolean standardSearch(final CharSequence constraint, final CharSe return text.toString().toLowerCase(locale).contains(constraint.toString().toLowerCase(locale)); } - public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activity, final DialogOptions dopt) { + public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activity, final DialogOptions dopt, final DialogState state) { final int dialogStyle = dopt.dialogStyle != 0 ? dopt.dialogStyle : GsContextUtils.instance.getResId(activity, GsContextUtils.ResType.STYLE, dopt.isDarkDialog ? "Theme_AppCompat_Dialog" : "Theme_AppCompat_Light_Dialog"); final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, dialogStyle); @@ -284,6 +291,10 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi listView.setId(LIST_VIEW_ID); listView.setAdapter(listAdapter); + if (state != null && state.instanceState != null) { + listView.onRestoreInstanceState(state.instanceState); + } + if (dopt.listPosition >= 0) { listView.setSelection(dopt.listPosition); } @@ -294,9 +305,12 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi mainLayout.addView(listView, listLayout); dialogBuilder.setOnDismissListener((dialogInterface) -> { - // Update state - dopt.listPosition = listView.getFirstVisiblePosition(); - dopt.defaultText = searchEditText.getText().toString(); + if (state != null) { + // Store/Update dialog state + state.instanceState = listView.onSaveInstanceState(); + state.listPosition = listView.getFirstVisiblePosition(); + state.defaultText = searchEditText.getText().toString(); + } if (dopt.dismissCallback != null) { dopt.dismissCallback.callback(dialogInterface); @@ -446,6 +460,10 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi listView.setOnItemLongClickListener((parent, view, pos, id) -> directActivate.callback(pos)); } + public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activity, final DialogOptions dopt) { + showMultiChoiceDialogWithSearchFilterUI(activity, dopt, null); + } + private static View makeTitleView(final Context context, final DialogOptions dopt) { // We nest the title layout within a horizontal layout so we can add a select all button // We return the horizontal layout so that the select all button can be found by tag diff --git a/app/src/main/res/layout/document__fragment__edit.xml b/app/src/main/res/layout/document__fragment__edit.xml index 9f507b0dc8..7bd95f3cea 100644 --- a/app/src/main/res/layout/document__fragment__edit.xml +++ b/app/src/main/res/layout/document__fragment__edit.xml @@ -31,20 +31,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/background" - android:minHeight="1dp" android:gravity="top" android:imeOptions="flagNoExtractUi" android:inputType="textMultiLine|textCapSentences" + android:minHeight="1dp" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/editor_bottom_margin" android:scrollbars="none" android:textCursorDrawable="@drawable/cursor_accent" /> - - - + - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 4215b2263f..bea7dc1ab6 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,7 +1,7 @@ - 16dp - 12dp + 18dp + 16dp 32dp 8dp 46dp diff --git a/app/src/main/res/xml/preferences_master.xml b/app/src/main/res/xml/preferences_master.xml index c2e03f3721..d1e91fba35 100644 --- a/app/src/main/res/xml/preferences_master.xml +++ b/app/src/main/res/xml/preferences_master.xml @@ -298,7 +298,7 @@ android:icon="@drawable/ic_format_size_black_24dp" android:key="@string/pref_key__editor_font_size" android:max="36" - android:min="1" + android:min="5" android:summary="@string/control_font_size_in_editor" android:title="@string/font_size" app:showSeekBarValue="true" />