2012年3月14日水曜日

Inkpod Web 1.1.5 Release


Inkpod Web 1.1.5 をリリースしました。
http://apps.inkpod-web.carabiner.jp/

今回のリリースはバグフィックスのみです。
前回のリリースでスポイト機能に問題が発生してしまった件を修正しました。また、その他細かい挙動の調整を行っています。

詳しい変更点は以下の通りです。

  • スポイト機能が動かなくなった問題を修正
  • 画像ダイアログ、クレジットから閉じるボタンを削除
  • 画像メニューを開いているとき、他を押せないように修正
  • 画像ダイアログを開いたとき、2度目は自動でフォーカスされない問題を修正
  • 画像ダイアログを閉じたときに、キーボードも閉じるように修正
  • 複数選択ボタンを、選択状態で表示が変わるように修正
  • ipadで日本語フォントもserifが表示されるように
  • フォントダイアログの表示がずれる問題を修正
  • フォントダイアログの内容を示しているfamilyで表示するように修正

なお、仕様変更により、Blog埋め込みマップが現在有効になっていません。
埋め込み方法の再検討から行っていますため、今しばらくお待ちください。

2012年3月13日火曜日

Sencha Touch 2.0 の クラスシステム

先週 3/6 に Sencha Touch 2.0 がリリースされました。パフォーマンスの向上と、ネイティブアプリ変換が大きく謳われています。

Inkpod Web でも Sencha Touch を使用しています。現在使用しているのが 1.1 のため、早速バージョンアップしてみたいところですが、内部構造が大きく変わってしまい、すぐには対応は難しそうです。

1.x から 2.x へのマイグレーション方法について、以下に記載があります。
Upgrading from Sencha Touch 1.x to 2.x

コンポーネントが全体的に刷新されましたが、その基幹となるクラスシステムと、データモデルについてシンタックスから大きな変更がありました。

ここでは、そのクラスシステムについて概要をお伝えしたいと思います。How to use classes in Sencha Touch 2 をベースに要点をまとめます。


クラスの基本について

Sencha Touch 2 では、Ext JS4 で開発されたクラスシステムを使うようになりました。
これは、継承、依存関係のロード、ミックスイン、強力な設定オプションなどを提供する JavaScript のクラスを簡単に作ることが出来ます。

次に簡単な例を示します。このアニマルクラスは 名前のプロパティとspeakメソッドを持ちます。
Ext.define('Animal', {
    config: {
        name: null
    },

    constructor: function(config) {
        this.initConfig(config);
    },

    speak: function() {
        alert('grunt');
    }
});
インスタンスを作成するには、Ext.create を使います。
var bob = Ext.create('Animal', {
    name: 'Bob'
});

bob.speak(); //alerts 'grunt'
create の第1引数にクラス名、第2引数に設定オプションを渡します。ここでは、Animalクラスに、name が Bob の初期値をセットしています。
2 での変更点 
以前は、クラスを作成するには Ext.extend で Object を継承していましたが、 Ext.defined でクラスを定義するようになりました。また、インスタンス生成には new を使用していましたが、Ext.create でクラス名を指定します。1で用意されていたほとんどクラスで設定オプションは使えましたが、自分が作成したクラスでは自分で実装する必要があったものが、自動で有効になったようです。
次に、このクラスを継承して、Humanクラスを作成します。
Ext.define('Human', {
    extend: 'Animal',

    speak: function() {
        alert(this.getName());
    }
});
speakメソッドを上書きして、自分の名前を言うようにしました。
Bob を Human にしてみましょう。
var bob = Ext.create('Human', {
    name: 'Bob'
});

bob.speak(); //alerts 'Bob'
Humanクラスを定義するときに、getName というメソッドを使用しましたが、これは定義していません。どこから来たのでしょう。クラスに config オプションを定義すると、次のことが自動的に付与されます。

  • 現在値を返す getterメソッド。ここでは getName()
  • 新しい値をセットする setter メソッド。ここでは  getName()
  • 設定値が変更されたときに、setter から呼ばれる applierメソッド。 ここでは applyName()

getter、setter メソッドは自動的に生成されます。クラスにデータアクセスする場合、この方法を推奨します。Sencha Touch の全てのクラスはこの形式に沿っているため、config オプションが分かれば、値を get/set することができます。

次に、applier の例です。もし、本当に名前を変更したいか、ユーザに毎回聞きたいとします。このとき、applyNameメソッドを定義すれば、自動的にそれが呼ばれます。
Ext.define('Human', {
    extend: 'Animal',

    applyName: function(newName, oldName) {
        return confirm('Are you sure you want to change name to ' + newName + '?')? newName : oldName;
    }
});
ブラウザ組み込みのconfirm関数は確認ダイアログを表示し、YESかNOかユーザに問い合わせます。もし false が返るなら applierメソッドは名前の変更をキャンセルします。

