Add pitch layout preference
.idea/misc.xml
| 4 | 4 | <option name="filePathToZoomLevelMap"> | |
| 5 | 5 | <map> | |
| 6 | 6 | <entry key="../../../../../../layout/custom_preview.xml" value="0.23385416666666667" /> | |
| 7 | + | <entry key="app/src/main/res/drawable/ic_pitch.xml" value="0.1535" /> | |
| 8 | + | <entry key="app/src/main/res/drawable/ic_rad.xml" value="0.1535" /> | |
| 9 | + | <entry key="app/src/main/res/drawable/ic_reading.xml" value="0.1535" /> | |
| 10 | + | <entry key="app/src/main/res/layout/fragment_results.xml" value="0.2078125" /> | |
| 11 | + | <entry key="app/src/main/res/layout/layout_result.xml" value="0.2078125" /> | |
| 12 | + | <entry key="app/src/main/res/xml/preferences.xml" value="0.2078125" /> | |
| 7 | 13 | </map> | |
| 8 | 14 | </option> | |
| 9 | 15 | </component> |
app/src/main/java/eu/lepiller/nani/MainActivity.java
| 44 | 44 | private SearchView search_form; | |
| 45 | 45 | private RadicalSelectorView radical_selector; | |
| 46 | 46 | private String readingStyle = "furigana"; | |
| 47 | + | private String pitchStyle = "box"; | |
| 47 | 48 | private String intentSearch = null; | |
| 48 | 49 | ViewPager2 viewPager2; | |
| 49 | 50 | ResultPagerAdapter pagerAdapter; | |
… | |||
| 73 | 74 | PreferenceManager.getDefaultSharedPreferences(this); | |
| 74 | 75 | sharedPref.registerOnSharedPreferenceChangeListener(this); | |
| 75 | 76 | int radSizePref = getRadSizePref(sharedPref); | |
| 76 | - | readingStyle = getReadingSizePref(sharedPref); | |
| 77 | + | readingStyle = getReadingStylePref(sharedPref); | |
| 78 | + | pitchStyle = getPitchStylePref(sharedPref); | |
| 77 | 79 | ||
| 78 | 80 | Button radical_button = findViewById(R.id.radical_button); | |
| 79 | 81 | ||
| 80 | 82 | pagerAdapter = new ResultPagerAdapter(this); | |
| 81 | 83 | pagerAdapter.setReadingStyle(readingStyle); | |
| 84 | + | pagerAdapter.setPitchStyle(pitchStyle); | |
| 82 | 85 | pagerAdapter.notifyDataSetChanged(); | |
| 83 | 86 | viewPager2.setAdapter(pagerAdapter); | |
| 84 | 87 | ||
… | |||
| 137 | 140 | if(key.compareTo(SettingsActivity.KEY_PREF_RAD_SIZE) == 0) { | |
| 138 | 141 | radical_selector.setRadSize(getRadSizePref(sharedPreferences)); | |
| 139 | 142 | } else if(key.compareTo(SettingsActivity.KEY_PREF_READING_STYLE) == 0) { | |
| 140 | - | readingStyle = getReadingSizePref(sharedPreferences); | |
| 143 | + | readingStyle = getReadingStylePref(sharedPreferences); | |
| 141 | 144 | pagerAdapter.setReadingStyle(readingStyle); | |
| 142 | 145 | pagerAdapter.notifyItemChanged(0); | |
| 146 | + | } else if(key.compareTo(SettingsActivity.KEY_PREF_PITCH_STYLE) == 0) { | |
| 147 | + | pitchStyle = getPitchStylePref(sharedPreferences); | |
| 148 | + | pagerAdapter.setPitchStyle(pitchStyle); | |
| 149 | + | pagerAdapter.notifyItemChanged(0); | |
| 143 | 150 | } | |
| 144 | 151 | } | |
| 145 | 152 | ||
… | |||
| 148 | 155 | return Integer.parseInt(prefRadSize); | |
| 149 | 156 | } | |
| 150 | 157 | ||
| 151 | - | private String getReadingSizePref(SharedPreferences sharedPreferences) { | |
| 158 | + | private String getReadingStylePref(SharedPreferences sharedPreferences) { | |
| 152 | 159 | return sharedPreferences.getString(SettingsActivity.KEY_PREF_READING_STYLE, "furigana"); | |
| 153 | 160 | } | |
| 154 | 161 | ||
| 162 | + | private String getPitchStylePref(SharedPreferences sharedPreferences) { | |
| 163 | + | return sharedPreferences.getString(SettingsActivity.KEY_PREF_PITCH_STYLE, "box"); | |
| 164 | + | } | |
| 165 | + | ||
| 155 | 166 | private class SearchThread extends Thread { | |
| 156 | 167 | String text; | |
| 157 | 168 | ||
app/src/main/java/eu/lepiller/nani/PitchContourView.java unknown status 1
| 1 | + | package eu.lepiller.nani; | |
| 2 | + | ||
| 3 | + | import android.content.Context; | |
| 4 | + | import android.graphics.Canvas; | |
| 5 | + | import android.graphics.Paint; | |
| 6 | + | import android.util.AttributeSet; | |
| 7 | + | import android.util.Pair; | |
| 8 | + | ||
| 9 | + | import androidx.annotation.Nullable; | |
| 10 | + | ||
| 11 | + | public class PitchContourView extends PitchView { | |
| 12 | + | private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 13 | + | private final static int spacing = 4; | |
| 14 | + | ||
| 15 | + | public PitchContourView(Context context) { | |
| 16 | + | super(context); | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | public PitchContourView(Context context, @Nullable AttributeSet attrs) { | |
| 20 | + | super(context, attrs); | |
| 21 | + | } | |
| 22 | + | ||
| 23 | + | public PitchContourView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
| 24 | + | super(context, attrs, defStyleAttr); | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | @Override | |
| 28 | + | protected void onDraw(Canvas canvas) { | |
| 29 | + | super.onDraw(canvas); | |
| 30 | + | if(pitchedMora == null || pitchedMora.size() == 0) | |
| 31 | + | return; | |
| 32 | + | ||
| 33 | + | paint.setColor(textColor); | |
| 34 | + | paint.setTextSize(textSize); | |
| 35 | + | paint.setStrokeWidth(2); | |
| 36 | + | ||
| 37 | + | int x = 0; | |
| 38 | + | for(int i = 0; i< pitchedMora.size(); i++) { | |
| 39 | + | Pair<String, Boolean> mora = pitchedMora.get(i); | |
| 40 | + | float posX = getX(x, textSize); | |
| 41 | + | String text = mora.first == null? "???": mora.first; | |
| 42 | + | x += text.length(); | |
| 43 | + | float width = paint.measureText(text); | |
| 44 | + | ||
| 45 | + | paint.setStyle(Paint.Style.FILL); | |
| 46 | + | paint.setTextSize((float)textSize); | |
| 47 | + | paint.setStrokeWidth(textSize); | |
| 48 | + | canvas.drawText(text, posX+spacing, textSize + textSize / 4, paint); | |
| 49 | + | ||
| 50 | + | paint.setStrokeWidth(2); | |
| 51 | + | paint.setStyle(Paint.Style.STROKE); | |
| 52 | + | if(mora.second) { | |
| 53 | + | canvas.drawLine(posX, 0, posX+width+2*spacing, 0, paint); | |
| 54 | + | } else { | |
| 55 | + | canvas.drawLine(posX, textSize + textSize/2, posX+width+2*spacing, textSize + textSize/2, paint); | |
| 56 | + | } | |
| 57 | + | ||
| 58 | + | if(i+1<pitchedMora.size()) { | |
| 59 | + | Pair<String, Boolean> mora2 = pitchedMora.get(i+1); | |
| 60 | + | if(mora2.second != mora.second) { | |
| 61 | + | canvas.drawLine(posX+width+2*spacing, 0, posX+width+2*spacing, textSize + textSize/2, paint); | |
| 62 | + | } | |
| 63 | + | } | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | } | |
| 67 | + | ||
| 68 | + | private static float getX(int i, float textSize) { | |
| 69 | + | return i*textSize + i*2*spacing + textSize/2; | |
| 70 | + | } | |
| 71 | + | ||
| 72 | + | private int totalSize() { | |
| 73 | + | int total = 0; | |
| 74 | + | for(int i = 0; i< pitchedMora.size(); i++) { | |
| 75 | + | Pair<String, Boolean> mora = pitchedMora.get(i); | |
| 76 | + | if(mora.first != null) | |
| 77 | + | total += mora.first.length(); | |
| 78 | + | } | |
| 79 | + | return total+1; | |
| 80 | + | } | |
| 81 | + | ||
| 82 | + | @Override | |
| 83 | + | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
| 84 | + | super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
| 85 | + | ||
| 86 | + | if(pitchedMora != null) | |
| 87 | + | setMeasuredDimension((int)getX(totalSize(), textSize), (int)(textSize + textSize/2)); | |
| 88 | + | else | |
| 89 | + | setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); | |
| 90 | + | } | |
| 91 | + | } |
app/src/main/java/eu/lepiller/nani/PitchDiagramView.java
| 1 | 1 | package eu.lepiller.nani; | |
| 2 | 2 | ||
| 3 | 3 | import android.content.Context; | |
| 4 | - | import android.content.res.Configuration; | |
| 5 | - | import android.content.res.TypedArray; | |
| 6 | 4 | import android.graphics.Canvas; | |
| 7 | - | import android.graphics.Color; | |
| 8 | 5 | import android.graphics.Paint; | |
| 9 | 6 | import android.util.AttributeSet; | |
| 10 | 7 | import android.util.Pair; | |
| 11 | - | import android.view.View; | |
| 12 | - | import android.widget.TextView; | |
| 13 | 8 | ||
| 14 | 9 | import androidx.annotation.Nullable; | |
| 15 | 10 | ||
| 16 | - | import java.util.ArrayList; | |
| 17 | - | ||
| 18 | - | public class PitchDiagramView extends View { | |
| 11 | + | public class PitchDiagramView extends PitchView { | |
| 19 | 12 | private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 20 | - | private int textColor = Color.BLACK; | |
| 21 | - | private int pitchColor = Color.BLACK; | |
| 22 | - | private ArrayList<Pair<String, Boolean>> pitchedMora = new ArrayList<>(); | |
| 23 | - | private int accent; | |
| 24 | - | private String text; | |
| 25 | - | ||
| 26 | - | private float textSize = 32; | |
| 27 | 13 | ||
| 28 | 14 | public PitchDiagramView(Context context) { | |
| 29 | 15 | super(context); | |
| 30 | - | setDefaults(); | |
| 31 | 16 | } | |
| 32 | 17 | ||
| 33 | 18 | public PitchDiagramView(Context context, @Nullable AttributeSet attrs) { | |
| 34 | 19 | super(context, attrs); | |
| 35 | - | setDefaults(); | |
| 36 | - | setupAttributes(attrs, 0); | |
| 37 | 20 | } | |
| 38 | 21 | ||
| 39 | 22 | public PitchDiagramView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
| 40 | 23 | super(context, attrs, defStyleAttr); | |
| 41 | - | setDefaults(); | |
| 42 | - | setupAttributes(attrs, defStyleAttr); | |
| 43 | - | } | |
| 44 | - | ||
| 45 | - | private void setDefaults() { | |
| 46 | - | textColor = getContext().getResources().getColor(android.R.color.tab_indicator_text); | |
| 47 | - | int mode = getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; | |
| 48 | - | if(mode == Configuration.UI_MODE_NIGHT_NO) { | |
| 49 | - | pitchColor = getContext().getResources().getColor(android.R.color.background_dark); | |
| 50 | - | } else if(mode == Configuration.UI_MODE_NIGHT_YES) { | |
| 51 | - | pitchColor = getContext().getResources().getColor(android.R.color.background_light); | |
| 52 | - | } | |
| 53 | - | textSize = new TextView(getContext()).getTextSize(); | |
| 54 | - | } | |
| 55 | - | ||
| 56 | - | private void setupAttributes(AttributeSet attrs, int defStyleAttr) { | |
| 57 | - | TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.PitchDiagramView, defStyleAttr, 0); | |
| 58 | - | textColor = typedArray.getColor(R.styleable.PitchDiagramView_textColor, textColor); | |
| 59 | - | pitchColor = typedArray.getColor(R.styleable.PitchDiagramView_pitchColor, pitchColor); | |
| 60 | - | textSize = typedArray.getDimension(R.styleable.PitchDiagramView_textSize, textSize); | |
| 61 | - | text = typedArray.getString(R.styleable.PitchDiagramView_text); | |
| 62 | - | accent = typedArray.getInt(R.styleable.PitchDiagramView_pitch, -1); | |
| 63 | - | updatePitchedMora(); | |
| 64 | - | } | |
| 65 | - | ||
| 66 | - | private static boolean is_mora(char c) { | |
| 67 | - | ArrayList<Character> not_mora = new ArrayList<>(); | |
| 68 | - | not_mora.add("???".charAt(0)); | |
| 69 | - | not_mora.add("???".charAt(0)); | |
| 70 | - | not_mora.add("???".charAt(0)); | |
| 71 | - | not_mora.add("???".charAt(0)); | |
| 72 | - | not_mora.add("???".charAt(0)); | |
| 73 | - | not_mora.add("???".charAt(0)); | |
| 74 | - | return !not_mora.contains(c); | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | public void setText(String text) { | |
| 78 | - | this.text = text; | |
| 79 | - | updatePitchedMora(); | |
| 80 | - | notify(); | |
| 81 | - | } | |
| 82 | - | ||
| 83 | - | public void setPitch(int pitch) { | |
| 84 | - | this.accent = pitch; | |
| 85 | - | updatePitchedMora(); | |
| 86 | - | notify(); | |
| 87 | - | } | |
| 88 | - | ||
| 89 | - | public String getText() { | |
| 90 | - | return text; | |
| 91 | - | } | |
| 92 | - | ||
| 93 | - | public int getPitch() { | |
| 94 | - | return accent; | |
| 95 | - | } | |
| 96 | - | ||
| 97 | - | private void updatePitchedMora() { | |
| 98 | - | ArrayList<String> moras = new ArrayList<>(); | |
| 99 | - | ||
| 100 | - | if(accent < 0 || text == null) | |
| 101 | - | return; | |
| 102 | - | ||
| 103 | - | for(int i=0; i<text.length(); i++) { | |
| 104 | - | char here = text.charAt(i); | |
| 105 | - | if(is_mora(here) && (i == text.length()-1 || is_mora(text.charAt(i+1)))) | |
| 106 | - | moras.add(text.substring(i,i+1)); | |
| 107 | - | else if(is_mora(here)) | |
| 108 | - | moras.add(text.substring(i,i+2)); | |
| 109 | - | } | |
| 110 | - | moras.add(null); | |
| 111 | - | pitchedMora = new ArrayList<>(); | |
| 112 | - | if(accent == 0) | |
| 113 | - | setHeiban(pitchedMora, moras); | |
| 114 | - | else if(accent == 1) | |
| 115 | - | setAtamadaka(pitchedMora, moras); | |
| 116 | - | else | |
| 117 | - | setOtherAccent(pitchedMora, moras, accent); | |
| 118 | - | } | |
| 119 | - | ||
| 120 | - | public void setTextColor(int textColor) { | |
| 121 | - | this.textColor = textColor; | |
| 122 | - | } | |
| 123 | - | ||
| 124 | - | public void setPitchColor(int pitchColor) { | |
| 125 | - | this.pitchColor = pitchColor; | |
| 126 | - | } | |
| 127 | - | ||
| 128 | - | public void setTextSize(float textSize) { | |
| 129 | - | this.textSize = textSize; | |
| 130 | - | notify(); | |
| 131 | 24 | } | |
| 132 | 25 | ||
| 133 | 26 | private static float getCharWidth(float textSize) { | |
… | |||
| 158 | 51 | return (float)3.5 * textSize + getParticleRadius(textSize); | |
| 159 | 52 | } | |
| 160 | 53 | ||
| 161 | - | private static void setHeiban(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras) { | |
| 162 | - | text.add(new Pair<>(moras.get(0), false)); | |
| 163 | - | for(int i=1; i<moras.size(); i++) { | |
| 164 | - | text.add(new Pair<>(moras.get(i), true)); | |
| 165 | - | } | |
| 166 | - | } | |
| 167 | - | ||
| 168 | - | private static void setAtamadaka(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras) { | |
| 169 | - | text.add(new Pair<>(moras.get(0), true)); | |
| 170 | - | for(int i=1; i<moras.size(); i++) { | |
| 171 | - | text.add(new Pair<>(moras.get(i), false)); | |
| 172 | - | } | |
| 173 | - | } | |
| 174 | - | ||
| 175 | - | private static void setOtherAccent(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras, int accent) { | |
| 176 | - | text.add(new Pair<>(moras.get(0), false)); | |
| 177 | - | int i; | |
| 178 | - | for(i=1; i<moras.size() && i < accent; i++) { | |
| 179 | - | text.add(new Pair<>(moras.get(i), true)); | |
| 180 | - | } | |
| 181 | - | for(; i<moras.size(); i++) { | |
| 182 | - | text.add(new Pair<>(moras.get(i), false)); | |
| 183 | - | } | |
| 184 | - | } | |
| 185 | - | ||
| 186 | 54 | @Override | |
| 187 | 55 | protected void onDraw(Canvas canvas) { | |
| 188 | 56 | super.onDraw(canvas); | |
… | |||
| 254 | 122 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
| 255 | 123 | ||
| 256 | 124 | if(pitchedMora != null) | |
| 257 | - | setMeasuredDimension((int)getX(pitchedMora.size(), textSize), (int)(getMoraPosition(textSize) + textSize/2)); | |
| 125 | + | setMeasuredDimension((int)getX(pitchedMora.size(), textSize), (int)(getMoraPosition(textSize) + textSize/2)); | |
| 258 | 126 | else | |
| 259 | 127 | setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); | |
| 260 | 128 | } | |
app/src/main/java/eu/lepiller/nani/PitchView.java unknown status 1
| 1 | + | package eu.lepiller.nani; | |
| 2 | + | ||
| 3 | + | import android.content.Context; | |
| 4 | + | import android.content.res.Configuration; | |
| 5 | + | import android.content.res.TypedArray; | |
| 6 | + | import android.graphics.Color; | |
| 7 | + | import android.graphics.Paint; | |
| 8 | + | import android.util.AttributeSet; | |
| 9 | + | import android.util.Pair; | |
| 10 | + | import android.view.View; | |
| 11 | + | import android.widget.TextView; | |
| 12 | + | ||
| 13 | + | import androidx.annotation.Nullable; | |
| 14 | + | ||
| 15 | + | import java.util.ArrayList; | |
| 16 | + | ||
| 17 | + | public abstract class PitchView extends View { | |
| 18 | + | private int accent; | |
| 19 | + | private String text; | |
| 20 | + | ||
| 21 | + | protected int textColor = Color.BLACK; | |
| 22 | + | protected int pitchColor = Color.BLACK; | |
| 23 | + | protected ArrayList<Pair<String, Boolean>> pitchedMora = new ArrayList<>(); | |
| 24 | + | protected float textSize = 32; | |
| 25 | + | ||
| 26 | + | public PitchView(Context context) { | |
| 27 | + | super(context); | |
| 28 | + | setDefaults(); | |
| 29 | + | } | |
| 30 | + | ||
| 31 | + | public PitchView(Context context, @Nullable AttributeSet attrs) { | |
| 32 | + | super(context, attrs); | |
| 33 | + | setDefaults(); | |
| 34 | + | setupAttributes(attrs, 0); | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | public PitchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
| 38 | + | super(context, attrs, defStyleAttr); | |
| 39 | + | setDefaults(); | |
| 40 | + | setupAttributes(attrs, defStyleAttr); | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | private void setDefaults() { | |
| 44 | + | textColor = getContext().getResources().getColor(android.R.color.tab_indicator_text); | |
| 45 | + | int mode = getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; | |
| 46 | + | if(mode == Configuration.UI_MODE_NIGHT_NO) { | |
| 47 | + | pitchColor = getContext().getResources().getColor(android.R.color.background_dark); | |
| 48 | + | } else if(mode == Configuration.UI_MODE_NIGHT_YES) { | |
| 49 | + | pitchColor = getContext().getResources().getColor(android.R.color.background_light); | |
| 50 | + | } | |
| 51 | + | textSize = new TextView(getContext()).getTextSize(); | |
| 52 | + | } | |
| 53 | + | ||
| 54 | + | private void setupAttributes(AttributeSet attrs, int defStyleAttr) { | |
| 55 | + | TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.PitchDiagramView, defStyleAttr, 0); | |
| 56 | + | textColor = typedArray.getColor(R.styleable.PitchDiagramView_textColor, textColor); | |
| 57 | + | pitchColor = typedArray.getColor(R.styleable.PitchDiagramView_pitchColor, pitchColor); | |
| 58 | + | textSize = typedArray.getDimension(R.styleable.PitchDiagramView_textSize, textSize); | |
| 59 | + | text = typedArray.getString(R.styleable.PitchDiagramView_text); | |
| 60 | + | accent = typedArray.getInt(R.styleable.PitchDiagramView_pitch, -1); | |
| 61 | + | updatePitchedMora(); | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | protected static boolean is_mora(char c) { | |
| 65 | + | ArrayList<Character> not_mora = new ArrayList<>(); | |
| 66 | + | not_mora.add("???".charAt(0)); | |
| 67 | + | not_mora.add("???".charAt(0)); | |
| 68 | + | not_mora.add("???".charAt(0)); | |
| 69 | + | not_mora.add("???".charAt(0)); | |
| 70 | + | not_mora.add("???".charAt(0)); | |
| 71 | + | not_mora.add("???".charAt(0)); | |
| 72 | + | return !not_mora.contains(c); | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | public void setText(String text) { | |
| 76 | + | this.text = text; | |
| 77 | + | updatePitchedMora(); | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | public void setPitch(int pitch) { | |
| 81 | + | this.accent = pitch; | |
| 82 | + | updatePitchedMora(); | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | public String getText() { | |
| 86 | + | return text; | |
| 87 | + | } | |
| 88 | + | ||
| 89 | + | public int getPitch() { | |
| 90 | + | return accent; | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | private void updatePitchedMora() { | |
| 94 | + | ArrayList<String> moras = new ArrayList<>(); | |
| 95 | + | ||
| 96 | + | if(accent < 0 || text == null) | |
| 97 | + | return; | |
| 98 | + | ||
| 99 | + | for(int i=0; i<text.length(); i++) { | |
| 100 | + | char here = text.charAt(i); | |
| 101 | + | if(is_mora(here) && (i == text.length()-1 || is_mora(text.charAt(i+1)))) | |
| 102 | + | moras.add(text.substring(i,i+1)); | |
| 103 | + | else if(is_mora(here)) | |
| 104 | + | moras.add(text.substring(i,i+2)); | |
| 105 | + | } | |
| 106 | + | moras.add(null); | |
| 107 | + | pitchedMora = new ArrayList<>(); | |
| 108 | + | if(accent == 0) | |
| 109 | + | setHeiban(pitchedMora, moras); | |
| 110 | + | else if(accent == 1) | |
| 111 | + | setAtamadaka(pitchedMora, moras); | |
| 112 | + | else | |
| 113 | + | setOtherAccent(pitchedMora, moras, accent); | |
| 114 | + | } | |
| 115 | + | ||
| 116 | + | public void setTextColor(int textColor) { | |
| 117 | + | this.textColor = textColor; | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | public void setPitchColor(int pitchColor) { | |
| 121 | + | this.pitchColor = pitchColor; | |
| 122 | + | } | |
| 123 | + | ||
| 124 | + | public void setTextSize(float textSize) { | |
| 125 | + | this.textSize = textSize; | |
| 126 | + | } | |
| 127 | + | ||
| 128 | + | private static void setHeiban(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras) { | |
| 129 | + | text.add(new Pair<>(moras.get(0), false)); | |
| 130 | + | for(int i=1; i<moras.size(); i++) { | |
| 131 | + | text.add(new Pair<>(moras.get(i), true)); | |
| 132 | + | } | |
| 133 | + | } | |
| 134 | + | ||
| 135 | + | private static void setAtamadaka(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras) { | |
| 136 | + | text.add(new Pair<>(moras.get(0), true)); | |
| 137 | + | for(int i=1; i<moras.size(); i++) { | |
| 138 | + | text.add(new Pair<>(moras.get(i), false)); | |
| 139 | + | } | |
| 140 | + | } | |
| 141 | + | ||
| 142 | + | private static void setOtherAccent(ArrayList<Pair<String, Boolean>> text, ArrayList<String> moras, int accent) { | |
| 143 | + | text.add(new Pair<>(moras.get(0), false)); | |
| 144 | + | int i; | |
| 145 | + | for(i=1; i<moras.size() && i < accent; i++) { | |
| 146 | + | text.add(new Pair<>(moras.get(i), true)); | |
| 147 | + | } | |
| 148 | + | for(; i<moras.size(); i++) { | |
| 149 | + | text.add(new Pair<>(moras.get(i), false)); | |
| 150 | + | } | |
| 151 | + | } | |
| 152 | + | } |
app/src/main/java/eu/lepiller/nani/ResultPagerAdapter.java
| 1 | 1 | package eu.lepiller.nani; | |
| 2 | 2 | ||
| 3 | 3 | import android.annotation.SuppressLint; | |
| 4 | + | import android.app.NotificationManager; | |
| 4 | 5 | import android.content.Context; | |
| 5 | 6 | import android.content.Intent; | |
| 6 | 7 | import android.text.Html; | |
… | |||
| 27 | 28 | static List<Result> results = new ArrayList<>(); | |
| 28 | 29 | static List<KanjiResult> kanjiResults = new ArrayList<>(); | |
| 29 | 30 | private static String readingStyle = "furigana"; | |
| 31 | + | private static String pitchStyle = "box"; | |
| 30 | 32 | private final Context context; | |
| 31 | 33 | ||
| 32 | 34 | static final String TAG = "RESULTS_PAGER"; | |
… | |||
| 138 | 140 | LinearLayout senses_view = child_result.findViewById(R.id.sense_view); | |
| 139 | 141 | TextView additional_info = child_result.findViewById(R.id.additional_info_view); | |
| 140 | 142 | TextView pitch_view = child_result.findViewById(R.id.pitch_view); | |
| 143 | + | PitchDiagramView pitch_diagram = child_result.findViewById(R.id.pitch_diagram_view); | |
| 144 | + | PitchContourView pitch_contour = child_result.findViewById(R.id.pitch_contour_view); | |
| 141 | 145 | ||
| 142 | 146 | // Populate the data into the template view using the data object | |
| 143 | 147 | if(readingStyle.compareTo("furigana") == 0) { | |
| 144 | 148 | kanji_view.setCombinedText(result.getKanjiFurigana()); | |
| 149 | + | reading_view.setVisibility(View.GONE); | |
| 145 | 150 | } else { | |
| 146 | 151 | kanji_view.setCombinedText(result.getKanji()); | |
| 147 | 152 | reading_view.setVisibility(View.VISIBLE); | |
… | |||
| 151 | 156 | // If pitch information is available, make it visible | |
| 152 | 157 | String pitch = result.getPitch(); | |
| 153 | 158 | if(pitch != null) { | |
| 154 | - | pitch_view.setVisibility(View.VISIBLE); | |
| 159 | + | if(pitchStyle.compareTo("box") == 0) { | |
| 160 | + | pitch_view.setVisibility(View.VISIBLE); | |
| 161 | + | pitch_diagram.setVisibility(View.GONE); | |
| 162 | + | pitch_contour.setVisibility(View.GONE); | |
| 163 | + | } else if(pitchStyle.compareTo("diagram") == 0) { | |
| 164 | + | if(readingStyle.compareTo("kana") == 0) { | |
| 165 | + | reading_view.setVisibility(View.GONE); | |
| 166 | + | } | |
| 167 | + | pitch_diagram.setVisibility(View.VISIBLE); | |
| 168 | + | pitch_contour.setVisibility(View.GONE); | |
| 169 | + | pitch_view.setVisibility(View.GONE); | |
| 170 | + | pitch_diagram.setText(result.getReading()); | |
| 171 | + | pitch_diagram.setPitch(Integer.parseInt(pitch)); | |
| 172 | + | } else if(pitchStyle.compareTo("contour") == 0) { | |
| 173 | + | if(readingStyle.compareTo("kana") == 0) { | |
| 174 | + | reading_view.setVisibility(View.GONE); | |
| 175 | + | } | |
| 176 | + | pitch_contour.setVisibility(View.VISIBLE); | |
| 177 | + | pitch_diagram.setVisibility(View.GONE); | |
| 178 | + | pitch_view.setVisibility(View.GONE); | |
| 179 | + | pitch_contour.setText(result.getReading()); | |
| 180 | + | pitch_contour.setPitch(Integer.parseInt(pitch)); | |
| 181 | + | } | |
| 182 | + | ||
| 155 | 183 | pitch_view.setText(pitch); | |
| 156 | 184 | pitch_view.setOnClickListener(v -> { | |
| 157 | 185 | Intent intent = new Intent(context, HelpPitchActivity.class); | |
… | |||
| 229 | 257 | } | |
| 230 | 258 | ||
| 231 | 259 | @SuppressLint("NotifyDataSetChanged") | |
| 260 | + | public void setPitchStyle(String pitchStyle) { | |
| 261 | + | ResultPagerAdapter.pitchStyle = pitchStyle; | |
| 262 | + | Log.d(TAG, "pitch style updated to " + pitchStyle); | |
| 263 | + | notifyDataSetChanged(); | |
| 264 | + | } | |
| 265 | + | ||
| 266 | + | @SuppressLint("NotifyDataSetChanged") | |
| 232 | 267 | public void setKanjiResults(List<KanjiResult> kanjiResults) { | |
| 233 | 268 | if(kanjiResults == null) | |
| 234 | 269 | return; | |
app/src/main/java/eu/lepiller/nani/SettingsActivity.java
| 7 | 7 | public class SettingsActivity extends AppCompatActivity { | |
| 8 | 8 | public static final String KEY_PREF_RAD_SIZE = "rad_size"; | |
| 9 | 9 | public static final String KEY_PREF_READING_STYLE = "reading_style"; | |
| 10 | + | public static final String KEY_PREF_PITCH_STYLE = "pitch_style"; | |
| 10 | 11 | ||
| 11 | 12 | @Override | |
| 12 | 13 | protected void onCreate(Bundle savedInstanceState) { |
app/src/main/res/drawable/ic_pitch.xml unknown status 1
| 1 | + | <vector xmlns:android="http://schemas.android.com/apk/res/android" | |
| 2 | + | android:width="32dp" | |
| 3 | + | android:height="32dp" | |
| 4 | + | android:viewportWidth="128" | |
| 5 | + | android:viewportHeight="128"> | |
| 6 | + | <path | |
| 7 | + | android:pathData="M64,64m-64,0a64,64 0,1 1,128 0a64,64 0,1 1,-128 0" | |
| 8 | + | android:strokeWidth="0.264583" | |
| 9 | + | android:fillColor="#e6e6e6" | |
| 10 | + | android:fillType="evenOdd"/> | |
| 11 | + | <path | |
| 12 | + | android:pathData="M28,84m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" | |
| 13 | + | android:strokeWidth="0.264583" | |
| 14 | + | android:fillColor="#1a1a1a"/> | |
| 15 | + | <path | |
| 16 | + | android:pathData="M100,84m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" | |
| 17 | + | android:strokeWidth="0.264583" | |
| 18 | + | android:fillColor="#1a1a1a"/> | |
| 19 | + | <path | |
| 20 | + | android:pathData="M64,40m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" | |
| 21 | + | android:strokeWidth="0.264583" | |
| 22 | + | android:fillColor="#1a1a1a"/> | |
| 23 | + | <path | |
| 24 | + | android:pathData="M28,84 L64,40 100,84" | |
| 25 | + | android:strokeLineJoin="miter" | |
| 26 | + | android:strokeWidth="5" | |
| 27 | + | android:fillColor="#00000000" | |
| 28 | + | android:strokeColor="#1a1a1a" | |
| 29 | + | android:strokeLineCap="butt"/> | |
| 30 | + | </vector> |
app/src/main/res/layout/layout_result.xml
| 37 | 37 | ||
| 38 | 38 | <TextView | |
| 39 | 39 | android:id="@+id/reading_view" | |
| 40 | - | android:layout_width="match_parent" | |
| 40 | + | android:layout_width="wrap_content" | |
| 41 | + | android:layout_height="wrap_content" | |
| 42 | + | android:layout_marginTop="8dp" | |
| 43 | + | android:layout_marginLeft="8dp" | |
| 44 | + | android:layout_marginStart="8dp" | |
| 45 | + | android:layout_marginRight="8dp" | |
| 46 | + | android:layout_marginEnd="8dp" | |
| 47 | + | android:textSize="@dimen/normal_size" | |
| 48 | + | android:textAlignment="center" | |
| 49 | + | android:contentDescription="@string/kanji_description" | |
| 50 | + | android:textIsSelectable="true" | |
| 51 | + | android:gravity="center_horizontal" | |
| 52 | + | android:minWidth="@dimen/title_size" | |
| 53 | + | android:visibility="gone" /> | |
| 54 | + | ||
| 55 | + | <eu.lepiller.nani.PitchContourView | |
| 56 | + | android:id="@+id/pitch_contour_view" | |
| 57 | + | android:layout_width="wrap_content" | |
| 58 | + | android:layout_height="wrap_content" | |
| 59 | + | android:layout_marginTop="8dp" | |
| 60 | + | android:layout_marginLeft="8dp" | |
| 61 | + | android:layout_marginStart="8dp" | |
| 62 | + | android:layout_marginRight="8dp" | |
| 63 | + | android:layout_marginEnd="8dp" | |
| 64 | + | android:textSize="@dimen/normal_size" | |
| 65 | + | android:textAlignment="center" | |
| 66 | + | android:contentDescription="@string/kanji_description" | |
| 67 | + | android:textIsSelectable="true" | |
| 68 | + | android:gravity="center_horizontal" | |
| 69 | + | android:minWidth="@dimen/title_size" | |
| 70 | + | android:visibility="gone" /> | |
| 71 | + | ||
| 72 | + | <eu.lepiller.nani.PitchDiagramView | |
| 73 | + | android:id="@+id/pitch_diagram_view" | |
| 74 | + | android:layout_width="wrap_content" | |
| 41 | 75 | android:layout_height="wrap_content" | |
| 42 | 76 | android:layout_marginTop="8dp" | |
| 43 | 77 | android:layout_marginLeft="8dp" | |
| 44 | 78 | android:layout_marginStart="8dp" | |
| 45 | 79 | android:layout_marginRight="8dp" | |
| 46 | 80 | android:layout_marginEnd="8dp" | |
| 81 | + | android:textSize="@dimen/normal_size" | |
| 47 | 82 | android:textAlignment="center" | |
| 48 | 83 | android:contentDescription="@string/kanji_description" | |
| 49 | 84 | android:textIsSelectable="true" |
app/src/main/res/values/strings.xml
| 63 | 63 | <item>kana</item> | |
| 64 | 64 | <item>romaji</item> | |
| 65 | 65 | </string-array> | |
| 66 | + | <string name="pref_pitch_style">Display style for pitch accent information</string> | |
| 67 | + | <string-array name="pref_pitch_style_choice"> | |
| 68 | + | <item>Box</item> | |
| 69 | + | <item>Diagram</item> | |
| 70 | + | <item>Contour</item> | |
| 71 | + | </string-array> | |
| 72 | + | <string-array name="pref_pitch_style_values"> | |
| 73 | + | <item>box</item> | |
| 74 | + | <item>diagram</item> | |
| 75 | + | <item>contour</item> | |
| 76 | + | </string-array> | |
| 66 | 77 | ||
| 67 | 78 | <!-- Dictionnary descriptions --> | |
| 68 | 79 | <string name="error_dico_url">Error fetching dictionary list: malformed URL.</string> |
app/src/main/res/xml/preferences.xml
| 14 | 14 | android:title="@string/pref_reading_style" | |
| 15 | 15 | android:defaultValue="furigana" | |
| 16 | 16 | android:icon="@drawable/ic_reading"/> | |
| 17 | + | <ListPreference | |
| 18 | + | android:entries="@array/pref_pitch_style_choice" | |
| 19 | + | android:entryValues="@array/pref_pitch_style_values" | |
| 20 | + | android:key="pitch_style" | |
| 21 | + | android:title="@string/pref_pitch_style" | |
| 22 | + | android:defaultValue="box" | |
| 23 | + | android:icon="@drawable/ic_pitch"/> | |
| 17 | 24 | </PreferenceScreen> | |
| 17 | 24 | = | |
| 18 | 25 | = | \ No newline at end of file |