2014年10月27日月曜日

百舌シリーズ 逢坂剛(著)

TV版では Mozu シリーズとしてシーズン2が始まり映画化の話も上がっているようですが。シーズン1から倉木という強烈なキャラクタに魅了され見続けていますが、せっかくなので原書を手にしました。原書は次の全6冊です。



  • 裏切りの日日
  • 百舌を叫ぶ夜
  • 幻の翼
  • 砕かれた鍵
  • よみがえる百舌
  • ノリスの巣


テレビから入った口なので、「裏切りの日日」の存在を「百舌を叫ぶ夜」の終盤の倉木の言葉で前作があることを知りました。これについてはまた今度改めて読んでみたいと思います。

テレビでは「百舌シリーズ」と謳ってますが、実際に百舌という殺し屋が登場するのは「百舌を叫ぶ夜」と「幻の翼」のみで(「よみがえる百舌」も登場するといえば登場するけれど)、wikipedia を見ると「公安警察シリーズ」とあり、そっちのほうがしっくりきます。

内容を超ざっくりいうと公安警察シリーズと書いてあるように、公安警察の闇の部分(政治家や暴力団との癒着等)を取り扱った作品です。倉木尚武、大杉良太、明星美希の3人を中心に公安の闇を暴いていくストーリーです。いくつかの関係なさそうな事件が根っこの部分で紐付いていたり、犯人の認識をすり替えられるような設定をしていたり、緻密に計算されたストーリー展開が面白いですが、登場人物のキャラクタがとても魅力的で、すぐに物語に引き込まれます。後半のページ数は膨大で「よみがえる百舌」に関しては600ページを越えますが、すらすらとページを消化し、1日1冊ペースでした。

TV版との比較ですが、シーズン1の百舌を叫ぶ夜については話の流れや設定はほぼ原作通りでした。ただ、新谷宏美が記憶を取り戻すトラウマはテレビ的には表現できないので、原作にいない有村架純氏が殺されることになったようです。また、最後の爆弾テロのくだりはTV版のみで、ドラマティックに演出するためにそうしたのは、シーズン2への布石ですかね。シーズン2は逆に話の流れが原作とは全然違っています(今の所)。原作には「だるま」も「グラークアルファ作戦」とか出てきませんし。新谷のスパイのくだりは同じにしているようですが。


大変面白く読めましたが正直私は、横暴だけれども正義感強くて頭も切れ、無表情で冷静だが実は情に熱い倉木というキャラクタを堪能したかったのですが、実際は「百舌を叫ぶ夜」「幻の翼」「砕かれた鍵」の3作しか出てこないのが非常に残念でした(あー裏切りの日日にも出ますかね)。ハッピーエンドを期待して読みたいなら「百舌を叫ぶ夜」と「幻の翼」の2冊で十分だと思います。それ以外はハッピーエンドとバッドエンドの中間です。この世界観を堪能したいのであれば全部いっちゃいましょう。









2014年10月19日日曜日

日本人の身体 安田 登 (著)

「膝」という言葉は「膝頭」を指すが、「膝の上に乗せる」というと「太もも」を指すように、日本人は身体を曖昧でおおざっぱに捉えてた。年を重ね、体が不調になると、不調を取り除くのではなく、健全な体は求めず、その不調と付き合っていこうとするのが昔の日本人だった。が、西洋文化が入ってくるにつれ、部位がポイント化され、病気は細分化する。悪いことではないが、危険なところもある。西洋文学との比較、日本古典文化や能の世界観、漢字の語源から「からだ」と「こころ」の本来の在り方を明らかにした一書。






今すごく気になっていることがあって「あとがき」部分を書く。少しだけネタバレを含む。








あとがきにの最後に次のような記述があった。

 体力的なものは考え方ひとつで変わると書いたが、しかしだからといって「考え方ひとつでものごと何とでもなる」というような精神論を開陳する気は毛頭ない。「こういう考え方をすれば体は楽になる」などというハウツーなどもない。
 だいたい「からだがつらい」といっている人に「考え方ひとつで楽になる」などということは決していってはいけない。考え方は一朝一夕には変わらないし、変えてはいけないものなのだ。
カウンセラーがラショナルビリーフを提示することをさらっと否定しているように取れる。私自身20代前半で、とある先輩からの「私はこう思う」という全力のポジティブシンキングにさらされ続けた結果、考え方を大きく変えてきた経験があり、私もそういう存在でありたいと考えていたが、これを読んで一部瓦解した。一律ではダメだ。こと体を壊した人に対しては気をつけなければならない。では、体を壊した人はどうするのがよいか。それについて次のように続き、終わる。

 古典をゆっくりじっくり読んだり、昔の人の世界にたらたらと浸っているうちに、なんとなく体が緩んでくる、それを待つ。それが大事だ。
 最後にちょっと我田引水すると、古典の世界に生きる手っ取り早い道は古典芸能の世界に浸ることだ。古典芸能の舞台に足を運ぶのもいいし、古典芸能を習ってみるのもいいだろう。古くて新しい世界が見えて来る。

「体が緩むまで待つ」という切り口は本当に感銘を受けた。なぜ古典を読んだり、古典芸能の世界に浸ると体が緩んでくるかは、本書に散々例が紹介されているので、気になる人は本書を紐解くことをお勧めする。とはいえ、古典に慣れていない私は読むのに少し骨が折れたので、また改めてじっくり読みたいと思う。



2014年10月18日土曜日

つくられる病: 過剰医療社会と「正常病」 井上 芳保 (著)


セロトニンやドーパミンの分泌に影響を与える薬物が開発できました。だからそれを精神薬として売りたくなりました。そして「うつ病」や「統合失調症」という診断が現場で増えているのです。そういう順番です。断じて逆ではありませんよ。
著者が薬学研究者が聞いた話。うつ病やメタボリックシンドローム。基準値次第で正常にも異常にもなりえる。異常にしてしまえば、なんでも正常でなければならないという強迫観念により、薬は売れる。国や製薬会社の思惑がある。本来は完全な正常なんてありえない。いかにうまく病気と付き合うかを考えるべき。

精神病院(心療内科)の数が圧倒的に多い日本に対し、精神病院をゼロにしたイタリア。精神病になった人を病院に隔離するのではなく、根本原因(社会や環境)の改善に取り組もうという決意の表れである。

メタボ、うつ病が蔓延するようになった理由を垣間見ることができる一書。

2014年10月3日金曜日

VMware Fusion 5 で Windows 10 Technical Preview を動かせてみた

Hyper-Vにインストールした記事はあったけど、VMで動かしたっていう話はまだ見かけてないので、うちのVMware Fusionは一つ前のバージョン(5)ですが、入れてみることにしました。

ISOのダウンロードをしようとこちらにアクセスしてみたら、Macからはダウンロード出来ないみたい。



しょうがないので、Windows 8.1ノートPCを立ち上げてダウンロードした。4.1GBあるんで、少々時間がかかりました。起動するまでの流れを書いて行きます。



VMware Fusion メニューの新規を選び、「オペレーティングシステムのインストールディスクまたはイメージを使用」を選択肢、ダウンロードしたISOを指定して続けるボタンをクリックします。

オペレーティングシステムの選択では、VMware Fusion 5 では Windows 7 しか選べないので、Windows 7 を選んで続けるボタンクリック。
起動前にハードの設定を変更出来るので、メモリ/HDDの容量やパーティションの変更などはここで行いましょう。

起動したらインストールが始まります。
 時間の設定は Japanese にすれば、キーボードとかも自動で変わってくれました。
 Install Now!!!
 ライセンス確認をNext!
 新規なので、下側を選択。
 ディスクを選びます。




  簡易設定かカスタム設定かを 聞かれます。取り急ぎ、簡易設定にしました。
 アカウント設定です。
 Microsoftアカウントを入力します。既存のアカウントにして OneDriveの情報が消えるといやだなと思い、Create a new account で新しいアカウントを作りました。
 勝手にストアアプリがいくつか入るみたいですね。
 無事、起動しました。
ゲスト側(Windows10)もホスト側(Mac)も非常に重たいです。この記事を書くのにクルクル回ってたので、一旦シャットダウンして、仮想OSのメモリを4GBまで拡張しました。

さて、まずは VMware Tools を入れました。


 ポロロンっていう通知でドライブにメディアが入ったことが通知されます。
 通知をクリックすると動作を聞かれました。
 インストールしちゃいます。




 再起動したら無事、インストール出来ました。
 これでフルスクリーン出来ます。



スタートメニューの右側は8のタイルが踏襲されていますね。



タイルにはアプリの右クリックで追加が出来るようです。(Mac側からキャプチャ撮ってますが、コンテキストメニューが消えてしまいます。すいません)





次はタスクビューとやらを見てみましょう。
タスクバーの左から2つめのアイコンをクリックすると開いているウィンドウが整列表示されます。



画面中央下にデスクトップ追加ボタンがあるので、それをクリックするとデスクトップが追加されました。仮想デスクトップというやつです。やっとこの機能がWindowsにも追加されましたね。



追加した仮想デスクトップに表示しているウィンドウを移動させるには、ウィンドウを右クリックして「Move To」から移動先を選択出来るようです。



どうしても Mac OS と比較してしまいますが、そこは右クリックじゃなくてドラッグ&ドロップで移動したいですね〜(Macでは出来る)。じゃないとタブレットとかでの移動が難しいような気がします。仮想デスクトップの切替は、Windowsキー+Ctrl+Left or Rightキーで出来ました。パッパッと切り替わるので、突然表示しているウィンドウが消えてしまうように見えます。Macの仮想ウィンドウがスライドして切り替わるのが如何に素晴らしいのかがよくわかりました(笑)

とりあえず、今日はここまで。







2014年10月1日水曜日

ペンタブ(wacom Creative Pen & Touch Tablet)

を買いました。LINEスタンプネタがノートに溜まってて、デジタル化するとこで止まってたので(膨大な数に挫けます)。本当は Surface Pro3 買っちゃおうとしたけど、13万は超えるし、近いうち iPad 出るし(13万あったら2台買えるやん)、Photoshop も仕事で使うしエトセトラエトセトラでペンタブにしました。


Amazonでぽちっと。


wacom Intuos Pen & Touch small Sサイズ CTH-480/S0

1日ちょいで届きました。早いね。


最新はフォトショがつかないので、一つ前の世代です。
写真にMBAが写ってますが、使うのはモニタが大きい iMac 君で。
あぁ、Microsoft Expression Design も筆圧コントロールに対応しているっぽいので、後で試してみよかな。

最近FileAlpaca が1bitレイヤーに対応したとかいうニュースがありましたが、日本語で話してくれっ!!!ていうぐらい意味がわかってません。デザインなんて「ど」がつく素人なんで、これから色々とお勉強ですな。



末っ子は絵を描くのが好きみたいなので、これで一緒に遊ぼっかな。




2014年9月16日火曜日

ノートンセキュリティ(2014)のインストール

先日、amzonクーポン使って購入したノートンセキュリティが届いたのでインストールしました。ターゲットは MBA に乗っている Windows 7 です。

CDが届いたんですが、ライセンスが書いてある紙を読むと CD からインストール出来るのは Windows のみのようです。折角ですので、CD からインストールしました。


インストール
まず、仮想 OS なので、CD / DVD に接続します。

場合によっては オートラン により自動的にセットアップが起動します。


ん?Norton Internet Security?Norton Securityなのでは?と思いつつ。CDからインストールを選択しました。今の MBA には、ノートンインターネットセキュリティが入っていて、そのままインストール出来るかどうかよくわからなかったのですが、やはり途中でエラーが発生しました。管理者云々。なので、エクスプローラからCDドライブを選択し、 Start.exe を右クリック -> 管理者で実行で起動しました。ら、いきなり Norton Internet Security のアンインストールが始まります。これが始まれば、あとは促されるままに進めることでインストールが完了します。インストールが完了したのですが、ノートンセキュリティとはいえ、実際はノートンインターネットセキュリティでした(苦笑)

おまけ
3台までインストール出来るので、iMac にも入れてみました。
インストール自体はチャチャっと出来ましたが、


LiveUpdate にはやたら時間がかかります。


ちなみにメニューバーにはこのように表示され、アクセス出来るようになります。





【CMD】バッチファイルでIPアドレスの変更

よく使うので、忘れないように。
IPアドレスを自動的に取得する
netsh interface ip set address "イーサネット" dhcp

次のIPアドレスを使う
netsh interface ip set address "イーサネット" static IPアドレス サブネットマスク デフォルトゲートウェイ

2014年9月13日土曜日

申し訳ない、御社をつぶしたのは私です。 カレン・フェラン (著), 神崎 朗子 (翻訳)

大胆なタイトル、奇抜な見出しで目を引きますね。このコンサルタントを完全否定するようなぶっ壊す感じ、私は大好きです。しかし、内容は堅実です。本書は数々のコンサルファームや有名な企業を渡り歩いてきた著者からの次のようなメッセージでした。(私の適当な解釈による要約)