新しいBobを作り名前を変更するときに、プロンプトでNo をクリックします。彼の名前は変更されません。
//訳注: 原文は Person とありますが、typo と思われます 
var bob = Ext.create('Human', {  
    name: 'Bob'
});

bob.setName('Fred'); //確認ダイアログを開き、Noをクリックする

bob.speak(); //まだ 'Bob' のまま

まとめ
  • 全てのクラスは Ext.define で定義される。
  • extend シンタックスを使用してほとんどのクラスは他のクラスを継承しています。
  • インスタンスは Ext.create で生成されます。例: Ext.create('SomeClass', {some: 'configuration'});
  • config シンタックスを使うと getter/setter が自動生成されるため、コードベースをきれいに保てます。

2 での変更点 
継承方法が、Ext.extend から extend というシンタックスに変更されました。
また、以前には無い機能として configオプションの getter/setter と applier ができました。プロパティアクセスよりも、こちらを使用することが推奨されるようです。(個人的には、プロパティアクセスのほうが便利ですが、typoが検知しやすいというメリットはありますね。)


依存関係と動的ローディング 

時々、クラスの中で別のクラスを使うことがあります。ページ内にそれらのクラスがあることを保証するために、requiresシンタックスを使用します。
Ext.define('Human', {
    extend: 'Animal',

    requires: 'Ext.MessageBox',

    speak: function() {
        Ext.Msg.alert(this.getName(), "Speaks...");
    }
});
この方法でクラスを作成すると、Sencha Touch は、Ext.MessageBox が既にロードされているかチェックします。もし無ければ、AJAXを使用して必要なクラスをロードします。

Ext.MessageBox 自身が依存しているクラスも含めてバックグラウンドで自動的にロードされます。Humanクラスが定義された時に一度だけ全てのクラスがロードされ、Ext.create を使ってインスタンスを作成できるようになります。これは、全てのスクリプトのローディングを自分で管理しなくて良いため、開発時に便利です。しかし、プロダクション環境ではお勧めしません。ファイルを1つずつインターネットからロードすることは遅いからです。

プロダクション環境では、アプリケーションで実際に使用しているクラスだけを含んだ、一つのJavaScript ファイルをロードするのが理想です。JSBuilder Tool をを使えば簡単です。これはあなたのコードを解析し、あなたのクラスと実際に使用しているフレームワークのクラスを一つのファイルにまとめます。詳しくは Building guide を参照してください。


命名規則

1. クラス

クラス名は アルファベットと数字のみです。数字も、テクニカルターム以外は推奨されません。アンダースコア、ハイフンなどの記号も使ってはいけません。次に例を示します。

  • 悪い例:  MyCompany.useful_util.Debug_Toolbar
  • 良い例:  MyCompany.util.Base64 

クラス名はパッケージでまとめます。ドット(.)で繋いだオブジェクトプロパティを使います。最低限、一つのユニークなトップレベルネームスペースが必要です。

  • MyCompany.data.CoolProxy
  • MyCompany.Application

トップレベルネームスペースと、実際のクラス名はキャメルケース(単語の頭を大文字)にし、それ以外は全て小文字にします。

  • MyCompany.form.action.AutoLoad

Sencha が提供するクラス以外は Ext をトップレベルに使用しないで下さい。
頭文字の単語もキャメルケースを使用します。

  • Ext.data.JsonProxy (Ext.data.JSONProxy ではなく)
  • MyCompany.util.HtmlParser (MyCompary.parser.HTMLParser ではなく)
  • MyCompany.server.Http (MyCompany.server.HTTP ではなく)

2. ソースファイル

クラス名をそのままファイルパスにします。結果、1クラスは1ファイルになります。

  • Ext.mixin.Observable は、 path/to/src/Ext/mixin/Observable.js
  • Ext.form.action.Submit は、 path/to/src/Ext/form/action/Submit.js
  • MyCompany.chart.axis.Numeric は、 path/to/src/MyCompany/chart/axis/Numeric.js

3. メソッドと変数

クラスメイトほぼ同じです。アルファベットと数字のみで、数字が許されるのはテクニカルタームだけです。メソッドと変数名は常にキャメルケースです。頭文字も同様です。

  • メソッドの例
  • encodeUsingMd5()
    getHtml()              getHTML() の代わりに
    getJsonResponse()      getJSONResponse() の代わりに
    parseXmlContent()      parseXMLContent() の代わりに
  • 変数の例
  • var isGoodName
    var base64Encoder
    var xmlReader
    var httpServer

4. プロパティ

クラスのプロパティ名も定数以外はメソッドと変数と同様です。定数のような静的クラスプロパティは全て大文字にします。

  • Ext.MessageBox.YES = "Yes"
  • Ext.MessageBox.NO = "No"
  • MyCompany.alien.Math.PI = "4.13"


2 での変更点 
今まで特に制約は無かった気がしますが、Extパッケージのファイルは大体これにそっていて変更は無いように思います。今回の動的ローディングや JSBuilder の関係で、より命名規則が大事になったのかもしれません。

