update gradle and implementations & rocker style

This commit is contained in:
Tungstend 2023-06-28 22:21:28 +08:00
parent ffbbdcb4df
commit ad6366e4ec
23 changed files with 1914 additions and 37 deletions

View File

@ -34,11 +34,11 @@ dependencies {
implementation project(path: ':FCLLibrary')
implementation project(path: ':FCLauncher')
implementation 'org.nanohttpd:nanohttpd:2.3.1'
implementation 'org.apache.commons:commons-compress:1.21'
implementation 'org.tukaani:xz:1.8'
implementation 'com.google.code.gson:gson:2.10'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'org.apache.commons:commons-compress:1.23.0'
implementation 'org.tukaani:xz:1.9'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'

View File

@ -1,4 +1,320 @@
package com.tungsten.fcl.control;
public class AddDirectionStyleDialog {
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ScrollView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.tungsten.fcl.R;
import com.tungsten.fcl.control.data.ButtonStyles;
import com.tungsten.fcl.control.data.ControlButtonStyle;
import com.tungsten.fcl.control.data.ControlDirectionStyle;
import com.tungsten.fcl.control.data.DirectionStyles;
import com.tungsten.fcl.util.FXUtils;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fcllibrary.component.dialog.FCLColorPickerDialog;
import com.tungsten.fcllibrary.component.dialog.FCLDialog;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLEditText;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLSeekBar;
import com.tungsten.fcllibrary.component.view.FCLSpinner;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import java.util.ArrayList;
public class AddDirectionStyleDialog extends FCLDialog implements View.OnClickListener {
private final Callback callback;
private FCLButton positive;
private FCLButton negative;
private FCLEditText editName;
private FCLSpinner<ControlDirectionStyle.Type> typeSpinner;
private ScrollView container;
private FCLLinearLayout buttonStyleLayout;
private FCLLinearLayout rockerStyleLayout;
private ControlDirectionStyle style = new ControlDirectionStyle("");
private ControlButtonStyle buttonStyle;
public interface Callback {
void onStyleAdd(ControlDirectionStyle style);
}
public AddDirectionStyleDialog(@NonNull Context context, Callback callback) {
super(context);
setContentView(R.layout.dialog_add_direction_style);
setCancelable(false);
this.callback = callback;
positive = findViewById(R.id.positive);
negative = findViewById(R.id.negative);
positive.setOnClickListener(this);
negative.setOnClickListener(this);
editName = findViewById(R.id.name);
typeSpinner = findViewById(R.id.type);
ArrayList<ControlDirectionStyle.Type> types = new ArrayList<>();
types.add(ControlDirectionStyle.Type.BUTTON);
types.add(ControlDirectionStyle.Type.ROCKER);
typeSpinner.setDataList(types);
ArrayList<String> typeString = new ArrayList<>();
typeString.add(getContext().getString(R.string.style_direction_button));
typeString.add(getContext().getString(R.string.style_direction_rocker));
ArrayAdapter<String> typeAdapter = new ArrayAdapter<>(getContext(), R.layout.item_spinner, typeString);
typeAdapter.setDropDownViewResource(R.layout.item_spinner_dropdown);
typeSpinner.setAdapter(typeAdapter);
container = findViewById(R.id.container);
buttonStyleLayout = (FCLLinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.view_direction_style_button, null);
rockerStyleLayout = (FCLLinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.view_direction_style_rocker, null);
style.nameProperty().bind(editName.stringProperty());
{
FCLSeekBar interval = buttonStyleLayout.findViewById(R.id.interval);
interval.addProgressListener();
FCLTextView intervalText = buttonStyleLayout.findViewById(R.id.interval_text);
interval.setProgress(style.getButtonStyle().getInterval());
style.getButtonStyle().intervalProperty().bindBidirectional(interval.progressProperty());
intervalText.stringProperty().bind(Bindings.createStringBinding(() -> interval.getProgress() / 10f + " %", interval.progressProperty()));
FCLTextView buttonStyleText = buttonStyleLayout.findViewById(R.id.button_style_text);
FCLButton buttonStyleSet = buttonStyleLayout.findViewById(R.id.set_button_style);
buttonStyle = ButtonStyles.getStyles().get(0);
buttonStyleText.setText(buttonStyle.getName());
buttonStyleText.stringProperty().bind(buttonStyle.nameProperty());
style.getButtonStyle().textSizeProperty().bind(buttonStyle.textSizeProperty());
style.getButtonStyle().textColorProperty().bind(buttonStyle.textColorProperty());
style.getButtonStyle().strokeWidthProperty().bind(buttonStyle.strokeWidthProperty());
style.getButtonStyle().strokeColorProperty().bind(buttonStyle.strokeColorProperty());
style.getButtonStyle().cornerRadiusProperty().bind(buttonStyle.cornerRadiusProperty());
style.getButtonStyle().fillColorProperty().bind(buttonStyle.fillColorProperty());
style.getButtonStyle().textSizePressedProperty().bind(buttonStyle.textSizePressedProperty());
style.getButtonStyle().textColorPressedProperty().bind(buttonStyle.textColorPressedProperty());
style.getButtonStyle().strokeWidthPressedProperty().bind(buttonStyle.strokeWidthPressedProperty());
style.getButtonStyle().strokeColorPressedProperty().bind(buttonStyle.strokeColorPressedProperty());
style.getButtonStyle().cornerRadiusPressedProperty().bind(buttonStyle.cornerRadiusPressedProperty());
style.getButtonStyle().fillColorPressedProperty().bind(buttonStyle.fillColorPressedProperty());
buttonStyleSet.setOnClickListener(v -> {
ButtonStyleDialog dialog = new ButtonStyleDialog(getContext(), true, buttonStyle, style -> {
buttonStyle.setName(style.getName());
buttonStyle.setTextSize(style.getTextSize());
buttonStyle.setTextColor(style.getTextColor());
buttonStyle.setStrokeWidth(style.getStrokeWidth());
buttonStyle.setStrokeColor(style.getStrokeColor());
buttonStyle.setCornerRadius(style.getCornerRadius());
buttonStyle.setFillColor(style.getFillColor());
buttonStyle.setTextSizePressed(style.getTextSizePressed());
buttonStyle.setTextColorPressed(style.getTextColorPressed());
buttonStyle.setStrokeWidthPressed(style.getStrokeWidthPressed());
buttonStyle.setStrokeColorPressed(style.getStrokeColorPressed());
buttonStyle.setCornerRadiusPressed(style.getCornerRadiusPressed());
buttonStyle.setFillColorPressed(style.getFillColorPressed());
});
dialog.show();
});
}
{
FCLSeekBar rockerSize = rockerStyleLayout.findViewById(R.id.rocker_size);
FCLSeekBar bgStrokeWidth = rockerStyleLayout.findViewById(R.id.bg_stroke_width);
FCLSeekBar bgCornerRadius = rockerStyleLayout.findViewById(R.id.bg_corner_radius);
FCLSeekBar strokeWidth = rockerStyleLayout.findViewById(R.id.stroke_width);
FCLSeekBar cornerRadius = rockerStyleLayout.findViewById(R.id.corner_radius);
rockerSize.addProgressListener();
bgStrokeWidth.addProgressListener();
bgCornerRadius.addProgressListener();
strokeWidth.addProgressListener();
cornerRadius.addProgressListener();
FCLTextView rockerSizeText = rockerStyleLayout.findViewById(R.id.rocker_size_text);
FCLTextView bgStrokeWidthText = rockerStyleLayout.findViewById(R.id.bg_stroke_width_text);
FCLTextView bgCornerRadiusText = rockerStyleLayout.findViewById(R.id.bg_corner_radius_text);
FCLTextView strokeWidthText = rockerStyleLayout.findViewById(R.id.stroke_width_text);
FCLTextView cornerRadiusText = rockerStyleLayout.findViewById(R.id.corner_radius_text);
rockerSize.setProgress(style.getRockerStyle().getRockerSize());
bgStrokeWidth.setProgress(style.getRockerStyle().getBgStrokeWidth());
bgCornerRadius.setProgress(style.getRockerStyle().getBgCornerRadius());
strokeWidth.setProgress(style.getRockerStyle().getRockerStrokeWidth());
cornerRadius.setProgress(style.getRockerStyle().getRockerCornerRadius());
style.getRockerStyle().rockerSizeProperty().bindBidirectional(rockerSize.progressProperty());
style.getRockerStyle().bgStrokeWidthProperty().bindBidirectional(bgStrokeWidth.progressProperty());
style.getRockerStyle().bgCornerRadiusProperty().bindBidirectional(bgCornerRadius.progressProperty());
style.getRockerStyle().rockerStrokeWidthProperty().bindBidirectional(strokeWidth.progressProperty());
style.getRockerStyle().rockerCornerRadiusProperty().bindBidirectional(cornerRadius.progressProperty());
rockerSizeText.stringProperty().bind(Bindings.createStringBinding(() -> rockerSize.getProgress() / 10f + " %", rockerSize.progressProperty()));
bgStrokeWidthText.stringProperty().bind(Bindings.createStringBinding(() -> bgStrokeWidth.getProgress() / 10f + " dp", bgStrokeWidth.progressProperty()));
bgCornerRadiusText.stringProperty().bind(Bindings.createStringBinding(() -> bgCornerRadius.getProgress() / 10f + " %", bgCornerRadius.progressProperty()));
strokeWidthText.stringProperty().bind(Bindings.createStringBinding(() -> strokeWidth.getProgress() / 10f + " dp", strokeWidth.progressProperty()));
cornerRadiusText.stringProperty().bind(Bindings.createStringBinding(() -> cornerRadius.getProgress() / 10f + " %", cornerRadius.progressProperty()));
FCLTextView bgStrokeColorText = rockerStyleLayout.findViewById(R.id.bg_stroke_color_text);
FCLTextView bgFillColorText = rockerStyleLayout.findViewById(R.id.bg_fill_color_text);
FCLTextView strokeColorText = rockerStyleLayout.findViewById(R.id.stroke_color_text);
FCLTextView fillColorText = rockerStyleLayout.findViewById(R.id.fill_color_text);
View bgStrokeColorView = rockerStyleLayout.findViewById(R.id.bg_stroke_color_view);
View bgFillColorView = rockerStyleLayout.findViewById(R.id.bg_fill_color_view);
View strokeColorView = rockerStyleLayout.findViewById(R.id.stroke_color_view);
View fillColorView = rockerStyleLayout.findViewById(R.id.fill_color_view);
FCLButton bgStrokeColorSet = rockerStyleLayout.findViewById(R.id.set_bg_stroke_color);
FCLButton bgFillColorSet = rockerStyleLayout.findViewById(R.id.set_bg_fill_color);
FCLButton strokeColorSet = rockerStyleLayout.findViewById(R.id.set_stroke_color);
FCLButton fillColorSet = rockerStyleLayout.findViewById(R.id.set_fill_color);
bgStrokeColorView.setBackgroundColor(style.getRockerStyle().getBgStrokeColor());
bgStrokeColorText.setText(getHex(style.getRockerStyle().getBgStrokeColor()));
bgFillColorView.setBackgroundColor(style.getRockerStyle().getBgFillColor());
bgFillColorText.setText(getHex(style.getRockerStyle().getBgFillColor()));
strokeColorView.setBackgroundColor(style.getRockerStyle().getRockerStrokeColor());
strokeColorText.setText(getHex(style.getRockerStyle().getRockerStrokeColor()));
fillColorView.setBackgroundColor(style.getRockerStyle().getRockerFillColor());
fillColorText.setText(getHex(style.getRockerStyle().getRockerFillColor()));
style.getRockerStyle().bgStrokeColorProperty().addListener(observable -> {
bgStrokeColorView.setBackgroundColor(style.getRockerStyle().getBgStrokeColor());
bgStrokeColorText.setText(getHex(style.getRockerStyle().getBgStrokeColor()));
});
style.getRockerStyle().bgFillColorProperty().addListener(observable -> {
bgFillColorView.setBackgroundColor(style.getRockerStyle().getBgFillColor());
bgFillColorText.setText(getHex(style.getRockerStyle().getBgFillColor()));
});
style.getRockerStyle().rockerStrokeColorProperty().addListener(observable -> {
strokeColorView.setBackgroundColor(style.getRockerStyle().getRockerStrokeColor());
strokeColorText.setText(getHex(style.getRockerStyle().getRockerStrokeColor()));
});
style.getRockerStyle().rockerFillColorProperty().addListener(observable -> {
fillColorView.setBackgroundColor(style.getRockerStyle().getRockerFillColor());
fillColorText.setText(getHex(style.getRockerStyle().getRockerFillColor()));
});
bgStrokeColorSet.setOnClickListener(v -> {
FCLColorPickerDialog dialog = new FCLColorPickerDialog(getContext(), style.getRockerStyle().getBgStrokeColor(), new FCLColorPickerDialog.Listener() {
@Override
public void onColorChanged(int color) {
}
@Override
public void onPositive(int destColor) {
style.getRockerStyle().setBgStrokeColor(destColor);
}
@Override
public void onNegative(int initColor) {
}
});
dialog.show();
});
bgFillColorSet.setOnClickListener(v -> {
FCLColorPickerDialog dialog = new FCLColorPickerDialog(getContext(), style.getRockerStyle().getBgFillColor(), new FCLColorPickerDialog.Listener() {
@Override
public void onColorChanged(int color) {
}
@Override
public void onPositive(int destColor) {
style.getRockerStyle().setBgFillColor(destColor);
}
@Override
public void onNegative(int initColor) {
}
});
dialog.show();
});
strokeColorSet.setOnClickListener(v -> {
FCLColorPickerDialog dialog = new FCLColorPickerDialog(getContext(), style.getRockerStyle().getRockerStrokeColor(), new FCLColorPickerDialog.Listener() {
@Override
public void onColorChanged(int color) {
}
@Override
public void onPositive(int destColor) {
style.getRockerStyle().setRockerStrokeColor(destColor);
}
@Override
public void onNegative(int initColor) {
}
});
dialog.show();
});
fillColorSet.setOnClickListener(v -> {
FCLColorPickerDialog dialog = new FCLColorPickerDialog(getContext(), style.getRockerStyle().getRockerFillColor(), new FCLColorPickerDialog.Listener() {
@Override
public void onColorChanged(int color) {
}
@Override
public void onPositive(int destColor) {
style.getRockerStyle().setRockerFillColor(destColor);
}
@Override
public void onNegative(int initColor) {
}
});
dialog.show();
});
}
container.addView(buttonStyleLayout);
typeSpinner.setSelection(0);
FXUtils.bindSelection(typeSpinner, style.styleTypeProperty());
style.styleTypeProperty().addListener(observable -> {
container.removeAllViewsInLayout();
if (style.styleTypeProperty().get() == ControlDirectionStyle.Type.BUTTON) {
container.addView(buttonStyleLayout);
} else {
container.addView(rockerStyleLayout);
}
});
}
private String getHex(int color) {
return "#" + String.format("%08X", (color));
}
@Override
public void onClick(View v) {
if (v == positive) {
if (DirectionStyles.getStyles().stream().anyMatch(it -> it.getName().equals(style.getName()))) {
Toast.makeText(getContext(), getContext().getString(R.string.style_warning_exist), Toast.LENGTH_SHORT).show();
} else if (StringUtils.isBlank(style.getName())) {
Toast.makeText(getContext(), getContext().getString(R.string.style_warning_name), Toast.LENGTH_SHORT).show();
} else {
dismiss();
callback.onStyleAdd(style);
}
}
if (v == negative) {
dismiss();
}
}
}

View File

@ -44,10 +44,16 @@ public class ButtonStyleAdapter extends FCLAdapter {
return selectedStyle.get();
}
public ButtonStyleAdapter(Context context, ObservableList<ControlButtonStyle> list, boolean select) {
public ButtonStyleAdapter(Context context, ObservableList<ControlButtonStyle> list, boolean select, ControlButtonStyle initStyle) {
super(context);
this.list = list;
this.select = select;
if (ButtonStyles.getStyles().stream().anyMatch(it -> it == initStyle)) {
selectedStyle.set(initStyle);
} else {
selectedStyle.set(list.get(0));
}
}
static class ViewHolder {

View File

@ -4,22 +4,35 @@ import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.tungsten.fcl.R;
import com.tungsten.fcl.control.data.ButtonStyles;
import com.tungsten.fcl.control.data.ControlButtonStyle;
import com.tungsten.fcllibrary.component.dialog.FCLDialog;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.HorizontalListView;
public class ButtonStyleDialog extends FCLDialog implements View.OnClickListener {
private final boolean select;
private final ControlButtonStyle initStyle;
private final Callback callback;
private FCLButton addStyle;
private FCLButton positive;
private HorizontalListView listView;
public ButtonStyleDialog(@NonNull Context context) {
public interface Callback {
void onStyleSelect(ControlButtonStyle style);
}
public ButtonStyleDialog(@NonNull Context context, boolean select, @Nullable ControlButtonStyle initStyle, Callback callback) {
super(context);
this.select = select;
this.initStyle = initStyle;
this.callback = callback;
setContentView(R.layout.dialog_manage_button_style);
setCancelable(false);
@ -32,8 +45,10 @@ public class ButtonStyleDialog extends FCLDialog implements View.OnClickListener
refreshList();
}
private ButtonStyleAdapter adapter;
public void refreshList() {
ButtonStyleAdapter adapter = new ButtonStyleAdapter(getContext(), ButtonStyles.getStyles(), false);
adapter = new ButtonStyleAdapter(getContext(), ButtonStyles.getStyles(), select, initStyle);
listView.setAdapter(adapter);
}
@ -48,6 +63,9 @@ public class ButtonStyleDialog extends FCLDialog implements View.OnClickListener
}
if (v == positive) {
dismiss();
if (callback != null && select) {
callback.onStyleSelect(adapter.getSelectedStyle());
}
}
}
}

View File

@ -1,4 +1,120 @@
package com.tungsten.fcl.control;
public class DirectionStyleAdapter {
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tungsten.fcl.R;
import com.tungsten.fcl.control.data.ControlDirectionStyle;
import com.tungsten.fcl.control.data.DirectionStyles;
import com.tungsten.fcl.control.view.ControlDirection;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fclcore.fakefx.collections.ObservableList;
import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog;
import com.tungsten.fcllibrary.component.view.FCLImageButton;
import com.tungsten.fcllibrary.component.view.FCLRadioButton;
import com.tungsten.fcllibrary.component.view.FCLTextView;
public class DirectionStyleAdapter extends FCLAdapter {
private final ObservableList<ControlDirectionStyle> list;
private final boolean select;
private final ObjectProperty<ControlDirectionStyle> selectedStyle = new SimpleObjectProperty<>(this, "style", null);
public ObjectProperty<ControlDirectionStyle> selectedStyleProperty() {
return selectedStyle;
}
public void setSelectedStyle(ControlDirectionStyle style) {
selectedStyle.set(style);
}
public ControlDirectionStyle getSelectedStyle() {
return selectedStyle.get();
}
public DirectionStyleAdapter(Context context, ObservableList<ControlDirectionStyle> list, boolean select, ControlDirectionStyle initStyle) {
super(context);
this.list = list;
this.select = select;
if (DirectionStyles.getStyles().stream().anyMatch(it -> it == initStyle)) {
selectedStyle.set(initStyle);
} else {
selectedStyle.set(list.get(0));
}
}
static class ViewHolder {
ControlDirection direction;
FCLTextView name;
FCLRadioButton radioButton;
FCLImageButton delete;
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public int getCount() {
return list.size();
}
@SuppressLint("ClickableViewAccessibility")
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
view = LayoutInflater.from(getContext()).inflate(R.layout.item_direction_style, null);
viewHolder.direction = view.findViewById(R.id.direction);
viewHolder.name = view.findViewById(R.id.name);
viewHolder.radioButton = view.findViewById(R.id.radio_button);
viewHolder.delete = view.findViewById(R.id.delete);
view.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) view.getTag();
}
ControlDirectionStyle style = list.get(i);
viewHolder.direction.getData().setStyle(style);
viewHolder.name.setText(style.getName());
if (select) {
viewHolder.radioButton.setVisibility(View.VISIBLE);
viewHolder.delete.setVisibility(View.GONE);
} else {
viewHolder.radioButton.setVisibility(View.GONE);
viewHolder.delete.setVisibility(View.VISIBLE);
}
viewHolder.radioButton.checkProperty().unbind();
viewHolder.radioButton.checkProperty().bind(Bindings.createBooleanBinding(() -> selectedStyle.get() == style, selectedStyle));
viewHolder.radioButton.setOnClickListener(view1 -> selectedStyle.set(style));
viewHolder.delete.setOnClickListener(view1 -> {
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setCancelable(false);
builder.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder.setMessage(getContext().getString(R.string.style_warning_delete));
builder.setPositiveButton(() -> {
DirectionStyles.removeStyles(style);
DirectionStyles.checkStyles();
notifyDataSetChanged();
});
builder.setNegativeButton(null);
builder.create().show();
});
return view;
}
}

View File

@ -1,4 +1,71 @@
package com.tungsten.fcl.control;
public class DirectionStyleDialog {
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.tungsten.fcl.R;
import com.tungsten.fcl.control.data.ControlDirectionStyle;
import com.tungsten.fcl.control.data.DirectionStyles;
import com.tungsten.fcllibrary.component.dialog.FCLDialog;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.HorizontalListView;
public class DirectionStyleDialog extends FCLDialog implements View.OnClickListener {
private final boolean select;
private final ControlDirectionStyle initStyle;
private final Callback callback;
private FCLButton addStyle;
private FCLButton positive;
private HorizontalListView listView;
public interface Callback {
void onStyleSelect(ControlDirectionStyle style);
}
public DirectionStyleDialog(@NonNull Context context, boolean select, @Nullable ControlDirectionStyle initStyle, Callback callback) {
super(context);
this.select = select;
this.initStyle = initStyle;
this.callback = callback;
setContentView(R.layout.dialog_manage_direction_style);
setCancelable(false);
addStyle = findViewById(R.id.add_style);
positive = findViewById(R.id.positive);
addStyle.setOnClickListener(this);
positive.setOnClickListener(this);
listView = findViewById(R.id.list);
refreshList();
}
private DirectionStyleAdapter adapter;
public void refreshList() {
adapter = new DirectionStyleAdapter(getContext(), DirectionStyles.getStyles(), select, initStyle);
listView.setAdapter(adapter);
}
@Override
public void onClick(View v) {
if (v == addStyle) {
AddDirectionStyleDialog dialog = new AddDirectionStyleDialog(getContext(), style -> {
DirectionStyles.addStyle(style);
refreshList();
});
dialog.show();
}
if (v == positive) {
dismiss();
if (callback != null && select) {
callback.onStyleSelect(adapter.getSelectedStyle());
}
}
}
}

View File

@ -561,11 +561,12 @@ public class GameMenu implements MenuCallback, View.OnClickListener {
}
if (v == manageButtonStyle) {
ButtonStyleDialog dialog = new ButtonStyleDialog(getActivity());
ButtonStyleDialog dialog = new ButtonStyleDialog(getActivity(), false, null, null);
dialog.show();
}
if (v == manageDirectionStyle) {
DirectionStyleDialog dialog = new DirectionStyleDialog(getActivity(), false, null, null);
dialog.show();
}
if (v == openMultiplayerMenu) {

View File

@ -107,7 +107,7 @@ public class DirectionEventData implements Cloneable, Observable {
}
/**
* Follow option
* Follow option (only rocker style)
*/
private final ObjectProperty<FollowOption> followOptionProperty = new SimpleObjectProperty<>(this, "followOption", FollowOption.CENTER_FOLLOW);

View File

@ -10,6 +10,7 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -130,8 +131,10 @@ public class ControlButton extends AppCompatButton {
(int) (screenWidth * (data.getBaseInfo().getPercentageHeight().getSize() / 1000f)) :
(int) (screenHeight * (data.getBaseInfo().getPercentageHeight().getSize() / 1000f));
}
setWidth(width);
setHeight(height);
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.width = width;
layoutParams.height = height;
setLayoutParams(layoutParams);
// Position
int x;
@ -147,6 +150,11 @@ public class ControlButton extends AppCompatButton {
(data.getBaseInfo().getVisibilityType() == BaseInfoData.VisibilityType.IN_GAME && menu.getCursorMode() == FCLBridge.CursorDisabled) ||
(data.getBaseInfo().getVisibilityType() == BaseInfoData.VisibilityType.MENU && menu.getCursorMode() == FCLBridge.CursorEnabled)),
menu.cursorModeProperty(), parentVisibilityProperty()));
visibilityProperty().addListener(observable -> {
if (!visibilityProperty.get()) {
cancelAllEvent();
}
});
}
private GradientDrawable drawableNormal;
@ -247,7 +255,12 @@ public class ControlButton extends AppCompatButton {
if (System.currentTimeMillis() - downTime <= 100
&& Math.abs(event.getX() - downX) <= 10
&& Math.abs(event.getY() - downY) <= 10) {
setX(positionX);
setY(positionY);
} else {
getData().getBaseInfo().setXPosition((int) ((1000 * (getX() + (getMeasuredWidth() / 2))) / screenWidth));
getData().getBaseInfo().setYPosition((int) ((1000 * (getY() + (getMeasuredHeight() / 2))) / screenHeight));
}
break;
}

View File

@ -1,14 +1,703 @@
package com.tungsten.fcl.control.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatButton;
import com.tungsten.fcl.FCLApplication;
import com.tungsten.fcl.control.GameMenu;
import com.tungsten.fcl.control.data.BaseInfoData;
import com.tungsten.fcl.control.data.ControlDirectionData;
import com.tungsten.fcl.control.data.ControlDirectionStyle;
import com.tungsten.fcl.control.data.DirectionEventData;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fclauncher.bridge.FCLBridge;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.BooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.BooleanPropertyBase;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fcllibrary.util.ConvertUtils;
import java.util.UUID;
/**
* Custom control direction view.
*/
public class ControlDirection extends View {
@SuppressLint("ViewConstructor")
public class ControlDirection extends RelativeLayout {
public ControlDirection(Context context) {
@Nullable
private final GameMenu menu;
private final boolean displayMode;
private final Path boundaryPath;
private final Paint boundaryPaint;
private final int screenWidth;
private final int screenHeight;
private static final double ANGLE_0 = 0;
private static final double ANGLE_360 = 360;
private static final double ANGLE_8D_OF_0P = 22.5;
private static final double ANGLE_8D_OF_1P = 67.5;
private static final double ANGLE_8D_OF_2P = 112.5;
private static final double ANGLE_8D_OF_3P = 157.5;
private static final double ANGLE_8D_OF_4P = 202.5;
private static final double ANGLE_8D_OF_5P = 247.5;
private static final double ANGLE_8D_OF_6P = 292.5;
private static final double ANGLE_8D_OF_7P = 337.5;
private BooleanProperty visibilityProperty;
private final BooleanProperty parentVisibilityProperty = new SimpleBooleanProperty(this, "parentVisibility", true);
public BooleanProperty parentVisibilityProperty() {
return parentVisibilityProperty;
}
public void setParentVisibility(boolean parentVisibility) {
parentVisibilityProperty.set(parentVisibility);
}
public boolean isParentVisibility() {
return parentVisibilityProperty.get();
}
private final ObjectProperty<ControlDirectionData> dataProperty = new SimpleObjectProperty<>(this, "data", new ControlDirectionData(UUID.randomUUID().toString()));
public ObjectProperty<ControlDirectionData> dataProperty() {
return dataProperty;
}
public void setData(ControlDirectionData data) {
dataProperty.set(data);
}
public ControlDirectionData getData() {
return dataProperty.get();
}
public ControlDirection(Context context, @Nullable GameMenu menu, boolean displayMode) {
super(context);
this.menu = menu;
this.displayMode = displayMode;
setClickable(true);
boundaryPath = new Path();
boundaryPaint = new Paint();
boundaryPaint.setAntiAlias(true);
boundaryPaint.setColor(Color.RED);
boundaryPaint.setStyle(Paint.Style.STROKE);
boundaryPaint.setStrokeWidth(3);
screenWidth = AndroidUtils.getScreenWidth(FCLApplication.getCurrentActivity());
screenHeight = AndroidUtils.getScreenHeight(FCLApplication.getCurrentActivity());
post(() -> {
notifyData();
if (menu != null) {
menu.editModeProperty().addListener(invalidate -> cancelAllEvent());
}
dataProperty.addListener(invalidate -> Schedulers.androidUIThread().execute(() -> {
notifyData();
cancelAllEvent();
}));
if (menu != null) {
menu.showViewBoundariesProperty().addListener(invalidate -> invalidate());
}
});
}
public ControlDirection(Context context, AttributeSet attrs) {
super(context, attrs);
this.menu = null;
this.displayMode = true;
setClickable(true);
boundaryPath = new Path();
boundaryPaint = new Paint();
boundaryPaint.setAntiAlias(true);
boundaryPaint.setColor(Color.RED);
boundaryPaint.setStyle(Paint.Style.STROKE);
boundaryPaint.setStrokeWidth(3);
screenWidth = AndroidUtils.getScreenWidth(FCLApplication.getCurrentActivity());
screenHeight = AndroidUtils.getScreenHeight(FCLApplication.getCurrentActivity());
post(() -> {
notifyData();
dataProperty.addListener(invalidate -> Schedulers.androidUIThread().execute(this::notifyData));
});
}
private void notifyData() {
ControlDirectionData data = getData();
refreshBaseInfo(data);
refreshStyle(data);
}
public void setSize(int size) {
ViewGroup.LayoutParams params = getLayoutParams();
params.width = size;
params.height = size;
setLayoutParams(params);
}
private void refreshBaseInfo(ControlDirectionData data) {
// Size
int size;
if (data.getBaseInfo().getSizeType() == BaseInfoData.SizeType.ABSOLUTE) {
size = ConvertUtils.dip2px(getContext(), data.getBaseInfo().getAbsoluteWidth());
} else {
size = data.getBaseInfo().getPercentageWidth().getReference() == BaseInfoData.PercentageSize.Reference.SCREEN_WIDTH ?
(int) (screenWidth * (data.getBaseInfo().getPercentageWidth().getSize() / 1000f)) :
(int) (screenHeight * (data.getBaseInfo().getPercentageWidth().getSize() / 1000f));
}
setSize(size);
// Position
int x;
int y;
x = (int) (screenWidth * (data.getBaseInfo().getXPosition() / 1000f)) - (size / 2);
y = (int) (screenHeight * (data.getBaseInfo().getYPosition() / 1000f)) - (size / 2);
if (!displayMode) {
setX(x);
setY(y);
}
// Visibility
if (!displayMode && menu != null) {
visibilityProperty().unbind();
visibilityProperty().bind(Bindings.createBooleanBinding(() -> isParentVisibility() && (data.getBaseInfo().getVisibilityType() == BaseInfoData.VisibilityType.ALWAYS ||
(data.getBaseInfo().getVisibilityType() == BaseInfoData.VisibilityType.IN_GAME && menu.getCursorMode() == FCLBridge.CursorDisabled) ||
(data.getBaseInfo().getVisibilityType() == BaseInfoData.VisibilityType.MENU && menu.getCursorMode() == FCLBridge.CursorEnabled)),
menu.cursorModeProperty(), parentVisibilityProperty()));
visibilityProperty().addListener(observable -> {
if (!visibilityProperty.get()) {
cancelAllEvent();
}
});
}
}
private final AppCompatButton centerBtn = new AppCompatButton(getContext());
private final AppCompatButton upBtn = new AppCompatButton(getContext());
private final AppCompatButton downBtn = new AppCompatButton(getContext());
private final AppCompatButton leftBtn = new AppCompatButton(getContext());
private final AppCompatButton rightBtn = new AppCompatButton(getContext());
private final AppCompatButton upLeftBtn = new AppCompatButton(getContext());
private final AppCompatButton upRightBtn = new AppCompatButton(getContext());
private final AppCompatButton downLeftBtn = new AppCompatButton(getContext());
private final AppCompatButton downRightBtn = new AppCompatButton(getContext());
private final AppCompatButton[] buttons = new AppCompatButton[] {
centerBtn,
upBtn,
downBtn,
leftBtn,
rightBtn,
upLeftBtn,
upRightBtn,
downLeftBtn,
downRightBtn
};
private final AppCompatButton area = new AppCompatButton(getContext());
private final AppCompatButton rocker = new AppCompatButton(getContext());
private int rockerSize;
private GradientDrawable drawableNormal;
private GradientDrawable drawablePressed;
private void refreshStyle(ControlDirectionData data) {
if (data.getStyle().getStyleType() == ControlDirectionStyle.Type.BUTTON) {
int size = (getMeasuredWidth() * (1000 - (2 * getData().getStyle().getButtonStyle().getInterval()))) / 3000;
int p0 = 0;
int p1 = size + ((getMeasuredWidth() * getData().getStyle().getButtonStyle().getInterval()) / 1000);
int p2 = getMeasuredWidth() - size;
drawableNormal = new GradientDrawable();
drawableNormal.setCornerRadius(ConvertUtils.dip2px(getContext(), data.getStyle().getButtonStyle().getCornerRadius() / 10f));
drawableNormal.setStroke(ConvertUtils.dip2px(getContext(), data.getStyle().getButtonStyle().getStrokeWidth() / 10f), data.getStyle().getButtonStyle().getStrokeColor());
drawableNormal.setColor(data.getStyle().getButtonStyle().getFillColor());
drawablePressed = new GradientDrawable();
drawablePressed.setCornerRadius(ConvertUtils.dip2px(getContext(), data.getStyle().getButtonStyle().getCornerRadiusPressed() / 10f));
drawablePressed.setStroke(ConvertUtils.dip2px(getContext(), data.getStyle().getButtonStyle().getStrokeWidthPressed() / 10f), data.getStyle().getButtonStyle().getStrokeColorPressed());
drawablePressed.setColor(data.getStyle().getButtonStyle().getFillColorPressed());
removeAllViews();
for (AppCompatButton b : buttons) {
addView(b);
ViewGroup.LayoutParams layoutParams = b.getLayoutParams();
layoutParams.width = size;
layoutParams.height = size;
b.setClickable(false);
b.setLayoutParams(layoutParams);
b.setGravity(Gravity.CENTER);
b.setPadding(0, 0, 0, 0);
b.setAllCaps(false);
b.setTextSize(data.getStyle().getButtonStyle().getTextSize());
b.setTextColor(data.getStyle().getButtonStyle().getTextColor());
b.setBackground(drawableNormal);
}
setButtonPosition(centerBtn, p1, p1);
setButtonPosition(upBtn, p1, p0);
setButtonPosition(downBtn, p1, p2);
setButtonPosition(leftBtn, p0, p1);
setButtonPosition(rightBtn, p2, p1);
setButtonPosition(upLeftBtn, p0, p0);
setButtonPosition(upRightBtn, p2, p0);
setButtonPosition(downLeftBtn, p0, p2);
setButtonPosition(downRightBtn, p2, p2);
centerBtn.setText("");
upBtn.setText("");
downBtn.setText("");
leftBtn.setText("");
rightBtn.setText("");
upLeftBtn.setText("");
upRightBtn.setText("");
downLeftBtn.setText("");
downRightBtn.setText("");
upLeftBtn.setVisibility(GONE);
upRightBtn.setVisibility(GONE);
downLeftBtn.setVisibility(GONE);
downRightBtn.setVisibility(GONE);
} else {
rockerSize = (getMeasuredWidth() * getData().getStyle().getRockerStyle().getRockerSize()) / 1000;
GradientDrawable drawableArea = new GradientDrawable();
drawableArea.setCornerRadius((float) (getMeasuredWidth() * data.getStyle().getRockerStyle().getBgCornerRadius()) / 1000);
drawableArea.setStroke(ConvertUtils.dip2px(getContext(), data.getStyle().getRockerStyle().getBgStrokeWidth() / 10f), data.getStyle().getRockerStyle().getBgStrokeColor());
drawableArea.setColor(data.getStyle().getRockerStyle().getBgFillColor());
GradientDrawable drawableRocker = new GradientDrawable();
drawableRocker.setCornerRadius((float) (rockerSize * data.getStyle().getRockerStyle().getRockerCornerRadius()) / 1000);
drawableRocker.setStroke(ConvertUtils.dip2px(getContext(), data.getStyle().getRockerStyle().getRockerStrokeWidth() / 10f), data.getStyle().getRockerStyle().getRockerStrokeColor());
drawableRocker.setColor(data.getStyle().getRockerStyle().getRockerFillColor());
removeAllViews();
addView(area, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
addView(rocker, new LayoutParams(rockerSize, rockerSize));
area.setClickable(false);
rocker.setClickable(false);
area.setBackground(drawableArea);
rocker.setBackground(drawableRocker);
setButtonPosition(area, 0, 0);
setButtonPosition(rocker, (getMeasuredWidth() / 2) - (rockerSize / 2), (getMeasuredWidth() / 2) - (rockerSize / 2));
}
}
private void setButtonPosition(AppCompatButton button, int x, int y) {
button.setX(x);
button.setY(y);
}
private void setButtonStyle(AppCompatButton button, boolean press) {
if (press) {
button.setTextSize(getData().getStyle().getButtonStyle().getTextSizePressed());
button.setTextColor(getData().getStyle().getButtonStyle().getTextColorPressed());
button.setBackground(drawablePressed);
} else {
button.setTextSize(getData().getStyle().getButtonStyle().getTextSize());
button.setTextColor(getData().getStyle().getButtonStyle().getTextColor());
button.setBackground(drawableNormal);
}
}
@Override
public void requestLayout() {
super.requestLayout();
post(() -> {
measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (menu != null && menu.isShowViewBoundaries() && !displayMode) {
boundaryPath.moveTo(0, 0);
boundaryPath.lineTo(getWidth(), 0);
boundaryPath.lineTo(getWidth(), getHeight());
boundaryPath.lineTo(0, getHeight());
boundaryPath.lineTo(0, 0);
canvas.drawPath(boundaryPath, boundaryPaint);
}
}
private float downX;
private float downY;
private float positionX;
private float positionY;
private long downTime;
private int clickCount = 0;
private long firstClickTime;
private boolean doubleClickEvent = false;
private boolean startClick = false;
private final Handler handler = new Handler();
private final Runnable deleteRunnable = () -> {
};
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (menu != null && menu.isEditMode()) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
positionX = getX();
positionY = getY();
downTime = System.currentTimeMillis();
handler.postDelayed(deleteRunnable, 400);
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) ((event.getX() - downX) * menu.getMenuSetting().getMouseSensitivity());
int deltaY = (int) ((event.getY() - downY) * menu.getMenuSetting().getMouseSensitivity());
float targetX = Math.max(0, Math.min(screenWidth - getWidth(), positionX + deltaX));
float targetY = Math.max(0, Math.min(screenHeight - getHeight(), positionY + deltaY));
setX(targetX);
setY(targetY);
if ((Math.abs(event.getX() - downX) > 1 || Math.abs(event.getY() - downY) > 1) && System.currentTimeMillis() - downTime < 400) {
handler.removeCallbacks(deleteRunnable);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
handler.removeCallbacks(deleteRunnable);
if (System.currentTimeMillis() - downTime <= 100
&& Math.abs(event.getX() - downX) <= 10
&& Math.abs(event.getY() - downY) <= 10) {
setX(positionX);
setY(positionY);
} else {
getData().getBaseInfo().setXPosition((int) ((1000 * (getX() + (getMeasuredWidth() / 2))) / screenWidth));
getData().getBaseInfo().setYPosition((int) ((1000 * (getY() + (getMeasuredHeight() / 2))) / screenHeight));
}
break;
}
} else if (menu != null && !menu.isEditMode()) {
if (getData().getStyle().getStyleType() == ControlDirectionStyle.Type.BUTTON) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
downTime = System.currentTimeMillis();
handleButtonEvent((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_MOVE:
handleButtonEvent((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (System.currentTimeMillis() - downTime <= 100
&& Math.abs(event.getX() - downX) <= 10
&& Math.abs(event.getY() - downY) <= 10) {
clickCount++;
if (clickCount == 1) {
firstClickTime = System.currentTimeMillis();
}
if (clickCount == 2) {
if (System.currentTimeMillis() - firstClickTime < 400) {
handleDoubleEvent(!doubleClickEvent);
clickCount = 0;
} else {
clickCount = 1;
firstClickTime = System.currentTimeMillis();
}
}
}
cancelAllEvent();
break;
}
} else {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
if (getData().getEvent().getFollowOption() == DirectionEventData.FollowOption.FOLLOW ||
(getData().getEvent().getFollowOption() == DirectionEventData.FollowOption.CENTER_FOLLOW
&& event.getX() >= (float) ((getMeasuredWidth() / 2) - (rockerSize / 2))
&& event.getX() <= (float) ((getMeasuredWidth() / 2) + (rockerSize / 2))
&& event.getY() >= (float) ((getMeasuredWidth() / 2) - (rockerSize / 2))
&& event.getY() <= (float) ((getMeasuredWidth() / 2) + (rockerSize / 2)))) {
downX = event.getX();
downY = event.getY();
downTime = System.currentTimeMillis();
startClick = true;
int deltaX = (int) (event.getX() - (getMeasuredWidth() / 2));
int deltaY = (int) (event.getY() - (getMeasuredWidth() / 2));
int targetX = (int) (getX() + deltaX);
int targetY = (int) (getY() + deltaY);
setX(targetX);
setY(targetY);
} else {
startClick = false;
handleRockerEvent((int) event.getX(), (int) event.getY());
}
break;
case MotionEvent.ACTION_MOVE:
handleRockerEvent((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (startClick
&& System.currentTimeMillis() - downTime <= 100
&& Math.abs(event.getX() - downX) <= 10
&& Math.abs(event.getY() - downY) <= 10) {
startClick = false;
clickCount++;
if (clickCount == 1) {
firstClickTime = System.currentTimeMillis();
}
if (clickCount == 2) {
if (System.currentTimeMillis() - firstClickTime < 400) {
handleDoubleEvent(!doubleClickEvent);
clickCount = 0;
} else {
clickCount = 1;
firstClickTime = System.currentTimeMillis();
}
}
}
cancelAllEvent();
break;
}
}
} else {
return true;
}
return true;
}
private void handleButtonEvent(int x, int y) {
int size = (getMeasuredWidth() * (1000 - (2 * getData().getStyle().getButtonStyle().getInterval()))) / 3000;
int p1 = size + ((getMeasuredWidth() * getData().getStyle().getButtonStyle().getInterval()) / 1000);
int p2 = getMeasuredWidth() - size;
if (x <= size && y <= size) {
// up left
handleMoveEvent(true, false, true, false);
} else if (x >= p1 && x <= p1 + size && y <= size) {
// up
handleMoveEvent(true, false, false, false);
} else if (x >= p2 && y <= size) {
// up right
handleMoveEvent(true, false, false, true);
} else if (x <= size && y >= p1 && y <= p1 + size) {
// left
handleMoveEvent(false, false, true, false);
} else if (x >= p1 && x <= p1 + size && y >= p1 && y <= p1 + size) {
// center
handleMoveEvent(false, false, false, false);
} else if (x >= p2 && y >= p1 && y <= p1 + size) {
// right
handleMoveEvent(false, false, false, true);
} else if (x < size && y >= p2) {
// down left
handleMoveEvent(false, true, true, false);
} else if (x >= p1 && x <= p1 + size && y >= p2) {
// down
handleMoveEvent(false, true, false, false);
} else if (x >= p2 && y >= p2) {
// down right
handleMoveEvent(false, true, false, true);
}
}
private void handleRockerEvent(int x, int y) {
int maxDistance = (getMeasuredWidth() / 2) - (rockerSize / 2);
Point centerPoint = new Point(getMeasuredWidth() / 2, getMeasuredWidth() / 2);
Point touchPoint = new Point(x, y);
Point position = getRockerPositionPoint(centerPoint, touchPoint, maxDistance);
rocker.setX(position.x - (float) (rockerSize / 2));
rocker.setY(position.y - (float) (rockerSize / 2));
}
private Point getRockerPositionPoint(Point centerPoint, Point touchPoint, float maxDistance) {
float lenX = (float) (touchPoint.x - centerPoint.x);
float lenY = (float) (touchPoint.y - centerPoint.y);
float lenXY = (float) Math.sqrt(lenX * lenX + lenY * lenY);
double radian = Math.acos(lenX / lenXY) * (touchPoint.y < centerPoint.y ? -1 : 1);
double angle = ConvertUtils.radian2Angle(radian);
if (lenXY <= maxDistance) {
handleAngleEvent(angle);
return touchPoint;
} else {
int showPointX = (int) (centerPoint.x + maxDistance * Math.cos(radian));
int showPointY = (int) (centerPoint.y + maxDistance * Math.sin(radian));
handleAngleEvent(angle);
return new Point(showPointX, showPointY);
}
}
public enum Direction {
DIRECTION_LEFT,
DIRECTION_RIGHT,
DIRECTION_UP,
DIRECTION_DOWN,
DIRECTION_UP_LEFT,
DIRECTION_UP_RIGHT,
DIRECTION_DOWN_LEFT,
DIRECTION_DOWN_RIGHT,
DIRECTION_CENTER
}
private Direction tempDirection = Direction.DIRECTION_CENTER;
private void handleAngleEvent(double angle) {
if (menu != null) {
if ((ANGLE_0 <= angle && ANGLE_8D_OF_0P > angle || ANGLE_8D_OF_7P <= angle && ANGLE_360 > angle) && tempDirection != Direction.DIRECTION_RIGHT) {
// right
tempDirection = Direction.DIRECTION_RIGHT;
handleMoveEvent(false, false, false, true);
} else if (ANGLE_8D_OF_0P <= angle && ANGLE_8D_OF_1P > angle && tempDirection != Direction.DIRECTION_DOWN_RIGHT) {
// down right
tempDirection = Direction.DIRECTION_DOWN_RIGHT;
handleMoveEvent(false, true, false, true);
} else if (ANGLE_8D_OF_1P <= angle && ANGLE_8D_OF_2P > angle && tempDirection != Direction.DIRECTION_DOWN) {
// down
tempDirection = Direction.DIRECTION_DOWN;
handleMoveEvent(false, true, false, false);
} else if (ANGLE_8D_OF_2P <= angle && ANGLE_8D_OF_3P > angle && tempDirection != Direction.DIRECTION_DOWN_LEFT) {
// down left
tempDirection = Direction.DIRECTION_DOWN_LEFT;
handleMoveEvent(false, true, true, false);
} else if (ANGLE_8D_OF_3P <= angle && ANGLE_8D_OF_4P > angle && tempDirection != Direction.DIRECTION_LEFT) {
// left
tempDirection = Direction.DIRECTION_LEFT;
handleMoveEvent(false, false, true, false);
} else if (ANGLE_8D_OF_4P <= angle && ANGLE_8D_OF_5P > angle && tempDirection != Direction.DIRECTION_UP_LEFT) {
// up left
tempDirection = Direction.DIRECTION_UP_LEFT;
handleMoveEvent(true, false, true, false);
} else if (ANGLE_8D_OF_5P <= angle && ANGLE_8D_OF_6P > angle && tempDirection != Direction.DIRECTION_UP) {
// up
tempDirection = Direction.DIRECTION_UP;
handleMoveEvent(true, false, false, false);
} else if (ANGLE_8D_OF_6P <= angle && ANGLE_8D_OF_7P > angle && tempDirection != Direction.DIRECTION_UP_RIGHT) {
// up right
tempDirection = Direction.DIRECTION_UP_RIGHT;
handleMoveEvent(true, false, false, true);
}
}
}
private void handleMoveEvent(boolean up, boolean down, boolean left, boolean right) {
if (menu != null) {
menu.getInput().sendKeyEvent(getData().getEvent().getUpKeycode(), up);
menu.getInput().sendKeyEvent(getData().getEvent().getDownKeycode(), down);
menu.getInput().sendKeyEvent(getData().getEvent().getLeftKeycode(), left);
menu.getInput().sendKeyEvent(getData().getEvent().getRightKeycode(), right);
}
if (getData().getStyle().getStyleType() == ControlDirectionStyle.Type.BUTTON) {
if (up && !down && !left && !right) {
upLeftBtn.setVisibility(VISIBLE);
upRightBtn.setVisibility(VISIBLE);
downLeftBtn.setVisibility(GONE);
downRightBtn.setVisibility(GONE);
} else if (!up && down && !left && !right) {
upLeftBtn.setVisibility(GONE);
upRightBtn.setVisibility(GONE);
downLeftBtn.setVisibility(VISIBLE);
downRightBtn.setVisibility(VISIBLE);
} else if (!up && !down && left && !right) {
upLeftBtn.setVisibility(VISIBLE);
upRightBtn.setVisibility(GONE);
downLeftBtn.setVisibility(VISIBLE);
downRightBtn.setVisibility(GONE);
} else if (!up && !down && !left && right) {
upLeftBtn.setVisibility(GONE);
upRightBtn.setVisibility(VISIBLE);
downLeftBtn.setVisibility(GONE);
downRightBtn.setVisibility(VISIBLE);
} else if (!up && !down && !left) {
upLeftBtn.setVisibility(GONE);
upRightBtn.setVisibility(GONE);
downLeftBtn.setVisibility(GONE);
downRightBtn.setVisibility(GONE);
}
setButtonStyle(centerBtn, !up && !down && !left && !right);
setButtonStyle(upBtn, up && !down && !left && !right);
setButtonStyle(downBtn, !up && down && !left && !right);
setButtonStyle(leftBtn, !up && !down && left && !right);
setButtonStyle(rightBtn, !up && !down && !left && right);
setButtonStyle(upLeftBtn, up && !down && left && !right);
setButtonStyle(upRightBtn, up && !down && !left && right);
setButtonStyle(downLeftBtn, !up && down && left && !right);
setButtonStyle(downRightBtn, !up && down && !left && right);
}
}
private void handleDoubleEvent(boolean enable) {
if (getData().getEvent().isSneak() && menu != null) {
doubleClickEvent = enable;
menu.getInput().sendKeyEvent(getData().getEvent().getSneakKeycode(), enable);
}
}
private void cancelAllEvent() {
if (getData().getStyle().getStyleType() == ControlDirectionStyle.Type.BUTTON) {
upLeftBtn.setVisibility(GONE);
upRightBtn.setVisibility(GONE);
downLeftBtn.setVisibility(GONE);
downRightBtn.setVisibility(GONE);
for (AppCompatButton b : buttons) {
setButtonStyle(b, false);
}
} else {
int x;
int y;
x = (int) (screenWidth * (getData().getBaseInfo().getXPosition() / 1000f)) - (getMeasuredWidth() / 2);
y = (int) (screenHeight * (getData().getBaseInfo().getYPosition() / 1000f)) - (getMeasuredWidth() / 2);
if (!displayMode) {
setX(x);
setY(y);
}
setButtonPosition(area, 0, 0);
setButtonPosition(rocker, (getMeasuredWidth() / 2) - (rockerSize / 2), (getMeasuredWidth() / 2) - (rockerSize / 2));
tempDirection = Direction.DIRECTION_CENTER;
}
if (menu != null) {
menu.getInput().sendKeyEvent(getData().getEvent().getUpKeycode(), false);
menu.getInput().sendKeyEvent(getData().getEvent().getDownKeycode(), false);
menu.getInput().sendKeyEvent(getData().getEvent().getLeftKeycode(), false);
menu.getInput().sendKeyEvent(getData().getEvent().getRightKeycode(), false);
}
}
public final BooleanProperty visibilityProperty() {
if (visibilityProperty == null) {
visibilityProperty = new BooleanPropertyBase() {
public void invalidated() {
Schedulers.androidUIThread().execute(() -> {
boolean visible = get();
setVisibility(visible ? VISIBLE : GONE);
});
}
public Object getBean() {
return this;
}
public String getName() {
return "visibility";
}
};
}
return visibilityProperty;
}
}

View File

@ -1,6 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="400dp"
android:layout_height="match_parent"
android:padding="10dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/title"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu_control_style_add"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:id="@+id/name_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_name"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:singleLine="true"
android:textSize="12sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/name"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:id="@+id/type_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_direction"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/type"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<ScrollView
android:id="@+id/container"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintTop_toBottomOf="@+id/type_layout"
app:layout_constraintBottom_toTopOf="@+id/positive"
android:layout_width="match_parent"
android:layout_height="120dp"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/positive"
android:text="@string/dialog_positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/negative"
android:text="@string/dialog_negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,6 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="400dp"
android:layout_height="match_parent"
android:padding="10dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/title"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu_controls_direction_style"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"/>
<com.tungsten.fcllibrary.component.view.HorizontalListView
android:orientation="horizontal"
android:id="@+id/list"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="150dp"
app:dividerWidth="0dp"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/positive"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/add_style"
android:text="@string/menu_control_style_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/positive"
android:text="@string/dialog_positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="150dp"
android:layout_height="150dp">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:padding="10dp"
android:background="@drawable/bg_item"
android:orientation="vertical"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">
<com.tungsten.fcl.control.view.ControlDirection
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/direction"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:id="@+id/name"/>
<com.tungsten.fcllibrary.component.view.FCLRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/radio_button"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:id="@+id/delete"
android:src="@drawable/ic_baseline_delete_24"
android:tint="@android:color/darker_gray"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_button_interval"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="0"
android:max="200"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/interval"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/interval_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_button"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/button_style_text"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_padding="false"
android:padding="8dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:layout_gravity="center"
android:id="@+id/set_button_style"
android:text="@string/menu_control_set"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>

View File

@ -0,0 +1,371 @@
<?xml version="1.0" encoding="utf-8"?>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_size"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="100"
android:max="900"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/rocker_size"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/rocker_size_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_bg_stroke_width"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="0"
android:max="50"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/bg_stroke_width"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/bg_stroke_width_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_bg_corner_radius"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="0"
android:max="500"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/bg_corner_radius"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/bg_corner_radius_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_stroke_width"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="0"
android:max="50"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/stroke_width"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/stroke_width_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_corner_radius"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:min="0"
android:max="500"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/corner_radius"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:gravity="end"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/corner_radius_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_bg_stroke_color"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:textAllCaps="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/bg_stroke_color_text"/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:id="@+id/bg_stroke_color_view"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_padding="false"
android:padding="8dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:layout_gravity="center"
android:id="@+id/set_bg_stroke_color"
android:text="@string/menu_control_set"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_bg_fill_color"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:textAllCaps="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/bg_fill_color_text"/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:id="@+id/bg_fill_color_view"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_padding="false"
android:padding="8dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:layout_gravity="center"
android:id="@+id/set_bg_fill_color"
android:text="@string/menu_control_set"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_stroke_color"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:textAllCaps="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/stroke_color_text"/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:id="@+id/stroke_color_view"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_padding="false"
android:padding="8dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:layout_gravity="center"
android:id="@+id/set_stroke_color"
android:text="@string/menu_control_set"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:text="@string/style_rocker_fill_color"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:textAllCaps="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/fill_color_text"/>
<View
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:id="@+id/fill_color_view"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_padding="false"
android:padding="8dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:layout_gravity="center"
android:id="@+id/set_fill_color"
android:text="@string/menu_control_set"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>

View File

@ -343,6 +343,8 @@
<string name="style_button_fill_color">填充颜色</string>
<string name="style_button_interval">按键间隔</string>
<string name="style_direction">方向控制键样式</string>
<string name="style_direction_button">十字键</string>
<string name="style_direction_rocker">摇杆</string>
<string name="style_rocker">摇杆样式</string>
<string name="style_rocker_size">摇杆大小</string>
<string name="style_rocker_bg_stroke_width">背景边框宽度</string>

View File

@ -366,6 +366,8 @@
<string name="style_button_fill_color">Fill Color</string>
<string name="style_button_interval">Button Interval</string>
<string name="style_direction">Direction Controller Style</string>
<string name="style_direction_button">Button</string>
<string name="style_direction_rocker">Rocker</string>
<string name="style_rocker">Rocker Style</string>
<string name="style_rocker_size">Rocker Size</string>
<string name="style_rocker_bg_stroke_width">Background Stroke Width</string>

View File

@ -30,16 +30,16 @@ dependencies {
implementation project(path: ':FCLauncher')
implementation 'com.github.marschall:zipfilesystem-standalone:1.0.1'
implementation 'org.nanohttpd:nanohttpd:2.3.1'
implementation 'com.github.steveice10:opennbt:1.4'
implementation 'org.tukaani:xz:1.8'
implementation 'com.github.steveice10:opennbt:1.5'
implementation 'org.tukaani:xz:1.9'
implementation 'commons-io:commons-io:2.11.0'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'org.apache.commons:commons-compress:1.21'
implementation 'org.apache.commons:commons-compress:1.23.0'
implementation 'com.moandjiezana.toml:toml4j:0.7.2'
implementation 'org.jenkins-ci:constant-pool-scanner:1.2'
implementation 'com.google.code.gson:gson:2.10'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -30,8 +30,8 @@ dependencies {
implementation project(path: ':FCLauncher')
implementation project(path: ':FCLCore')
implementation 'commons-io:commons-io:2.11.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.asynclayoutinflater:asynclayoutinflater:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'

View File

@ -23,6 +23,11 @@ public class ConvertUtils {
return (int) (pxValue / scare + 0.5f);
}
public static double radian2Angle(double radian) {
double tmp = Math.round(radian / Math.PI * 180);
return tmp >= 0 ? tmp : 360 + tmp;
}
public static Bitmap stringToBitmap(String string) {
if (string == null)
return null;

View File

@ -35,8 +35,8 @@ android {
dependencies {
implementation 'com.jaredrummler:android-device-names:2.1.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
}

View File

@ -1,6 +1,6 @@
#Tue Oct 11 19:03:04 CST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME