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

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

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

今回は水平方向のスクロールバーを作成した。垂直スクロールバーのことも考え右の方にスペースを空けておいた。

まずはスクロールバー用のインターフェース。スクロールバーを描画するためのdrawメソッドを定義しておく。

package text.edit.view;

import android.graphics.Canvas;
import android.graphics.Paint;

import text.edit.info.ViewInfo;

public interface ScrollBar {
    void draw(Canvas canvas, ViewInfo viewInfo, Paint paint);
}

次に水平スクロールバー。スクロールバーの枠とスクロールバー本体を描画している。

package text.edit.view;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;

import text.edit.info.ViewInfo;
import text.edit.info.ConstName;

public class HorizontalScrollBar implements ScrollBar{
    private static final int BAR_HEIGHT = 10;
    
    public void draw(Canvas canvas, ViewInfo viewInfo, Paint paint){
        int width = viewInfo.getInt(ConstName.EDITOR_WIDTH);
        int height = viewInfo.getInt(ConstName.EDITOR_HEIGHT);
        int rulerWidth = viewInfo.getInt(ConstName.ROW_RULER_WIDTH);
        
        int startY = height - HorizontalScrollBar.BAR_HEIGHT;
        int hsWidth = width - 10;
        
        Rect borderRect = new Rect(rulerWidth, startY, hsWidth, height);
        Rect barRect = HorizontalScrollBar.calcBarRect(viewInfo,borderRect);
        
        int srcColor = paint.getColor();
        Paint.Style srcStyle = paint.getStyle();
        
        HorizontalScrollBar.drawBorder(canvas, borderRect, paint);
        HorizontalScrollBar.drawBar(canvas, barRect, paint);
        
        paint.setColor(srcColor);
        paint.setStyle(srcStyle);
    }
    
    private static void drawBorder(Canvas canvas, Rect rect, Paint paint){
        paint.setColor(0xFF000000);
        paint.setStyle(Paint.Style.STROKE);
        
        canvas.drawRect(rect, paint);
    }
    
    private static void drawBar(Canvas canvas, Rect rect, Paint paint){
        paint.setColor(0xFF0000FF);
        paint.setStyle(Paint.Style.FILL);
        
        canvas.drawRect(rect, paint);
    }
    
    private static Rect calcBarRect(ViewInfo viewInfo, Rect borderRect){
        int maxWidth = viewInfo.getInt(ConstName.EDITOR_WIDTH) + viewInfo.getInt(ConstName.SCROLL_MAX_X);
        
        float per = (float)borderRect.width() / maxWidth;
        int barWidth = (int)Math.ceil((viewInfo.getInt(ConstName.EDITOR_WIDTH) * per));
        int startX = (int)Math.ceil((viewInfo.getInt(ConstName.SCROLL_X) * per) + borderRect.left);
        
        Rect rect = new Rect(startX, borderRect.top, startX + barWidth, borderRect.bottom);
        
        return rect;
    }
}

ConstNameも変更した。定数の追加

package text.edit.info;

public class ConstName {
    public static final String EDITOR_FONT_SIZE = "Editor.FontSize";
    public static final String EDITOR_WIDTH = "Editor.Width";
    public static final String EDITOR_HEIGHT = "Editor.Height";
    
    public static final String ROW_RULER_WIDTH = "RowRuler.Width";
    
    public static final String SCROLL_X = "Scroll.X";
    public static final String SCROLL_Y = "Scroll.Y";
    public static final String SCROLL_MAX_X = "Scroll.MaxX";
    public static final String SCROLL_MAX_Y = "Scroll.MaxY";
    
    public static final String CARET_ROW = "Caret.Row";
    public static final String CARET_COLUMN = "Caret.Column";
}

次にEditorViewの変数の宣言。とはいっても以下の1行追加しただけ

private ScrollBar horizontalScroll;

次にスクロールバーの初期化部分。initScrollにスクロールバーの初期化部分1行を追加しただけ

private void initScroll(){
    maxScrollX =0;
    maxScrollY = 0;
    viewInfo.put(ConstName.SCROLL_MAX_X, maxScrollX);
    viewInfo.put(ConstName.SCROLL_MAX_Y, maxScrollY);
        
    horizontalScroll = new HorizontalScrollBar();
      
    paint = new TextPaint();
    paint.setTextSize(fontSize);
}

次にEditorViewのinitRuler。viewInfoにルーラの幅を保存するようにした。

private void initRuler(){
    rowRuler = new RowRuler();
    rowRuler.setFontSize(fontSize);
    viewInfo.put(ConstName.ROW_RULER_WIDTH, rowRuler.getWidth());
}

次はViewInfoにスクロールバーの最大値を入れる部分。ViewInfoに保存する部分を追加した。

public void documentChanged(int row, int column, String text){
    int rowCount = document.getLineCount();
    maxScrollY = rowCount * fontSize;
    viewInfo.put(ConstName.SCROLL_MAX_Y, maxScrollY);
}
    
public void changeLine(int[] lines){
    int start = lines[0];
    int end = lines[lines.length - 1];
        
    for(int row = start; row < end; row++){
        String line = document.getLine(row);
        int lineWidth = (int)paint.measureText(line);

        if(lineWidth > maxScrollX){
            maxScrollX = lineWidth;
        }
    }
        
    viewInfo.put(ConstName.SCROLL_MAX_X, maxScrollX);
}

最後にonDrawメソッド。ここも1行だけ追加。スクロールバーのdrawメソッドを呼び出す部分を追加

@Override
protected void onDraw(Canvas canvas){
    viewInfo.put(ConstName.EDITOR_WIDTH, getWidth());
    viewInfo.put(ConstName.EDITOR_HEIGHT, getHeight());
    TextPaint paint = new TextPaint();
    paint.setTextSize(fontSize);

    drawText(canvas, document.getText(), paint);
    rowRuler.drawRuler(canvas, viewInfo, paint);
    horizontalScroll.draw(canvas, viewInfo, paint);
}