2022/05/31(火)Processing AndroidModeのcontrolP5ボタン

最近Processingを始めましたが、AndroidModeっていうのがあり、これを使うとProcessingアプリがAndroidスマホで動作します。どちらかというと簡易的にAndroidアプリをProcessingで製作出来る、といった方が分かりやすいかもしれません。そこで早速何か簡単な自分用ツールを作ってみようと思ったのですがいきなり躓きました。
それは、定番なProcessingGUIライブラリのcontrolP5ライブラリをAndroidModeで利用する場合、ボタンイベントが所望の動作にならないというものです。ざっと調べた結果仕様っぽかったので、手軽に使いたい自分には悲しい状況になりました。

どうやらボタンイベントに関する挙動で、マウスXY/クリックによるボタン操作と画面タップによるボタン操作の違いに起因してるようです。
他の方法としては正攻法なAndroidSDKのコンポーネントを使うだとかあるみたいなのですが、難しいことは分かりませんし、カジュアルに使えてアプリ作っていきたいので今回簡易的にボタンコンポーネントクラスを作りました。
  • TapButton.pde
    public class TapButton
    {
      float x;
      float y;
      float w;
      float h;
      String s;
      int fontsize;
      boolean visible;
    
      TapButton(float _x, float _y, float _w, float _h, String _s)
      {
        x = _x;
        y = _y;
        w = _w;
        h = _h;
        s = _s;
        fontsize = int(w / s.length());
        visible = true;
      }
    
      void Draw()
      {
        if (visible)
        {
          rectMode(CENTER);
          textAlign(CENTER, CENTER);
          textSize(fontsize);
    
          fill(255);
          rect(x, y, w, h);
          fill(0);
          text(s, x, y, w, h);
        }
      }
    
      void Visible(boolean b)
      {
        visible = b;
      }
    
      boolean Tapped(TouchEvent touchEvent)
      {
        int tapNum = touchEvent . getNumPointers( ) ;
        float tap_x, tap_y;
        if (0 < tapNum)
        {
          tap_x = touchEvent . getPointer( 0 ).x ;
          tap_y = touchEvent . getPointer( 0 ).y ;
          if ( abs(tap_x - this.x) < (w/2) && abs(tap_y - this.y) < (h/2) && this.visible)
          {
            return true;
          }
        }
        return false;
      }
    }
    
    

  • Test.pde
    import android.os.Bundle;
    import android.view.WindowManager;
    
    static int LetterBox = 16; //Letterbox of application draw area
    int sizeW, sizeH;
    boolean flag_backpress = false;//back button press flag
    boolean flag_exit = false;
    
    TapButton tb1 = new TapButton(500, 400, 300, 100, "button1");
    TapButton tb2 = new TapButton(500, 600, 300, 100, "button2");
    
    public void settings()
    {
      sizeW = displayWidth - LetterBox;
      sizeH = displayHeight - LetterBox;
      size(sizeW, sizeH);
    }
    
    public void setup()
    {
    
      frameRate(30);
    }
    
    void backPressed()
    {
      flag_backpress = true;
    }
    
    public void draw()
    {
    
      //DRAWING PROCESS --------------------------------------------------------------
      background(150);
    
      if (mousePressed)
      {
        textSize(50);
        fill(0);
        textAlign(TOP, LEFT);
        text(Integer.toString(mouseX) + "," + Integer.toString(mouseY), 0, 500);
      }
    
      textSize(32);
      fill(0);
      textAlign(TOP, LEFT);
      text(Integer.toString(displayWidth), 0, 150);
      text(Integer.toString(displayHeight), 300, 150);
    
      ellipseMode(CENTER);  // Set ellipseMode to CENTER
      fill(100);  // Set fill to gray
      ellipse(mouseX, mouseY, 100, 100);  // Draw gray ellipse using CENTER mode
    
      //TapButton draw ---------------------------------------------------------------
      tb1.Draw();
      tb2.Draw();
    
      //MAIN LOOP PROCESS ------------------------------------------------------------
      if (flag_backpress)
      {
        flag_backpress = false;
        textAlign(CENTER, CENTER);
        textSize(100);
        fill(255);
        rect(0, sizeH/2 - 80, sizeW, 160, 32);
        fill(0);
        text("Exiting...", sizeW/2, sizeH/2);
        flag_exit = true;
      } else if (flag_exit)
      {
        delay(1000);
        exit();
      }
    }
    
    public void touchStarted(TouchEvent touchEvent)
    {
      int tapNum = touchEvent . getNumPointers( ) ;
      float x = touchEvent . getPointer( 0 ).x ;
      float y = touchEvent . getPointer( 0 ).y ;
    
      //TapButton
      if (tb1.Tapped(touchEvent))
      {
        tb1.Visible(false);
      }
      if (tb2.Tapped(touchEvent))
      {
        tb1.Visible(true);
      }
    }
    
    
テストプログラムは、button1を押すと、button1が消えてbutton2を押すとbutton1が表示されます。
グローバル変数の
TapButton tb1 = new TapButton(500, 400, 300, 100, "button1");
でボタンを定義して、Draw()内の
tb1.Draw();
で描画、タップイベントは
public void touchStarted(TouchEvent touchEvent)内で、
  if (tb1.Tapped(touchEvent))
  {
    tb1.Visible(false);
  }
のようにifで判定してタップ時の処理を書きます。
(ソースコード一部修正:2022/6/12)

2013/06/25(火)IPAexフォント

なんでも作っちゃう、かものarms22さんがTwitterで呟いていたのでメモ。

IPAexフォント
フリーのフォントで、日本語が等幅で素敵なフォントみたいです。
Wordが主流になってからというもの、ワープロや一太郎の時代のようにきっちりまとまった和文を書けなくなったと思っている人には朗報かもしれません。

私は、C#で画像にテキスト出力して、そのビットマップをサーマルプリンタに送るのにいいなと思いました。
やっぱ和文は等幅が一番ですよね。

2013/01/23(水)ブラウザコンポーネント(VS付属とWebKit)

とある事情で数日前から専用ブラウザを製作し始めました。
VisualStudio2005のC#にて開発。
最近はソフト設計だとC#が便利すぎてこればっかり使ってます。昔VC++を使っていたころに比べてソフトに拘る事がなくなったのでコンポーネント豊富でさくっと作れるC#はすばらしいと思っています。

それで、今回もさくっとC#のブラウザコンポーネントを使って製作…が2点問題が発生しました。
  • UserAgantを自由に変更できないこと
  • モバイルサイトでは表示が乱れてしまうこと
この2点は非常に痛い。というか、これが出来なきゃ意味がない。さっそくWebで調べたところUserAgantは簡単に書き換えられることが分かりました。

続きを読む