世の中を動かすのは人間で、一人として同じ人間がいない世の中。そこで標準化/確立化されたコンサル用ツールは、全ての組織において効果を発揮するわけではない。ツールはある程度数値化出来るので便利だが、やっているうちに数値化することが仕事だと錯覚してしまう。手段が目的化する落とし穴に誰もがはまってしまう。そうではなく、人間を見よう。現場の人間の声を聞こう。要諦はそこにある。

私も独立するまで10年ほど一般企業に勤めていた経験があり、コンサルティングはあまりわかりませんが、プロジェクトマネージャー関係はそれなりに学習していました。それもあって、コンサルティングとは関係なくても、管理者目線で全然読めます。むしろ管理者であるなら絶対に目を通しておくべきです。役職あるなら必読です。管理者や従業員は一体、管理のためにどれだけ無駄な時間を費やしたことか。戦略なしで現場の戦術にたよるの?とかね。

読んでて昔の記憶がフラッシュバックしたんですが、ちょっと吐き出します。あるプロジェクトで一緒になった結構年上の主任と何人かでランチをしている折に、昔その主任が面倒を見ていた女性が退職した話になりました。退職した女性は確かに扱いづらい人だったのかもしれませんが、その主任は結構厳しく当たっていたため、うつ病になり休業し、そのまま退職したという流れです。退職したと聞いた瞬間、こともあろうにその主任はガッツポーズをしました。ぅおい!管理者として最低だなと思いました。というか人として。自分は未熟な後輩を育成することが出来ない人間ですと宣言したことに気づいていないんですね。その後、その主任はマネージャーに昇格しました。あぁ、この会社ダメだー、現場を全然見てないわーとがっかりしました。数値だけ見て現場を見てない。数値だけはそこそこ良かったですからね。でもそのよかった理由も優秀なメンバーがかなりフォローしてた結果ですよ。この会社にしてこのマネージャありといいますか。本書でピーターの法則も実際に有り得るという指摘も、実際にありえました(苦笑)


話は戻って、他にもうなずいた所や斬新だなと思ったところを覚え書きます。(要点の箇条書き)


  • 戦略開発は将来予測ではなく自己発見だから上層部だけでやるのではなく従業員全員を巻き込むべき
  • 業績管理システムいつのまにか従業員を在庫品のように評価してレッテルを張り、追跡するシステムになってしまう
  • そもそも客観的評価はありえなくて、点数付けるのは主観でしかないからインセンティブ報酬はやめて、業界より少し上回る報酬にすべき
  • マネジメントのテクニックなど無く、よい関係を築くことしかやってない
  • リーダーの行動規範は34もあり、全部出来る人間なんてそうはいない、むしろスティーブジョブズ氏のように全然当てはまらないのに優秀なリーダーはいる
  • タレントマネジメントはペーパーワークや評価付けに追われて、肝心の社員同士の交流が妨げられる
  • 頭を使いたくないからコンサルを使うのは間違い

などなど、、、ほんとはもっと詳しく書きたいですが控えます。私が組織運営するようになったらまた改めて読もうと思います。






2014年9月11日木曜日

Mac用のOneDriveアプリ

HDDの破損にビビって、重要なファイルはクラウド(とりあえずOneDrive)に置くことにしました。MacからOneDriveにフォルダごと一気に入れたかったのですが、ツールじゃないと無理だということでツールを入れました。

で、早速やってみたところ、落ちる落ちる。もう30回くらいは落ちたので、あきらめて①ファイルずつアップロードしました。(あまり使わないのはアーカイブにして)

私の中で、OneDriveの評価は高かったのですが、なんだかなー。もうちょっと頑張ってよ>Microsoft という気分です。


Windows からやればいんだけど、やれない事情があってね。
Google Drive は Gmail が流出したとか、ファイルを閲覧されそうな印象なので却下。
DropBoxは別の要件で使っているので使えない。
他になんかいーのないかなー。


医療の選択 桐野 高明 (著)

北海道に行った際、新千歳から旭川に向かう道中で同行した後輩3人が医療関係に携わっていて、医療の現場で今起こっていることを色々と教えてもらった。私はシステム屋なので、7年くらい前に調剤システムを作ったことがあるぐらいの全くの門外漢。前提となる知識があったらもっと話が盛り上がっただろうなと思い、本書:医療の選択を手にしました。

