package org.solovyev.android.calculator.plot; import android.annotation.SuppressLint; import android.content.Context; import android.content.DialogInterface; import android.graphics.Typeface; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.*; import android.widget.TextView; import butterknife.Bind; import butterknife.ButterKnife; import org.solovyev.android.calculator.*; import org.solovyev.android.plotter.BasePlotterListener; import org.solovyev.android.plotter.PlotFunction; import org.solovyev.android.plotter.PlotIconView; import org.solovyev.android.plotter.Plotter; import org.solovyev.android.views.DividerItemDecoration; import javax.annotation.Nonnull; import javax.inject.Inject; import java.util.List; import static android.support.v7.widget.LinearLayoutManager.VERTICAL; import static android.view.Menu.NONE; public class PlotFunctionsFragment extends BaseDialogFragment { @Inject Plotter plotter; @Inject Typeface typeface; @NonNull private final PlotterListener plotterListener = new PlotterListener(); private Adapter adapter; public PlotFunctionsFragment() { } public static void show(@Nonnull FragmentManager fm) { App.showDialog(new PlotFunctionsFragment(), "plot-functions", fm); } @Override protected void inject(@NonNull AppComponent component) { super.inject(component); component.inject(this); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = super.onCreateView(inflater, container, savedInstanceState); plotter.addListener(plotterListener); return view; } @NonNull protected RecyclerView onCreateDialogView(@NonNull Context context, @NonNull LayoutInflater inflater, Bundle savedInstanceState) { @SuppressLint("InflateParams") final RecyclerView view = (RecyclerView) inflater.inflate(R.layout.fragment_plot_functions, null); view.setLayoutManager(new LinearLayoutManager(context, VERTICAL, false)); view.addItemDecoration(new DividerItemDecoration(context, null)); adapter = new Adapter(plotter.getPlotData().functions); view.setAdapter(adapter); return view; } @Override public void onDestroyView() { plotter.removeListener(plotterListener); super.onDestroyView(); } protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) { builder.setPositiveButton(R.string.cpp_close, null); builder.setNeutralButton(R.string.cpp_add, null); } @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_NEUTRAL: PlotEditFunctionFragment.show(null, getActivity().getSupportFragmentManager()); return; default: super.onClick(dialog, which); return; } } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { @Bind(R.id.function_icon) PlotIconView icon; @Bind(R.id.function_name) TextView name; private PlotFunction function; private ViewHolder(@NonNull View itemView) { super(itemView); BaseActivity.fixFonts(itemView, typeface); ButterKnife.bind(this, itemView); itemView.setOnClickListener(this); itemView.setOnCreateContextMenuListener(this); } void bind(@NonNull PlotFunction function) { this.function = function; name.setText(function.function.getName()); icon.setMeshSpec(function.meshSpec); } @Override public void onClick(View v) { PlotEditFunctionFragment.show(function, getActivity().getSupportFragmentManager()); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { menu.add(NONE, R.string.cpp_delete, NONE, R.string.cpp_delete).setOnMenuItemClickListener(this); } @Override public boolean onMenuItemClick(MenuItem item) { if (function != null && item.getItemId() == R.string.cpp_delete) { plotter.remove(function); return true; } return false; } } private class Adapter extends RecyclerView.Adapter { @NonNull private final List<PlotFunction> list; public Adapter(@NonNull List<PlotFunction> list) { this.list = list; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); return new ViewHolder(inflater.inflate(R.layout.fragment_functions_function, parent, false)); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((ViewHolder) holder).bind(list.get(position)); } @Override public int getItemCount() { return list.size(); } public void remove(@NonNull PlotFunction function) { final int i = list.indexOf(function); if (i >= 0) { list.remove(i); notifyItemRemoved(i); } } public void update(int id, @NonNull PlotFunction function) { final int i = find(id); if (i >= 0) { list.set(i, function); notifyItemChanged(i); } } private int find(int id) { for (int i = 0; i < list.size(); i++) { final PlotFunction function = list.get(i); if (function.function.getId() == id) { return i; } } return -1; } public void add(@NonNull PlotFunction function) { list.add(function); notifyItemInserted(list.size() - 1); } } private class PlotterListener extends BasePlotterListener { @Override public void onFunctionAdded(@NonNull PlotFunction function) { adapter.add(function); } @Override public void onFunctionUpdated(int id, @NonNull PlotFunction function) { adapter.update(id, function); } @Override public void onFunctionRemoved(@NonNull PlotFunction function) { adapter.remove(function); } } }