diff options
Diffstat (limited to 'android/source/src/java/org/libreoffice/FontController.java')
-rw-r--r-- | android/source/src/java/org/libreoffice/FontController.java | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/android/source/src/java/org/libreoffice/FontController.java b/android/source/src/java/org/libreoffice/FontController.java new file mode 100644 index 000000000..e0161076a --- /dev/null +++ b/android/source/src/java/org/libreoffice/FontController.java @@ -0,0 +1,449 @@ +package org.libreoffice; + +import android.graphics.Color; +import android.graphics.Rect; +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.Spinner; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +public class FontController implements AdapterView.OnItemSelectedListener { + + /** -1 as value in ".uno:Color" et al. means "automatic color"/no color set. */ + private static final int COLOR_AUTO = -1; + + private boolean mFontNameSpinnerSet = false; + private boolean mFontSizeSpinnerSet = false; + private final LibreOfficeMainActivity mActivity; + private final ArrayList<String> mFontList = new ArrayList<>(); + private final ArrayList<String> mFontSizes = new ArrayList<>(); + private final HashMap<String, ArrayList<String>> mAllFontSizes = new HashMap<>(); + + private String mCurrentFontSelected = null; + private String mCurrentFontSizeSelected = null; + + public FontController(LibreOfficeMainActivity activity) { + mActivity = activity; + } + private BottomSheetBehavior colorPickerBehavior; + private BottomSheetBehavior backColorPickerBehavior; + private BottomSheetBehavior toolBarBottomBehavior; + private ColorPickerAdapter colorPickerAdapter; + private ColorPickerAdapter backColorPickerAdapter; + + final ColorPaletteListener colorPaletteListener = new ColorPaletteListener() { + @Override + public void applyColor(int color) { + sendFontColorChange(color, false); + } + + @Override + public void updateColorPickerPosition(int color) { + if (colorPickerAdapter == null) { + return; + } + if (color == COLOR_AUTO) { + colorPickerAdapter.unselectColors(); + changeFontColorBoxColor(Color.TRANSPARENT); + return; + } + final int colorWithAlpha = color | 0xFF000000; + colorPickerAdapter.findSelectedTextColor(colorWithAlpha); + changeFontColorBoxColor(colorWithAlpha); + } + }; + + final ColorPaletteListener backColorPaletteListener = new ColorPaletteListener() { + @Override + public void applyColor(int color) { + sendFontBackColorChange(color, false); + } + + @Override + public void updateColorPickerPosition(int color) { + if (backColorPickerAdapter == null) { + return; + } + if (color == COLOR_AUTO) { + backColorPickerAdapter.unselectColors(); + changeFontBackColorBoxColor(Color.TRANSPARENT); + return; + } + final int colorWithAlpha = color | 0xFF000000; + backColorPickerAdapter.findSelectedTextColor(colorWithAlpha); + changeFontBackColorBoxColor(colorWithAlpha); + } + }; + + private void changeFontColorBoxColor(final int color){ + final ImageButton fontColorPickerButton = mActivity.findViewById(R.id.font_color_picker_button); + + LOKitShell.getMainHandler().post(new Runnable() { + @Override + public void run() { + fontColorPickerButton.setBackgroundColor(color); + } + }); + } + + private void changeFontBackColorBoxColor(final int color){ + final ImageButton fontBackColorPickerButton = mActivity.findViewById(R.id.font_back_color_picker_button); + + LOKitShell.getMainHandler().post(new Runnable() { + @Override + public void run() { + fontBackColorPickerButton.setBackgroundColor(color); + } + }); + } + + private void sendFontChange(String fontName) { + try { + JSONObject json = new JSONObject(); + JSONObject valueJson = new JSONObject(); + valueJson.put("type", "string"); + valueJson.put("value", fontName); + json.put("CharFontName.FamilyName", valueJson); + + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CharFontName", json.toString())); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void sendFontSizeChange(String fontSize) { + try { + JSONObject json = new JSONObject(); + JSONObject valueJson = new JSONObject(); + valueJson.put("type", "float"); + valueJson.put("value", fontSize); + json.put("FontHeight.Height", valueJson); + + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:FontHeight", json.toString())); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void sendFontColorChange(int color, boolean keepAlpha){ + try { + JSONObject json = new JSONObject(); + JSONObject valueJson = new JSONObject(); + valueJson.put("type", "long"); + valueJson.put("value", keepAlpha ? color : 0x00FFFFFF & color); + json.put("Color", valueJson); + + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Color", json.toString())); + changeFontColorBoxColor(color); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + /* + * 0x00FFFFFF & color operation removes the alpha which is FF, + * if we don't remove it, the color value becomes negative which is not recognized by LOK + */ + private void sendFontBackColorChange(int color, boolean keepAlpha) { + try { + JSONObject json = new JSONObject(); + JSONObject valueJson = new JSONObject(); + valueJson.put("type", "long"); + valueJson.put("value", keepAlpha ? color : 0x00FFFFFF & color); + if(mActivity.getTileProvider().isSpreadsheet()){ + json.put("BackgroundColor", valueJson); + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:BackgroundColor", json.toString())); + }else if(mActivity.getTileProvider().isPresentation()){ + json.put("CharBackColor", valueJson); + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CharBackColor", json.toString())); + }else { + json.put("BackColor", valueJson); + LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:BackColor", json.toString())); + } + + changeFontBackColorBoxColor(color); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + + @Override + public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { + if (mFontList.isEmpty() || !mFontNameSpinnerSet) + return; + if (parent == mActivity.findViewById(R.id.font_name_spinner)) { + String currentFontSelected = parent.getItemAtPosition(pos).toString(); + if (!currentFontSelected.equals(mCurrentFontSelected)) { + mCurrentFontSelected = currentFontSelected; + sendFontChange(mCurrentFontSelected); + } + } else if (parent == mActivity.findViewById(R.id.font_size_spinner)) { + String currentFontSizeSelected = parent.getItemAtPosition(pos).toString(); + if (!currentFontSizeSelected.equals(mCurrentFontSizeSelected)) { + mCurrentFontSizeSelected = currentFontSizeSelected; + sendFontSizeChange(mCurrentFontSizeSelected); + } + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + // Do nothing. + } + + public void parseJson(String json) { + mFontList.clear(); + mAllFontSizes.clear(); + try { + JSONObject jObject = new JSONObject(json); + JSONObject jObject2 = jObject.getJSONObject("commandValues"); + Iterator<String> keys = jObject2.keys(); + ArrayList<String> fontSizes; + while (keys.hasNext()) { + String key = keys.next(); + mFontList.add(key); + JSONArray array = jObject2.getJSONArray(key); + fontSizes = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + fontSizes.add(array.getString(i)); + } + mAllFontSizes.put(key, fontSizes); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void setupFontViews() { + LOKitShell.getMainHandler().post(new Runnable() { + public void run() { + setupFontNameSpinner(); + setupFontSizeSpinner(); + setupColorPicker(); + setupBackColorPicker(); + } + }); + } + + private void setupFontNameSpinner() { + Spinner fontSpinner = mActivity.findViewById(R.id.font_name_spinner); + ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(mActivity, android.R.layout.simple_spinner_item, mFontList); + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + fontSpinner.setAdapter(dataAdapter); + } + + private void setupFontSizeSpinner() { + Spinner fontSizeSpinner = mActivity.findViewById(R.id.font_size_spinner); + ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(mActivity, android.R.layout.simple_spinner_item, mFontSizes); + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + fontSizeSpinner.setAdapter(dataAdapter); + } + + private void setupColorPicker(){ + LinearLayout colorPickerLayout = mActivity.findViewById(R.id.toolbar_color_picker); + + RecyclerView recyclerView = colorPickerLayout.findViewById(R.id.fontColorView); + GridLayoutManager gridLayoutManager = new GridLayoutManager(mActivity, 11, GridLayoutManager.VERTICAL, true); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(gridLayoutManager); + + + + RecyclerView recyclerView2 = colorPickerLayout.findViewById(R.id.fontColorViewSub); + GridLayoutManager gridLayoutManager2 = new GridLayoutManager(mActivity,4); + recyclerView2.setHasFixedSize(true); + recyclerView2.addItemDecoration(new RecyclerView.ItemDecoration() { + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + outRect.bottom = 3; + outRect.top = 3; + outRect.left = 3; + outRect.right = 3; + } + }); + recyclerView2.setLayoutManager(gridLayoutManager2); + + ColorPaletteAdapter colorPaletteAdapter = new ColorPaletteAdapter(mActivity, colorPaletteListener); + recyclerView2.setAdapter(colorPaletteAdapter); + + this.colorPickerAdapter = new ColorPickerAdapter(mActivity, colorPaletteAdapter, colorPaletteListener); + recyclerView.setAdapter(colorPickerAdapter); + RelativeLayout fontColorPicker = mActivity.findViewById(R.id.font_color_picker); + ImageButton fontColorPickerButton = mActivity.findViewById(R.id.font_color_picker_button); + View.OnClickListener clickListener = new View.OnClickListener(){ + @Override + public void onClick(View view) { + toolBarBottomBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + colorPickerBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + mActivity.findViewById(R.id.search_toolbar).setVisibility(View.GONE); + } + }; + LinearLayout toolbarBottomLayout = mActivity.findViewById(R.id.toolbar_bottom); + colorPickerBehavior = BottomSheetBehavior.from(colorPickerLayout); + toolBarBottomBehavior = BottomSheetBehavior.from(toolbarBottomLayout); + + ImageButton pickerGoBackButton = colorPickerLayout.findViewById(R.id.button_go_back_color_picker); + pickerGoBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + toolBarBottomBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + colorPickerBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } + }); + + + fontColorPicker.setOnClickListener(clickListener); + fontColorPickerButton.setOnClickListener(clickListener); + + final Button autoColorButton = colorPickerLayout.findViewById(R.id.button_auto_color); + autoColorButton.setOnClickListener(view -> { + sendFontColorChange(COLOR_AUTO, true); + }); + } + + private void setupBackColorPicker(){ + LinearLayout backColorPickerLayout = mActivity.findViewById(R.id.toolbar_back_color_picker); + + RecyclerView recyclerView = backColorPickerLayout.findViewById(R.id.fontColorView); + GridLayoutManager gridLayoutManager = new GridLayoutManager(mActivity, 11, GridLayoutManager.VERTICAL, true); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(gridLayoutManager); + + + + RecyclerView recyclerView2 = backColorPickerLayout.findViewById(R.id.fontColorViewSub); + GridLayoutManager gridLayoutManager2 = new GridLayoutManager(mActivity,4); + recyclerView2.setHasFixedSize(true); + recyclerView2.addItemDecoration(new RecyclerView.ItemDecoration() { + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + outRect.bottom = 3; + outRect.top = 3; + outRect.left = 3; + outRect.right = 3; + } + }); + recyclerView2.setLayoutManager(gridLayoutManager2); + + ColorPaletteAdapter colorPaletteAdapter = new ColorPaletteAdapter(mActivity, backColorPaletteListener); + recyclerView2.setAdapter(colorPaletteAdapter); + + this.backColorPickerAdapter = new ColorPickerAdapter(mActivity, colorPaletteAdapter, backColorPaletteListener); + recyclerView.setAdapter(backColorPickerAdapter); + RelativeLayout fontColorPicker = mActivity.findViewById(R.id.font_back_color_picker); + ImageButton fontColorPickerButton = mActivity.findViewById(R.id.font_back_color_picker_button); + View.OnClickListener clickListener = new View.OnClickListener(){ + @Override + public void onClick(View view) { + toolBarBottomBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + backColorPickerBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + mActivity.findViewById(R.id.search_toolbar).setVisibility(View.GONE); + } + }; + LinearLayout toolbarBottomLayout = mActivity.findViewById(R.id.toolbar_bottom); + backColorPickerBehavior = BottomSheetBehavior.from(backColorPickerLayout); + toolBarBottomBehavior = BottomSheetBehavior.from(toolbarBottomLayout); + + ImageButton pickerGoBackButton = backColorPickerLayout.findViewById(R.id.button_go_back_color_picker); + pickerGoBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + toolBarBottomBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + backColorPickerBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } + }); + + + fontColorPicker.setOnClickListener(clickListener); + fontColorPickerButton.setOnClickListener(clickListener); + + final Button autoColorButton = backColorPickerLayout.findViewById(R.id.button_auto_color); + autoColorButton.setOnClickListener(view -> { + sendFontBackColorChange(COLOR_AUTO, true); + }); + } + + public void selectFont(final String fontName) { + LOKitShell.getMainHandler().post(new Runnable() { + public void run() { + selectFontCurrentThread(fontName); + } + }); + } + + private void selectFontCurrentThread(String fontName) { + Spinner spinner = mActivity.findViewById(R.id.font_name_spinner); + if (!mFontNameSpinnerSet) { + spinner.setOnItemSelectedListener(this); + mFontNameSpinnerSet = true; + } + + if (fontName.equals(mCurrentFontSelected)) + return; + + int position = mFontList.indexOf(fontName); + if (position != -1) { + mCurrentFontSelected = fontName; + spinner.setSelection(position,false); + } + + resetFontSizes(fontName); + } + + private void resetFontSizes(String fontName) { + if (mAllFontSizes.get(fontName) != null) { + mFontSizes.clear(); + mFontSizes.addAll(mAllFontSizes.get(fontName)); + Spinner spinner = mActivity.findViewById(R.id.font_size_spinner); + ArrayAdapter<?> arrayAdapter = (ArrayAdapter<?>)spinner.getAdapter(); + arrayAdapter.notifyDataSetChanged(); + } + } + + public void selectFontSize(final String fontSize) { + LOKitShell.getMainHandler().post(new Runnable() { + public void run() { + selectFontSizeCurrentThread(fontSize); + } + }); + } + + private void selectFontSizeCurrentThread(String fontSize) { + Spinner spinner = mActivity.findViewById(R.id.font_size_spinner); + if (!mFontSizeSpinnerSet) { + spinner.setOnItemSelectedListener(this); + mFontSizeSpinnerSet = true; + } + + if (fontSize.equals(mCurrentFontSizeSelected)) + return; + + int position = mFontSizes.indexOf(fontSize); + if (position != -1) { + mCurrentFontSizeSelected = fontSize; + spinner.setSelection(position, false); + } + } +} |