原文は、まだ「Working with classes in Sencha Touch 2.0」と続きますが、ひとまずここまで。続きは次の機会で。


2012年2月24日金曜日

Inkpod Web 1.1.4 Release

Inkpod Web version 1.1.4 をリリースしました!
http://apps.inkpod-web.carabiner.jp


今回のリリースは関連線周りのバグフィックスと、機能修正が中心となっています。
細かい修正ですが、より違和感なく使用できるようになりました。


今回より、こちらのBlogのほうへ更新情報を記載するようにしました。
主な修正点は以下の通りです。
  • 関連線のテキストの位置を見直しました。
  • テキストボックスの描画と設定を追加しました。
  • 関連の作成時、対象オブジェクトにフォーカス枠をつけるようにしました。(PCブラウザ)
  • 矢印にそってフォーカスリングを表示するようにしました。
  • 矢印の透明度を上げると、矢尻がはみ出して見えてしまう問題を修正しました。
  • オブジェクトの最小サイズを20から10に変更しました。
  • オブジェクトのサイズを小さくすると文字が消える問題を修正しました。
  • トグルボタンの初期値がONのときラベルが表示されない問題を修正しました。
  • グリッドスナップ時にオブジェクトサイズを変更するとハンドルがずれる問題を修しました。
  • グリッドスナップ時にオブジェクトサイズを変更すると文字の折り返しがずれる問題を修正しました。
  • タッチが3本以上は無視するようにしました。(マルチタスクジェスチャ対応)
  • 一括作成時に空白文字が入っているとインデントがずれる問題を修正しました。

現在、ある大きな新機能を準備中です。
もう少しかかりますが、それまで今しばらくお待ちください。

2012年2月13日月曜日

Inkpod Web 1.1.1 Release

Inkpod Web の version 1.1.1 をリリースしました!
http://apps.inkpod-web.carabiner.jp

今回のアプリケーションのドメイン名が変更になる、という大きな変更がありました。

ドメインの変更は影響が大きいため極力避けたかったのですが、最初に適当なものをつけると後々問題になりますね。。まだ今のうちなら、と今回のタイミングで変更させて頂きました。

ドメインの変更は検索エンジン的にも問題ありますが、Inkpod Webではもっと大きな影響があります。LocalStorage を利用してデータを保存しているため、ドメイン単位でのデータしか持つことが出来ません。
つまり、今回のドメイン変更によって、以前のデータをそのまま利用できなくなってしまいました。

しかし、ご安心ください。
Export/Import機能で、以前のドメインから新しいドメインへデータを移行することが出来ます。ユーザ自ら行う必要がありますが、複数マップのExportも今回のアップデートで対応しましたので、ご面倒ですが何卒よろしくお願いいたします。

もしかすると、データによってはExport/Importで問題が発生するかもしれません。その場合は、是非 こちらでも twitter でも facebook でもバグレポートを頂けると助かります。

なお、機能的に大きな追加はありませんが、使い勝手の向上とバグフィックスが多く反映されています。一覧は 更新情報 をご確認ください。

新しい機能の使い方などについて、またこちらのBlogでお知らせしていこうと思います。

2012年2月1日水曜日

Inkpod Web 1.1 Release

長らくお待たせしました。
やっと 新バージョンをリリースすることが出来ました!

今回は内部構造から見直し、パフォーマンスをかなり改善することができました。その分 時間かかりましたが。。。
特に iPad で使用すると、その違いが顕著にわかると思います。iPad2ならもうネイティブアプリ並!?(w

2011年12月21日水曜日

タスク管理のソーシャルゲーム化

タスクの管理って難しいですよね。
古今東西、色々な手法が考案されて来ました。
どれも整理の手法や効率アップについてよく考えられています。

しかし、タスクを登録するのが億劫になったり、
そもそも仕事をやる気にならない、という問題には目をつぶってきました。

肝心のタスクを登録すること、そしてそれをこなす、
という最重要にして最大の障壁に対して
まだ完璧な解は出ていないのでは無いでしょうか。

そこで、最近流行のゲーミフィケーションをタスク管理に取り入れたらどうだろう。
さらにソーシャル化してしまえば、逃げ場はありません。

結構広がりのあるサービスが考えられます。
ちょっとやってみたいと思いながらマップを書いてみました。

2011年12月19日月曜日

インプット・アウトプットの方法

みなさん日々、いろいろなソースから情報収集していることかと思います。
それらをただ見るだけではもったいないと、ブックマークしたり、Evernote等へクリップしたりとしている人も多いはずです。

単にそのまま溜め込んでいくだけで、本当に大丈夫ですか?
一度自分の考えで咀嚼して、再整理すると、新しい解釈や考えを広げることができます。

それをさらにソーシャルメディアや Blog に、Publicなアウトプットとして出すことで
そのスピードを加速させることができます。

そんなことを考えながら、最近の私の情報の収集・アウトプットの流れをマップにしてみました。