読んではみましたが、レビューを書こうという気が起きず、もう4日ほど放置していたのですが、嫁さんと本書についての話をしたり、茂木健一郎氏の本日の連続ツイート【「今、ここ」を生きる子どもたちにとって】(https://www.facebook.com/kenichiromogiqualia/posts/578593068934021
を読んで、自分の中で消化しておく必要があると思い、筆を執った(キーを叩いた)次第です。


何故、レビューを書く気がしなかったかというと、きっと私の読み方が悪かったのだろうと思いますが、どこに向かって話が進んでいるのか全く汲み取れなかったのです。現在の医療システムを歴史の流れにそって纏めてくれてはいますが、著者の桐野氏の意見というものがあまりなく、結局何がい言いたかったのかがよくわからなかったというのが正直なところです。また、いくつか選択肢があるとしても、医療システムに縁遠い私にとって、それらの選択肢に手が届くことはまずないのではないか?とどこか遠い話のように感じたからです。茂木氏の「システム論よりも、自分たちの具体的な選択の方が大切」というのを読んで、その通りだなと思いました。またその発想を受け、私ならどう選択するというシミュレーションをして行くことはアリだと思いました。シミュレーションしていなければ、チャンスが巡って来たときに即座に手を挙げることは出来ないですからね。

でまぁ、本書を振り返ってみたわけですが。世界の医療の現状と行き詰まりが結構よく纏まっていますね。全体的にざくーっと私なりに纏めてしまうと次のような感じでしょうか。(章の前後関係はばらばらです)

税金と社会保障の関係は次の4つに分類出来ます。
①高負担、低給付
②低負担、高給付
③高負担、高給付
④低負担、低給付
①は国民感情的に受け入れ不可能、②はウェルカムだけど国内に油田があるなど莫大な資源が無いと無理、③は大きな政府、④は小さな政府であると。小さな政府というのは発展途上国などにみられる社会保障はある程度無視して経済発展を優先させる社会です(経済が潤うと社会保障分が増えるという説もある)。先進諸国は概ね③を選択していますが、システムはバラバラです。アメリカは自由を選択し、日本は国民皆保険、イギリスでは無料で医療が受けれるNHSというシステムを選択しています。それぞれが今、行き詰まりつつあります。医療技術とその資金だったり、施術が始まるまでの時間だったり云々。高齢者の介護であったり、医薬品の開発であったり。大きな舵取りは出来ないけど今のシステムの中で少しずつ変えていくしかないようです。

医療とは直接的に関係ないですが、国債に対する指摘はなるほどな!!!と思いました。1000兆円の国債で金利が0.1%上がると10兆円が吹っ飛びますが、それは消費税4%分にあたるという話。国債を発行しても富裕層が富むだけで、国民への負担が増えるだけなんですね。

知らないことだらけで、知らないというのは怖いと改めて感じました。
色々と遠い話ですが、今何が出来るのかを考えていきたいです。

[WPF][Silverlight][C#] ScrollViewer でマウスでの横スクロールと慣性スクロール

将来的に横スクロールにしたいという話があって、事前調査してみました。
やりたいことは下記3つ。
  1. マウスホイールで横スクロール
  2. ドラッグで横スクロール
  3. 慣性スクロール
あんまり情報ないですねー。とりあえずざくっとと作ってみたので、コードだけ紹介します。WPF版では ScrollViewer のカスタムコントロールで、Silverlight では ScrollViewer  を継承できないので Behavior で作りました。ほぼ同じようなコードになってます。加速度までは考慮していないのであしからず。

WPF版(Custom Control)
    /// <summary>
    /// 慣性スクロールビューア
    /// </summary>
    public class MomentumScrollViewer : ScrollViewer
    {
        #region インスタンスフィールド
        /// <summary>
        /// マウスオフセット位置
        /// </summary>
        private double mouseOffset;
        /// <summary>
        /// 開始位置
        /// </summary>
        private double startOffset;
        /// <summary>
        /// プレス有無
        /// </summary>
        private bool isPressed = false;
        /// <summary>
        /// 最終位置
        /// </summary>
        private double lastPosition;
        /// <summary>
        /// 移動量
        /// </summary>
        private double momentumValue;
        #endregion
        #region 依存プロパティ
        /// <summary>
        /// 運動量を取得または設定します。
        /// </summary>
        public double MomentumValue
        {
            get { return (double)GetValue(MomentumValueProperty); }
            set { SetValue(MomentumValueProperty, value); }
        }
        /// <summary>
        /// 運動量依存関係プロパティを識別します。
        /// </summary>
        public static readonly DependencyProperty MomentumValueProperty =
            DependencyProperty.Register("MomentumValue", typeof(double), typeof(MomentumScrollViewer), new PropertyMetadata(0.5));
        /// <summary>
        /// 水平位置を取得または設定します。
        /// </summary>
        public double HorizontalPosition
        {
            get { return (double)GetValue(HorizontalPositionProperty); }
            set { SetValue(HorizontalPositionProperty, value); }
        }
        /// <summary>
        /// 水平位置依存関係プロパティを識別します。
        /// </summary>
        public static readonly DependencyProperty HorizontalPositionProperty =
            DependencyProperty.Register("HorizontalPosition", typeof(double), typeof(MomentumScrollViewer), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnHorizontalPositionChanged)));
        #endregion
        #region コンストラクタ
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MomentumScrollViewer()
        {
            // 各イベント登録
            this.PreviewMouseWheel += MomentumScrollViewer_PreviewMouseWheel;
            this.Loaded += (sender, e) =>
                {
                    var content = this.GetValue(ScrollViewer.ContentProperty) as FrameworkElement;
                    if (content != null)
                    {
                        content.MouseLeftButtonDown += content_MouseLeftButtonDown;
                        content.MouseLeftButtonUp += content_MouseLeftButtonUp;
                        content.MouseMove += content_MouseMove;
                        content.MouseLeave += content_MouseLeave;
                    }
                };
        }
        #endregion
        #region イベント
        /// <summary>
        /// 水平スクロール位置変更イベント
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        private static void OnHorizontalPositionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var scrollViewer = obj as MomentumScrollViewer;
            if (scrollViewer != null)
            {
                scrollViewer.ScrollToHorizontalOffset((double)e.NewValue);
            }
        }
        #region ホイールでのスクロール
        /// <summary>
        /// マウスホイールイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MomentumScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            beginScroll(e.Delta);
            e.Handled = true;
        }
        #endregion
        #region ドラッグによるスクロール
        /// <summary>
        /// 左ボタンダウンイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void content_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var position = e.GetPosition(this);
            this.mouseOffset = position.X;
            this.startOffset = this.HorizontalOffset;
            this.isPressed = true;
        }
        /// <summary>
        /// マウス移動イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void content_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.isPressed)
            {
                var position = e.GetPosition(this);
                // 前回値からの運動量を保持し、前回値を更新
                momentumValue = lastPosition - position.X;
                lastPosition = position.X;
                // 変化量を算出し、スクロール
                var delta = (position.X > mouseOffset) ? -(position.X - mouseOffset) : mouseOffset - position.X;
                this.ScrollToHorizontalOffset(startOffset + delta);
            }
        }
        /// <summary>
        /// マウスリーブイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void content_MouseLeave(object sender, MouseEventArgs e)
        {
            dragEnd();
        }
        /// <summary>
        /// 左ボタンアップイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void content_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            dragEnd();
        }
        #endregion
        #endregion
        #region プライベートメソッド
        /// <summary>
        /// ドラッグ終了処理
        /// </summary>
        private void dragEnd()
        {
            if (this.isPressed)
            {
                this.isPressed = false;
                // 運動量がある場合は慣性スクロール
                if (momentumValue != 0)
                {
                    beginScroll(momentumValue * (-1));
                }
            }
        }

        /// <summary>
        /// 慣性スクロール開始
        /// </summary>
        /// <param name="delta">変化量</param>
        private void beginScroll(double delta)
        {
            // 目的地設定
            var to = HorizontalOffset - delta * MomentumValue;
            if (to < 0)
                to = 0;
            if (to > ExtentWidth)
                to = ExtentWidth;
            // 慣性スクロールアニメーション開始
            var animation = new DoubleAnimation(to, new Duration(TimeSpan.FromMilliseconds(1000)));
            animation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut };
            this.BeginAnimation(MomentumScrollViewer.HorizontalPositionProperty, animation);
        }
        #endregion
    }


Sivlerlight版(Behavior)
    /// <summary>
    /// 慣性スクロールビヘイビア
    /// </summary>
    public class MomentumScrollingBehavior : Behavior<ScrollViewer>
    {
        #region インスタンスフィールド
        /// <summary>
        /// マウスオフセット位置
        /// </summary>
        private double mouseOffset;
        /// <summary>
        /// 開始位置
        /// </summary>
        private double startOffset;
        /// <summary>
        /// プレス有無
        /// </summary>
        private bool isPressed = false;
        /// <summary>
        /// 最終位置
        /// </summary>
        private double lastPosition;
        /// <summary>
        /// 移動量
        /// </summary>
        private double momentumValue;
        #endregion
        #region 依存プロパティ
        /// <summary>
        /// 運動量を取得または設定します。
        /// </summary>
        public double MomentumValue
        {
            get { return (double)GetValue(MomentumValueProperty); }
            set { SetValue(MomentumValueProperty, value); }
        }
        /// <summary>
        /// 運動量依存関係プロパティを識別します。
        /// </summary>
        public static readonly DependencyProperty MomentumValueProperty =
            DependencyProperty.Register("MomentumValue", typeof(double), typeof(MomentumScrollingBehavior), new PropertyMetadata(0.5));
        /// <summary>
        /// 水平位置を取得または設定します。
        /// </summary>
        public double HorizontalPosition
        {
            get { return (double)GetValue(HorizontalPositionProperty); }
            set { SetValue(HorizontalPositionProperty, value); }
        }
        /// <summary>
        /// 水平位置依存関係プロパティを識別します。
        /// </summary>
        public static readonly DependencyProperty HorizontalPositionProperty =
            DependencyProperty.Register("HorizontalPosition", typeof(double), typeof(MomentumScrollingBehavior), new PropertyMetadata(0.0, new PropertyChangedCallback(OnHorizontalPositionChanged)));
        #endregion

        #region イベント
        /// <summary>
        /// アタッチ完了
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.MouseWheel += scrollViewer_MouseWheel;
            this.AssociatedObject.Loaded += (sender, e) =>
            {
                var content = this.AssociatedObject.GetValue(ScrollViewer.ContentProperty) as FrameworkElement;
                if (content != null)
                {
                    content.MouseLeftButtonDown += content_MouseLeftButtonDown;
                    content.MouseLeftButtonUp += content_MouseLeftButtonUp;
                    content.MouseMove += content_MouseMove;
                    content.MouseLeave += content_MouseLeave;
                }
            };
        }
        /// <summary>
        /// デタッチ
        /// </summary>
        protected override void OnDetaching()
        {
            this.AssociatedObject.MouseWheel -= scrollViewer_MouseWheel;
            var content = this.AssociatedObject.GetValue(ScrollViewer.ContentProperty) as FrameworkElement;
            if (content != null)
            {
                content.MouseLeftButtonDown -= content_MouseLeftButtonDown;
                content.MouseLeftButtonUp -= content_MouseLeftButtonUp;
                content.MouseMove -= content_MouseMove;
                content.MouseLeave -= content_MouseLeave;
            }
            base.OnDetaching();
        }
        /// <summary>
        /// 水平スクロール位置変更イベント
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        private static void OnHorizontalPositionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var behavior = obj as MomentumScrollingBehavior;
            if (behavior != null)
            {
                behavior.AssociatedObject.ScrollToHorizontalOffset((double)e.NewValue);
            }
        }
        /// <summary>
        /// マウスホイールイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void scrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            beginScroll(e.Delta);
            e.Handled = true;
        }
        #region ドラッグによるスクロール
        /// <summary>
        /// 左ボタンダウンイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void content_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var position = e.GetPosition(this.AssociatedObject);
            this.mouseOffset = position.X;
            this.startOffset = this.AssociatedObject.HorizontalOffset;
            this.isPressed = true;
        }
        /// <summary>
        /// マウス移動イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void content_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.isPressed)
            {
                var position = e.GetPosition(this.AssociatedObject);
                // 前回値からの運動量を保持し、前回値を更新
                momentumValue = lastPosition - position.X;
                lastPosition = position.X;
                // 変化量を算出し、スクロール
                var delta = (position.X > mouseOffset) ? -(position.X - mouseOffset) : mouseOffset - position.X;
                this.AssociatedObject.ScrollToHorizontalOffset(startOffset + delta);
            }
        }
        /// <summary>
        /// マウスリーブイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void content_MouseLeave(object sender, MouseEventArgs e)
        {
            dragEnd();
        }
        /// <summary>
        /// 左ボタンアップイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void content_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            dragEnd();
        }
        #endregion
        #endregion
        #region プライベートメソッド
        /// <summary>
        /// ドラッグ終了処理
        /// </summary>
        private void dragEnd()
        {
            if (this.isPressed)
            {
                this.isPressed = false;
                // 運動量がある場合は慣性スクロール
                if (momentumValue != 0)
                {
                    beginScroll(momentumValue * (-1));
                }
            }
        }

        /// <summary>
        /// 慣性スクロール開始
        /// </summary>
        /// <param name="delta">変化量</param>
        private void beginScroll(double delta)
        {
            // 目的地設定
            var to = this.AssociatedObject.HorizontalOffset - delta * MomentumValue;
            if (to < 0)
                to = 0;
            if (to > this.AssociatedObject.ExtentWidth)
                to = this.AssociatedObject.ExtentWidth;
            // 慣性スクロールアニメーション開始
            var storyboard = new Storyboard();
            storyboard.Children.Add(new DoubleAnimation()
            {
                From = this.AssociatedObject.HorizontalOffset,
                To = to,
                Duration = new Duration(TimeSpan.FromMilliseconds(1000)),
                EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut }
            });
            Storyboard.SetTarget(storyboard, this);
            Storyboard.SetTargetProperty(storyboard, new PropertyPath("HorizontalPosition"));
            storyboard.Begin();
        }
        #endregion
    }










2014年9月9日火曜日

[Expression Design]使い方 - エクスポート

お絵かきしたものを PNG ファイル等に出力してみましょう。


メニューから ファイル - エクスポートをクリックします。コントロールキーとEキーがショートカットです。


出力設定画面が表示されるので、サイズや形式を指定して「すべてエクスポート」ボタンをクリックします。


出力結果はこんな感じです。

 

ちなみに出力できる形式は、以下の通りです。


  • XAML Silverlight 3 キャンバス
  • XAML WPF ResourceDictionary
  • XAML Silverlight 4 / WPFキャンバス
  • SVG
  • PNG
  • JPEG
  • TIFF
  • BMP
  • WDP
  • PSD
  • PDF
XAML は Windows のプレゼンテーションの基盤である UI 言語です。
Microsoft の意図をくみ取ると、デザイナさんには最終的に Visual Studio を使ってもらいたいのかもしれませんねぇ。

  1. Photoshop ( PSD )
  2. Expression Design
  3. Expression Blend
  4. Visual Studio


[Expression Design]使い方 - エフェクト

エフェクトの見え方を一覧的にしてみました。








各エフェクトを複合的に使うことが出来るので、その効果は無限大ですかねー。

[Expression Design]使い方 - お絵描き

ポリラインを使ってお絵描きをしてみましょう。
左端のツールバーからペンのところを長押しすると出てくるドロップダウンメニューからポリラインを選択してください。



星を描いてみよう

星の角のところを適当にクリックしてつなげます。(色はプロパティタブで変更してね。変更方法は「文字の操作」を参考にしてみてください。


次に角の位置の変更を行います。
左側のツールバーの個別選択を選択します。


これで角の赤点を移動出来るようになります。ドラッグ&ドロップです。


グリッドにあわせてうまく整形しましょう。



サイズ変更
サイズ変更を行う場合、左端のツールバーから選択内容を選択します。


サイズ変更したいオブジェクトをクリックすると8個の点が表示されます。
それをドラッグ&ドロップでサイズが変更出来るようになります。


縦横比固定
サイズ変更を行う際に縦横の比率はそのままとしたい場合、シフトキー+ドラッグで縦横比を維持したままサイズの変更を行えます。



回転

オブジェクトを回転させる場合は、四隅のいずれかの点のちょっと外側をドラッグすることで回転します。


斜めに傾ける
各辺の中間にある点のちょっと外側をドラッグするとオブジェクトを斜めにヒョジすることが出来ます。




アンカーポイント削除
左端ツールバーのペンを長押しすることで表示されるドロップダウンメニューから「アンカーポイントの削除」をクリックします。消去したいアンカーポイントをクリックすることでアンカーポイントを削除出来ます。



アンカーポイントをなだらかに
アンカーポイントの変換を行うことで、角張っているのを滑らかにすることが出来ます。



星は星でも光っている感じのが出来上がります。


グループ化
同じ要素を選択し、右クリック - グループ化しておくことで、纏めて移動させたい時に1つだけ移動させれば付いてくるようになったり、あとから変更する際に一気に変更することが出来るようになります。



半透明にしよう
プロパティタブの外観のところにある不透明度を調整することで、半透明にすることが出来るようになります。


グラデーション
グラデーションラベルを選択すると単色からグラデーションに変更されます。


色の変更は下図の赤四角枠をクリックして色を選択することで行えます。


グラデーションを放射状にするには右端の「放射状グラデーション」をクリックします。


グラデーションのポイントも追加出来るし、グラデーションの中点も調整出来ます。



これぐらい出来ればある程度描けますね。