<< 前 ホーム 次 >>

bakaid: 20131130

music-synthesizer-for-androidの話の続き。

PianoKeyの生成をPianoKeyboardに移したところまで
書いたんでしたね。次に、PianoKeyの配置の処理を
PianoKeyboardにまとめます。

各PianoKeyの配置は、各々が自分で決めています。
これはこれで一理あるんですが、鍵盤全体で配置を決め
たいときには面倒なんですね。

各PianoKeyの配置は、PianoKey#layoutというメソッド
で決めています。このメソッドでPianoKey#rect_という
Rectを求めています。ですから、PianoKeyboardで各
PianoKeyの配置をRectで求め、それを各PianoKeyに配る
という設計に変えます。

これで、PianoKeyの生成と配置の処理をPianoKeyboard
に集めることができました。変更前に変更したい処理を
一ヶ所に集めるというリファクタリングは、わりとやり
ます。

public class PianoKeyboard {
  // Generate the set of keys.  There are 12 music keys per octave, plus the octave change button
  // on either end.
  public PianoKey[] createKeys(PianoView piano, int octaves) {
    ArrayList keys = createWhiteKeys(piano, octaves);
    keys.addAll(createBlackKeys(piano, octaves));
    keys.addAll(createOctaveChangingKeys(piano));
    PianoKey[] typeArg = {};
    return keys.toArray(typeArg);
  }

  private ArrayList createWhiteKeys(PianoView piano, int octaves) {
    ArrayList keys = new ArrayList();
    for (int octave = 0; octave < octaves; ++octave) {
      for (int note = 0; note < 7; ++note) {
        keys.add(new WhitePianoKey(piano, octave, note));
      }
    }
    return keys;
  }

  private ArrayList createBlackKeys(PianoView piano, int octaves) {
    ArrayList keys = new ArrayList();
    for (int octave = 0; octave < octaves; ++octave) {
      for (int note = 0; note < 7; ++note) {
        if (BlackPianoKey.isValid(note)) {
          keys.add(new BlackPianoKey(piano, octave, note));
        }
      }
    }
    return keys;
  }

  private ArrayList createOctaveChangingKeys(PianoView piano) {
    ArrayList keys = new ArrayList();
    keys.add(new OctavePianoKey(piano, -1));
    keys.add(new OctavePianoKey(piano, 1));
    return keys;
  }

  public void draw(Canvas canvas, Rect drawingRect, PianoKey[] keys, int octaves) {
    layoutKeys(drawingRect, keys, octaves);
    drawKeys(canvas, keys);
  }

  private void layoutKeys(Rect drawingRect, PianoKey[] keys, int octaves) {
    for (int i = 0; i < keys.length; ++i) {
      if (keys[i] instanceof OctavePianoKey) {
        Rect rect = getOctaveKeyRect(drawingRect, octaves, keys[i]);
        keys[i].setRect(rect);
      } else if (keys[i] instanceof BlackPianoKey) {
        Rect rect = getBlackKeyRect(drawingRect, octaves, (NotePianoKey) keys[i]);
        keys[i].setRect(rect);
      } else {
        Rect rect = getWhiteKeyRect(drawingRect, octaves, (NotePianoKey) keys[i]);
        keys[i].setRect(rect);
       }
    }
  }

  private Rect getWhiteKeyRect(Rect drawingRect, int octaves, NotePianoKey key) {
    int whiteKeyWidth = getWhiteKeyWidth(drawingRect, octaves);
    Rect rect = new Rect();
    rect.top = 0;
    rect.bottom = getWhiteKeyHeight(drawingRect);
    rect.left = ((key.getOctaveOffset() * PianoKey.WHITE_KEYS.length + key.getKey() + 1) * whiteKeyWidth);
    rect.right = rect.left + whiteKeyWidth;
    return rect;
  }

  private Rect getBlackKeyRect(Rect drawingRect, int octaves, NotePianoKey key) {
    int whiteKeyWidth = getWhiteKeyWidth(drawingRect, octaves);
    int blackKeyWidth = getBlackKeyWidth(drawingRect, octaves);
    Rect rect = new Rect();
    rect.top = 0;
    rect.bottom = rect.top + getBlackKeyHeight(drawingRect);
    rect.left = ((key.getOctaveOffset() * PianoKey.WHITE_KEYS.length + key.getKey() + 2) * whiteKeyWidth) -
        (blackKeyWidth/2);
    rect.right = rect.left + blackKeyWidth;
    return rect;
  }

  private Rect getOctaveKeyRect(Rect drawingRect, int octaves, PianoKey key) {
    int whiteKeyWidth = getWhiteKeyWidth(drawingRect, octaves);
    Rect rect = new Rect();
    rect.top = 0;
    rect.bottom = getWhiteKeyHeight(drawingRect);
    if (key.getDelta() <= 0) {
      rect.left = 0;
      rect.right = rect.left + whiteKeyWidth;
    } else {
      rect.right = drawingRect.right;
      rect.left = rect.right - whiteKeyWidth;
    }
    return rect;
  }

  private void drawKeys(Canvas canvas, PianoKey[] keys) {
    for (int i = 0; i < keys.length; ++i) {
      keys[i].draw(canvas);
    }
  }

  private int getWhiteKeyWidth(Rect drawingRect, int octaves) {
    // It's +2 to reserve space for the octave-up/down buttons.
    return drawingRect.width() / ((PianoKey.WHITE_KEYS.length * octaves) + 2);
  }

  private int getWhiteKeyHeight(Rect drawingRect) {
    return drawingRect.height();
  }

  private int getBlackKeyWidth(Rect drawingRect, int octaves) {
    return (getWhiteKeyWidth(drawingRect, octaves) * 2) / 3;
  }

  private int getBlackKeyHeight(Rect drawingRect) {
    return getWhiteKeyHeight(drawingRect) / 2;
  }
}

本家Permlink

<< 前 ホーム 次 >>


Copyright © 1905 tko at jitu.org

バカが征く on Rails