マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

簡易テキストエディタ作成 その3

今回はとりあえず行ルーラを付けてみた

まず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);
    }

次回はスクロールの実装かな