package de.markusfisch.android.shadereditor.fragment; import de.markusfisch.android.shadereditor.activity.AddUniformActivity; import de.markusfisch.android.shadereditor.opengl.ShaderRenderer; import de.markusfisch.android.shadereditor.opengl.TextureParameters; import de.markusfisch.android.shadereditor.view.SoftKeyboard; import de.markusfisch.android.shadereditor.widget.TextureParametersView; import de.markusfisch.android.shadereditor.R; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.support.v4.app.Fragment; import android.text.InputFilter; import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.EditText; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import java.util.Locale; import java.util.regex.Pattern; public abstract class AbstractSamplerPropertiesFragment extends Fragment { public static final String TEXTURE_NAME_PATTERN = "[a-zA-Z0-9_]+"; public static final String SAMPLER_2D = "sampler2D"; public static final String SAMPLER_CUBE = "samplerCube"; private static final Pattern NAME_PATTERN = Pattern.compile( "^" + TEXTURE_NAME_PATTERN + "$"); private static boolean inProgress = false; private TextView sizeCaption; private SeekBar sizeBarView; private TextView sizeView; private EditText nameView; private CheckBox addUniformView; private TextureParametersView textureParameterView; private View progressView; private String samplerType = SAMPLER_2D; protected void setSizeCaption(String caption) { sizeCaption.setText(caption); } protected void setMaxValue(int max) { sizeBarView.setMax(max); } protected void setSamplerType(String name) { samplerType = name; } protected abstract int saveSampler( Context context, String name, int size); protected View initView( Activity activity, LayoutInflater inflater, ViewGroup container) { View view = inflater.inflate( R.layout.fragment_sampler_properties, container, false); sizeCaption = view.findViewById(R.id.size_caption); sizeBarView = view.findViewById(R.id.size_bar); sizeView = view.findViewById(R.id.size); nameView = view.findViewById(R.id.name); addUniformView = view.findViewById( R.id.should_add_uniform); textureParameterView = view.findViewById( R.id.texture_parameters); progressView = view.findViewById(R.id.progress_view); view.findViewById(R.id.save).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { saveSamplerAsync(); } }); if (activity.getCallingActivity() == null) { addUniformView.setVisibility(View.GONE); addUniformView.setChecked(false); textureParameterView.setVisibility(View.GONE); } initSizeView(); initNameView(); return view; } private void initSizeView() { setSizeView(sizeBarView.getProgress()); sizeBarView.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged( SeekBar seekBar, int progressValue, boolean fromUser) { setSizeView(progressValue); } @Override public void onStartTrackingTouch( SeekBar seekBar) { } @Override public void onStopTrackingTouch( SeekBar seekBar) { } }); } private void setSizeView(int power) { int size = getPower(power); sizeView.setText(String.format( Locale.US, "%d x %d", size, size)); } private void initNameView() { nameView.setFilters(new InputFilter[]{ new InputFilter() { @Override public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { return NAME_PATTERN .matcher(source) .find() ? null : ""; } }}); } // this AsyncTask is running for a short and finite time only // and it's perfectly okay to delay garbage collection of the // parent instance until this task has ended @SuppressLint("StaticFieldLeak") private void saveSamplerAsync() { final Context context = getActivity(); if (context == null || inProgress) { return; } final String name = nameView.getText().toString(); final TextureParameters tp = new TextureParameters(); textureParameterView.setParameters(tp); final String params = tp.toString(); if (name.trim().length() < 1) { Toast.makeText( context, R.string.missing_name, Toast.LENGTH_SHORT).show(); return; } else if (!name.matches(TEXTURE_NAME_PATTERN) || name.equals(ShaderRenderer.UNIFORM_BACKBUFFER)) { Toast.makeText( context, R.string.invalid_texture_name, Toast.LENGTH_SHORT).show(); return; } SoftKeyboard.hide(context, nameView); final int size = getPower(sizeBarView.getProgress()); inProgress = true; progressView.setVisibility(View.VISIBLE); new AsyncTask<Void, Void, Integer>() { @Override protected Integer doInBackground(Void... nothings) { return saveSampler(context, name, size); } @Override protected void onPostExecute(Integer messageId) { inProgress = false; progressView.setVisibility(View.GONE); Activity activity = getActivity(); if (activity == null) { return; } if (messageId > 0) { Toast.makeText( activity, messageId, Toast.LENGTH_SHORT).show(); return; } if (addUniformView.isChecked()) { AddUniformActivity.setAddUniformResult( activity, "uniform " + samplerType + " " + name + ";" + params); } activity.finish(); } }.execute(); } private static int getPower(int power) { return 1 << (power + 1); } }