Kaydet (Commit) a149042c authored tarafından Mert Tumer's avatar Mert Tumer Kaydeden (comit) Tomaž Vajngerl

Ability to change Font Color and added a new Color Picker on Android Viewer

Change-Id: I1d22749a446e451196f0819322cb04ed7d7befae
Reviewed-on: https://gerrit.libreoffice.org/37840Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
Tested-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst 7299bdf0
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#231F20"
android:fillColor="#FFFFFFFF"
android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zM22.24,5.59L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#231F20"
android:fillColor="#FFFF"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M21,11H6.83l3.58,-3.59L9,6l-6,6 6,6 1.41,-1.41L6.83,13H21z"/>
</vector>
......@@ -86,6 +86,7 @@
</LinearLayout>
<include layout="@layout/toolbar_bottom"/>
<include layout="@layout/toolbar_color_picker"/>
<RelativeLayout
android:id="@+id/loadingPanel"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="35dp"
android:id="@+id/fontColorBox"
android:clickable="true"
android:scaleType="fitCenter"
/>
</RelativeLayout>
\ No newline at end of file
......@@ -168,6 +168,35 @@
app:srcCompat="@drawable/ic_superscript" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/font_color_picker"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Font Color"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:textSize="14dp"
android:gravity="center_vertical"
android:textColor="@color/fontBlack"
android:layout_alignParentLeft="true"
/>
<ImageButton
android:id="@+id/font_color_picker_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:gravity="center_vertical"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar_color_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/toolbar_background"
android:elevation="3dp"
android:orientation="vertical"
app:popupTheme="@style/LibreOfficeTheme.Toolbar"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:showIn="@layout/activity_main"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="vertical">
<ImageButton
android:id="@+id/button_go_back_color_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_back_black_24dp"
android:background="@drawable/image_button_background"
android:layout_marginBottom="10dp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fontColorView"
>
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fontColorViewSub"
android:layout_marginTop="20dp"
android:layout_below="@id/fontColorView"
android:layout_alignParentBottom="true">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
......@@ -98,5 +98,30 @@
<color name="handle_color">#26a69a</color>
<color name="button_selected_background">#33000000</color>
<color name="fontBlack">#000000</color>
<color name="fontDarkRed">#990000</color>
<color name="fontRed">#FF0000</color>
<color name="fontOrange">#FF8000</color>
<color name="fontYellow">#FFFF00</color>
<color name="fontGreen">#00FF00</color>
<color name="fontCyan">#00FFFF</color>
<color name="fontLightBlue">#0080FF</color>
<color name="fontBlue">#0000FF</color>
<color name="fontPurple">#990099</color>
<color name="fontPink">#FF00FF</color>
<integer-array name="fontcolors">
<item>@color/fontBlack</item>
<item>@color/fontDarkRed</item>
<item>@color/fontRed</item>
<item>@color/fontOrange</item>
<item>@color/fontYellow</item>
<item>@color/fontGreen</item>
<item>@color/fontCyan</item>
<item>@color/fontLightBlue</item>
<item>@color/fontBlue</item>
<item>@color/fontPurple</item>
<item>@color/fontPink</item>
</integer-array>
</resources>
package org.libreoffice;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
public class ColorPaletteAdapter extends RecyclerView.Adapter<ColorPaletteAdapter.ColorPaletteViewHolder> {
int[][] color_palette;
Context mContext;
int upperSelectedBox = -1;
int selectedBox = 0;
boolean animate;
ColorPaletteListener colorPaletteListener;
public ColorPaletteAdapter(Context mContext, ColorPaletteListener colorPaletteListener) {
this.mContext = mContext;
this.color_palette = new int[11][8];
this.colorPaletteListener = colorPaletteListener;
}
@Override
public ColorPaletteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = LayoutInflater.from(mContext).inflate(R.layout.colorbox, parent, false);
ColorPaletteViewHolder holder = new ColorPaletteViewHolder(item);
return holder;
}
public int getSelectedBox() {
return selectedBox;
}
@Override
public void onBindViewHolder(final ColorPaletteViewHolder holder, final int position) {
holder.colorBox.setBackgroundColor(color_palette[upperSelectedBox][position]);
if (selectedBox == position) {
holder.colorBox.setImageResource(R.drawable.ic_done_all_white_12dp);
} else {
holder.colorBox.setImageDrawable(null);
}
holder.colorBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setPosition(position);
}
});
if (animate) //it will only animate when the upper color box is selected
setAnimation(holder.colorBox);
}
private void setAnimation(View viewToAnimate) {
Animation animation = AnimationUtils.loadAnimation(mContext, android.R.anim.fade_in);
viewToAnimate.startAnimation(animation);
}
@Override
public int getItemCount() {
return color_palette[0].length;
}
private void setPosition(int position) {
this.selectedBox = position;
colorPaletteListener.applyColor(color_palette[upperSelectedBox][position]);
animate = false;
updateAdapter();
}
public void setPosition(int upperSelectedBox, int position) {
if (this.upperSelectedBox != upperSelectedBox) {
this.upperSelectedBox = upperSelectedBox;
this.selectedBox = position;
colorPaletteListener.applyColor(color_palette[upperSelectedBox][position]);
animate = true;
updateAdapter();
}
}
/*
this is for InvalidationHandler when .uno:FontColor is captured
*/
public void changePosition(int upperSelectedBox, int position) {
if(this.upperSelectedBox != upperSelectedBox){
this.upperSelectedBox = upperSelectedBox;
animate=true;
}
this.selectedBox = position;
updateAdapter();
}
public void setColorPalette(int[][] color_palette, int position1, int position2) {
this.color_palette = color_palette;
setPosition(position1, position2);
}
private void updateAdapter(){
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
ColorPaletteAdapter.this.notifyDataSetChanged();
}
});
}
class ColorPaletteViewHolder extends RecyclerView.ViewHolder {
ImageButton colorBox;
public ColorPaletteViewHolder(View itemView) {
super(itemView);
colorBox = (ImageButton) itemView.findViewById(R.id.fontColorBox);
}
}
}
\ No newline at end of file
package org.libreoffice;
public interface ColorPaletteListener {
void applyColor(int color);
void updateColorPickerPosition(int color);
}
package org.libreoffice;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.ColorPickerViewHolder> {
Context mContext;
ColorPaletteAdapter colorPaletteAdapter;
ColorPaletteListener colorPaletteListener;
int[] colorList;
int[][] colorPalette = new int[11][8];
int selectedBox = 0;
public ColorPickerAdapter(Context mContext, final ColorPaletteAdapter colorPaletteAdapter, ColorPaletteListener colorPaletteListener) {
this.mContext = mContext;
this.colorPaletteAdapter = colorPaletteAdapter;
this.colorPaletteListener = colorPaletteListener;
Resources r = mContext.getResources();
this.colorList = r.getIntArray(R.array.fontcolors);
initializeColorPalette();
}
@Override
public ColorPickerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = LayoutInflater.from(mContext).inflate(R.layout.colorbox, parent, false);
ColorPickerViewHolder holder = new ColorPickerViewHolder(item);
return holder;
}
@Override
public void onBindViewHolder(final ColorPickerViewHolder holder, final int position) {
holder.colorBox.setBackgroundColor(colorList[position]);
if (selectedBox != position)
holder.colorBox.setImageDrawable(null);
else {
holder.colorBox.setImageResource(R.drawable.ic_done_white_12dp);
}
holder.colorBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setPosition(position);
colorPaletteListener.applyColor(colorList[position]);
}
});
}
@Override
public int getItemCount() {
return colorList.length;
}
private void setPosition(int position) {
this.selectedBox = position;
selectSubColor(position, position==0?0:3);
colorPaletteListener.applyColor(colorList[position]);
updateAdapter();
}
private void selectSubColor(int position1, int position2) {
colorPaletteAdapter.setPosition(position1, position2);
}
private void initializeColorPalette() {
for (int i = 0; i < 11; i++) {
int red = Color.red(colorList[i]);
int green = Color.green(colorList[i]);
int blue = Color.blue(colorList[i]);
int red_tint = red;
int green_tint = green;
int blue_tint = blue;
int red_shade = red;
int green_shade = green;
int blue_shade = blue;
if (i != 0) {
colorPalette[i][3] = colorList[i];
for (int k = 2; k >= 0; k--) {
red_shade = (int) (red_shade * 0.75);
green_shade = (int) (green_shade * 0.75);
blue_shade = (int) (blue_shade * 0.75);
colorPalette[i][k] = (Color.rgb(red_shade, green_shade, blue_shade));
}
for (int k = 4; k < 7; k++) {
red_tint = (int) (red_tint + (255 - red_tint) * 0.45);
green_tint = (int) (green_tint + (255 - green_tint) * 0.45);
blue_tint = (int) (blue_tint + (255 - blue_tint) * 0.45);
colorPalette[i][k] = (Color.rgb(red_tint, green_tint, blue_tint));
}
} else {
colorPalette[0][0] = colorList[i];
for (int k = 1; k < 7; k++) {
red_tint = (int) (red_tint + (255 - red_tint) * 0.25);
green_tint = (int) (green_tint + (255 - green_tint) * 0.25);
blue_tint = (int) (blue_tint + (255 - blue_tint) * 0.25);
colorPalette[i][k] = (Color.rgb(red_tint, green_tint, blue_tint));
}
}
}
for (int i = 0; i < 11; i++){
this.colorPalette[i][7] = (Color.rgb(255, 255, 255)); // last one is always white
}
colorPaletteAdapter.setColorPalette(colorPalette, 0, 0);
}
public void findSelectedTextColor(int color) {
/*
Libreoffice recognizes -1 as Black
*/
if (color == -1) {
colorPaletteAdapter.changePosition(0, 0);
selectedBox = 0;
updateAdapter();
return;
}
/*
Find the color if the palette points another color
*/
if (colorPalette[selectedBox][colorPaletteAdapter.getSelectedBox()] != color) {
for (int i = 0; i < 11; i++) {
for (int k = 0; k < 8; k++) {
if (colorPalette[i][k] == color) {
colorPaletteAdapter.changePosition(i, k);
selectedBox = i;
updateAdapter();
return;
}
}
}
}
}
private void updateAdapter(){
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
ColorPickerAdapter.this.notifyDataSetChanged();
}
});
}
class ColorPickerViewHolder extends RecyclerView.ViewHolder {
ImageButton colorBox;
public ColorPickerViewHolder(View itemView) {
super(itemView);
this.colorBox = (ImageButton) itemView.findViewById(R.id.fontColorBox);
}
}
}
\ No newline at end of file
package org.libreoffice;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Rect;
import android.support.design.widget.BottomSheetBehavior;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import org.json.JSONArray;
......@@ -31,7 +39,38 @@ public class FontController implements AdapterView.OnItemSelectedListener {
public FontController(Activity activity) {
mActivity = activity;
}
private BottomSheetBehavior colorPickerBehavior;
private BottomSheetBehavior toolBarBottomBehavior;
private ColorPickerAdapter colorPickerAdapter;
ColorPaletteListener colorPaletteListener = new ColorPaletteListener() {
@Override
public void applyColor(int color) {
sendFontColorChange(color);
}
@Override
public void updateColorPickerPosition(int color) {
colorPickerAdapter.findSelectedTextColor(color);
changeFontColorBoxColor(color);
}
};
private void changeFontColorBoxColor(final int color){
final ImageButton fontColorPickerButton = (ImageButton)mActivity.findViewById(R.id.font_color_picker_button);
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
if(color == -1){ //Libreoffice recognizes -1 as black
fontColorPickerButton.setBackgroundColor(Color.BLACK);
}else{
fontColorPickerButton.setBackgroundColor(color);
}
}
});
}
private void sendFontChange(String fontName) {
try {
JSONObject json = new JSONObject();
......@@ -62,6 +101,23 @@ public class FontController implements AdapterView.OnItemSelectedListener {
}
}
private void sendFontColorChange(int color){
try {
JSONObject json = new JSONObject();
JSONObject valueJson = new JSONObject();
valueJson.put("type", "long");
valueJson.put("value", color);
json.put("Color", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Color", json.toString()));
changeFontColorBoxColor(color);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (mFontList == null || !mFontNameSpinnerSet)
......@@ -114,6 +170,7 @@ public class FontController implements AdapterView.OnItemSelectedListener {
public void run() {
setupFontNameSpinner();
setupFontSizeSpinner();
setupColorPicker();
}
});
}
......@@ -132,6 +189,64 @@ public class FontController implements AdapterView.OnItemSelectedListener {
fontSizeSpinner.setAdapter(dataAdapter);
}
private void setupColorPicker(){
RecyclerView recyclerView = (RecyclerView) mActivity.findViewById(R.id.fontColorView);
GridLayoutManager gridLayoutManager = new GridLayoutManager(mActivity, 11, GridLayoutManager.VERTICAL, true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(gridLayoutManager);
RecyclerView recyclerView2 = (RecyclerView) mActivity.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 = (RelativeLayout) mActivity.findViewById(R.id.font_color_picker);
ImageButton fontColorPickerButton = (ImageButton)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 toolbarColorPicker = (LinearLayout) mActivity.findViewById(R.id.toolbar_color_picker);
LinearLayout toolbarBottomLayout = (LinearLayout) mActivity.findViewById(R.id.toolbar_bottom);
colorPickerBehavior = BottomSheetBehavior.from(toolbarColorPicker);
toolBarBottomBehavior = BottomSheetBehavior.from(toolbarBottomLayout);
ImageButton pickerGoBackButton = (ImageButton)mActivity.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);
}
public void selectFont(final String fontName) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
......
......@@ -216,6 +216,8 @@ public class InvalidationHandler implements Document.MessageCallback {
mContext.getFormattingController().onToggleStateChanged(Document.BULLET_LIST, pressed);
} else if (parts[0].equals(".uno:DefaultNumbering")) {
mContext.getFormattingController().onToggleStateChanged(Document.NUMBERED_LIST, pressed);
} else if (parts[0].equals(".uno:Color")) {
mContext.getFontController().colorPaletteListener.updateColorPickerPosition(Integer.parseInt(value));
} else if (parts[0].equals(".uno:StatePageNumber")) {
// get the total page number and compare to the current value and update accordingly
String[] splitStrings = parts[1].split(" ");
......
......@@ -88,6 +88,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private String newDocumentType = null;
BottomSheetBehavior bottomToolbarSheetBehavior;
BottomSheetBehavior toolbarColorPickerBottomSheetBehavior;
private FormattingController mFormattingController;
private ToolbarController mToolbarController;
private FontController mFontController;
......@@ -231,8 +232,11 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
host.addTab(spec);
LinearLayout bottomToolbarLayout = (LinearLayout) findViewById(R.id.toolbar_bottom);
LinearLayout toolbarColorPickerLayout = (LinearLayout) findViewById(R.id.toolbar_color_picker);
bottomToolbarSheetBehavior = BottomSheetBehavior.from(bottomToolbarLayout);
toolbarColorPickerBottomSheetBehavior = BottomSheetBehavior.from(toolbarColorPickerLayout);
bottomToolbarSheetBehavior.setHideable(true);
toolbarColorPickerBottomSheetBehavior.setHideable(true);
}
// Loads a new Document
......@@ -514,7 +518,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
if (findViewById(R.id.toolbar_bottom).getVisibility() != View.VISIBLE) {
if (findViewById(R.id.toolbar_bottom).getVisibility() != View.VISIBLE
&& findViewById(R.id.toolbar_color_picker).getVisibility() != View.VISIBLE) {
showSoftKeyboardDirect();
}
}
......@@ -558,6 +563,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
@Override
public void run() {
bottomToolbarSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
toolbarColorPickerBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
findViewById(R.id.search_toolbar).setVisibility(View.GONE);
isFormattingToolbarOpen=false;
isSearchToolbarOpen=false;
......@@ -602,6 +608,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
} else {
showBottomToolbar();
findViewById(R.id.formatting_toolbar).setVisibility(View.GONE);
toolbarColorPickerBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
findViewById(R.id.search_toolbar).setVisibility(View.VISIBLE);
hideSoftKeyboardDirect();
isFormattingToolbarOpen=false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment