今回はとりあえず行ルーラを付けてみた
まずtext.edit.infoというパッケージを作成してViewInfoというクラスを作成。Viewのサイズやスクロール位置とかをMapに格納する。
package text.edit.info; import java.util.Map; import java.util.HashMap; public class ViewInfo{ private Map<String, Object> infoMap; public ViewInfo(){ infoMap = new HashMap<String, Object>(); } public void put(String key, Object value){ infoMap.put(key, value); } public Object get(String key){ return infoMap.get(key); } public Integer getInt(String key){ return (Integer)infoMap.get(key); } public boolean containsKey(String key){ return infoMap.containsKey(key); } }
次にinterfaceのRulerを作成。ルーラを描画するためのdrawRulerというメソッドを定義しておく。
package text.edit.view; import android.graphics.Canvas; import android.text.TextPaint; import text.edit.info.ViewInfo; public interface Ruler{ void drawRuler(Canvas canvas, ViewInfo viewInfo, TextPaint paint); }
次にRulerを実装したクラスRowRulerを作成。ルーラを描画する。Canvas#translateを最後に呼び出してるけど、これはEditorViewに移したほうがいいかな
package text.edit.view; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Canvas; import android.text.TextPaint; import text.edit.info.ViewInfo; public class RowRuler implements Ruler{ public void drawRuler(Canvas canvas, ViewInfo viewInfo, TextPaint paint){ int fontSize = viewInfo.getInt("Editor.FontSize"); int width = (fontSize / 2) * 5; int height = (viewInfo.getInt("Editor.Height")); int row = 1; int srcColor = paint.getColor(); Paint.Style srcStyle = paint.getStyle(); //背景の描画 paint.setStyle(Paint.Style.FILL); paint.setColor(0xC0CC9900); canvas.drawRect(0, 0, width, height, paint); paint.setStyle(srcStyle); paint.setColor(Color.BLACK); //行数の描画 for(int y = fontSize; y <= height; y += fontSize){ String rowNumber = String.format("%05d", row); canvas.drawText(rowNumber, 0, y, paint); row++; } paint.setColor(srcColor); paint.setStyle(srcStyle); canvas.translate(width + 4, 0); } }
EditorViewが長くなってきたので変更部分を中心に部分的に載せる。EditorViewにViewInfoとRulerのインスタンス変数を追加。コンストラクタにinitViewInfoとinitRulerを呼び出すようにした。
public class EditorView extends View{ private int fontSize; private TextDocument document; private Map<String, Integer> colorMap; private ViewInfo viewInfo; private Ruler rowRuler; public EditorView(Context context){ super(context); fontSize = 16; document = new TextDocument(); setBackgroundColor(Color.WHITE); initColorMap(); initViewInfo(); initRuler(); }
initViewInfoでスクロール位置(そのうち実装)やキャレット位置(そのうち実装)をViewInfoに渡す。initRulerはルーラの初期化をしている。
private void initViewInfo(){ viewInfo = new ViewInfo(); viewInfo.put("Editor.FontSize", fontSize); viewInfo.put("Editor.ScrollX", 0); viewInfo.put("Editor.ScrollY", 0); viewInfo.put("Caret.Row", 0); viewInfo.put("Caret.Column", 0); } private void initRuler(){ rowRuler = new RowRuler(); }
最後にonDrawを変更。ViewInfoにViewのサイズを渡す。これはViewのサイズ変更したときにやればいいのだが、サイズ変更のイベントを知らないので今は描画時に取得している。後はdrawTextの前にdrawRulerを呼び出すのみ
@Override protected void onDraw(Canvas canvas){ viewInfo.put("Editor.Width", getWidth()); viewInfo.put("Editor.Height", getHeight()); TextPaint paint = new TextPaint(); rowRuler.drawRuler(canvas, viewInfo, paint); drawText(canvas, document.getText(), paint); }
次回はスクロールの実装かな