Modern UI for WPFのデフォルトレイアウトを変更する方法

どーも。panjaです。

最近WPFを触っています。
WPFはWinFormsに変わるユーザーインターフェースシステムでなんかかっこいいことが出来そうな感じのものです。
Windows Presentation Foundation - Wikipedia

UIのライブラリ(違う?フレームワーク?)としてModern UI for WPF(MUI)を使用しています。
github.com

あるアプリの作成にMUIを使用していたのですが、どーにもデフォルトのレイアウトが気に入らない!と思ったので変更する方法を調べてみました。
今回はその結果を紹介してみます。

手順は以下の通りです。

  1. Modern UI for WPF(MUI)をダウンロードしてきます。GitHub - firstfloorsoftware/mui: Modern UI for WPF
  2. ダウンロードしたものの中に「FirstFloor.ModernUI.sln」が入っているので開きます。
  3. 「$(SolutionDir)¥FirstFloor.ModernUI¥Themes¥ModernWindow.xaml」を開きます。
  4. 29行目(2017/01/25現在)の
<ControlTemplate TargetType="controls:ModernWindow">

から197行目の

</ControlTemplate>

の中でMUIのテンプレートプロジェクトのメインウィンドウであるModernWindowのレイアウトを決定しているので、変更したい項目を探し出して好きなように変更する。
5. ソリューションをビルドする

これでOKです。
あとは、新しいテンプレートを使用したいプロジェクトの参照に先ほどビルドしたFirstFloor.ModernUI.dll追加すれば使用できるようになります。



以下に、私が実際に行った変更を載せておきます。
具体的には下の画像の赤枠のスペースを無くす変更を行いました。
(青色のRectangleを目一杯広げたページを表示しています。赤枠はGimpで追加しました。)
f:id:panda531531:20170125232135p:plain


ここに表示されるページに関する変更は「ModernWindow.xaml」の160、161行目

<!-- content frame -->
<controls:ModernFrame x:Name="ContentFrame" Grid.Row="3" Grid.RowSpan="2" Margin="42,8,16,16" Source="{Binding ContentSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" ContentLoader="{TemplateBinding ContentLoader}"/>

で行います。
赤枠のスペースを無くすためには、ここに設定してある「Margin="42,8,16,16"」を好きな値に変更してあげれば変更完了です。
今回は「Margin="5,0,5,5"」に変更しました。
結果は以下のようになりました。
f:id:panda531531:20170125231757p:plain

はい。変更できました。



まだまだわからないことだらけのWPF
今後も忘備録的にまとめていきたいと思います。
内容に誤りなどありましたら是非コメントよろしくお願いします。

Jenkinsのビルドログにご用心

どーも。

今回はJenkinsのビルドログファイルについてです。

普段の開発では、社内サーバー上でJenkinsを動かしています。
試行錯誤を繰り返しながら、やっとこさある程度安定して動作するようになりました。

Jenkinsについて知らない方はこのスライドなんかを呼んでみるといいかもしれません。

www.slideshare.net

現時点の構成としては、Subversionのpost-commitフック内でjobを走らせています。
job内ではビルド、テスト実行、CppCheckによる静的解析、SourceMonitorによるメトリクス計測、Doxygenによるドキュメント発行、結果のメール送信などを行っています。
とにかく出来ることを詰め込みまくった感じです。
(もっとこんなこと出来るよってのがあったら是非教えてください)

また、同じく社内サーバー上で動かしているRedmineとの連携も出来るようにしています。



さて、本題です。

Jenkins、Redmineなどを動かしている社内サーバーのストレージが一杯になってしまうということが先日起きてしまいました。
もともとCIサーバーになどするつもりの無いサーバーを勝手に(一応許可はもらってましたが)ごちょごちょしたツケが回ってきたようです。

開発が進むにつれてコード量も多くなってきていたのでその辺が原因だろうなーと思ったので、可能な限りシンボリックリンクを貼って中間生成物をそっちに吐いてみたりしました。
一旦はそれで問題なかったのですが、しばらくすると現象が再現してしまいました。

どうにかならんかなーと色々調査していたら以下の記事を発見!
qiita.com
「古いビルドの破棄」、、、たしかにあった気がするな。


ということでビルドログがどれくらい残っているか確認してみました。
ちなみにこの時点でのjobのビルド数は3500くらいでした。
ビルドログの場所はここでした↓。
%JENKINS_HOME%¥jobs¥(job名)¥log

早速サイズを確認してみると、、、70GB!
Cドライブが200GBしかないので35%をビルドログが占めていたことになります。

というわけで原因がわかったので、古いログをバックアップしてjobの設定で最大100ビルド(最長30日)分のビルドログしか残さないように変更しました。

「古いビルドの破棄」のオプションはデフォルトでONにしておいてくれてもいいような気がするんですがどうなんでしょうね。
また一つ勉強になりました。

clcacheを使ってVisualStudio2013のビルド(コンパイル)高速化

どーも。panjaです。

関西もだいぶ寒くなってきましたね。
体調を崩さないように手洗いうがいをしっかりしましょう。

さて、今回はccacheの亜種のclcacheについてです。

ccacheとは

まずはccacheについて。
ccache — Overview

Wikipediaさんによると、(ccache - Wikipedia)

ccacheとは、CまたはC++コンパイラが出力するデータをキャッシュするソフトウェア開発ツールである。その目的は、2回目以降のソフトウェアビルドにおいてはコンパイルを避け、出力結果を再利用することにある。これは再コンパイル速度を劇的に改善する。

ということです。
C、C++Objective-CObjective-C++に対応しています。
「遅いビルドは悪!」とレガシーコード改善ガイド(7.2章)にも記述があるように、なんとかビルドの高速化が出来ないかと思っていた矢先に出会いました。

しかし、、、こいつは普段VisualStudioで開発している私とは仲良くなれないやつだったのです。
VC++コンパイラcl.exeでは使えないとのことでした。(GCC系のコンパイラしか対応していない)


VC++で使えるやつないかー、と探して見つけたのが今回の本題clcacheです。

clcacheとは

ではclcacheについて書いていきます。
github.com

clchacheはGitHubで公開されているVC++用のコンパイラキャッシュです。

上記4つの情報を基にハッシュを生成して、2度目以降のコンパイル時の判定に使用しているようです。

GitHub上ではclcache.pyというpythonスクリプトファイルが公開されており、このファイルをpyinstallerを使ってexe化して使うというのが基本的な流れになります。

実際の流れは以下のような感じです。

(事前準備)
Python(ver3.3以上)をインストールしておく
・以下のコマンドでpyinstallerをインストールしておく

pip install pyinstaller


(手順)
1. GitHub - frerich/clcache: A compiler cache for MSVC, much like ccache for gcc から任意の場所にcloneしてくる(もしくはzipでダウンロードして展開する)
2. 以下のコマンドでclcache.pyの内容をexe化する(clcache.exeというファイルが./dist/以下に生成されます)

pyinstaller --onefile clcache.py

3. 任意の場所に(例えばC:¥clcache¥bin¥)にclcache.exeをコピーしcl.exeにリネームする
4. この場所にパスを通す(システム環境変数のPathの最初に追加)*2
5. 必要なら再起動する

以上で使えるようになっているはずです。
GitHub - frerich/clcache: A compiler cache for MSVC, much like ccache for gcc の「Installation for Visual Studio」という項目に別の方法が記載されていますが、私の場合はこの方法では上手くいきませんでした。環境によって結果は異なると思いますので注意してください。)

おもむろにVisualStudioを立ち上げてソリューションをリビルドしましょう。
1回目は今まで通り時間がかかります。





はい、終わりました。

適当に編集をして再度ビルドすると、、、


なんということでしょう~
すぐに終わりました(か?)

結果

ではどれくらい早くなったのか見てみましょう。

あるファイルを1行だけ改行させてビルドした結果です。
最適化手法によっても変わるのかな−と思ったので「最適化無効(/Od)」、「実行時間優先(/O2)」、「最大限の最適化(/Ox)」の3種類で試してみました。

clcacheを使わない場合はこんな感じでした。

最適化手法 コンパイル時間①*3 リンク時間*4 合計
無効(/Od) 40sec 80sec 120sec
実行時間優先(/O2) 40sec 110sec 150sec
最大限の最適化(/Ox) 37sec 110sec 147sec

はい。
コンパイルよりリンクに時間かかってますねぇ。。。。
今回はコンパイル時間を短縮するのが目的なのでこの問題はまた後で考えることにします。


clcacheを使った場合はこんな感じ。

最適化手法 コンパイル時間② リンク時間 合計 ②/①
無効(/Od) 22sec 74sec 96sec 0.55
実行時間優先(/O2) 36sec 100sec 136sec 0.9
最大限の最適化(/Ox) 37sec 98sec 135sec 1

はい。

なんだか微妙な結果です。
他のページに書いてあるような劇的な効果はありませんでした。
それどころか最大限の最適化を行った場合はあっても無くても同じという結果になりました。
まぁ最適化をしない場合には半分くらいにはなっているのでこの場合は有効と言えそうです。

まとめ

最適化を行わない場合はclcacheを使用してコンパイル時間が短くなることが確認できました。
ただ、他のページに紹介してあるような劇的な効果は今回は得られませんでした。

普段の開発ではclcacheを有効にしておいて、最適化は無効にしておくのが良さそうです。(もちろんリリース時に有効にする必要があります)
実験方法も悪いような気がしますし、継続的に効果を確認していきたいと思います。



リンク時間はどうやって短くできるんだろうか。。。

*1:The `normalized' command line

*2:本物のcl.exeをシステムが見つけてしまう前にこのcl.exeを見つけるための設定だと思います

*3:cl.exeが動いている時間を測りました

*4:link.exeが動いている時間を測りました

落ち葉アート

どーも。
panjaです。

先週末に息子と一緒に近所の公園を散歩(息子はストライダーで爆走)していた時に、きれいな落ち葉アートを見つけました。

数日前にツイッターで話題になってたやつを誰か真似したんだろーなー、なんてことを考えていました。

今度は息子と一緒になんか作ってみようかな。

tesseract-ocrを使って紙の書籍のソースコードを読んでみた

どーも。panjaです。

通勤中にちまちまと「レガシーコード改善ガイド」を読んでいます。

レガシーコード改善ガイド

レガシーコード改善ガイド

文章中にはちょいちょいC++Javaコードスニペットが現れるのですが、普段IDEの力を借りて開発してることもあり、構文強調表示が無いとまぁ頭に入ってきません。
そんなことを思いながらなので当然モチベーションーも下がってきます。

どうにかしたいなーとぼんやり考えていたのですが、とりあえずデータ化しないと何も出来ないだろうということでOCRにチャレンジしてみました。

使用したOCRライブラリはtesseract-ocrです。元々はHPが開発していたらしいですが、今はGoogleが管理しているようです。オープンソースということで気軽に使用出来ます。
github.com

今回は自作のプログラムで使いたかったので、Githubからクローンしてきてビルドしたものを使いました。その辺の手順なんかはググってもらえればたくさん出てくると思いますので割愛します。


VisualStudio2013でtesseract-ocrをビルドして新規にソリューションを作成しました。
適当にパスなどを通してあげると使えるようになります。
dogear11.hatenablog.com
基本的に上記のページを参考にさせてもらいました。コードもほとんど同じです。

早速結果を見てみましょう。
以下は「レガシーコード改善ガイド」の一部をスキャンしたものです。
f:id:panda531531:20161124233105j:plain

この画像から文字を読み取ってみると......
f:id:panda531531:20161124233125p:plain

。。。。。。
前半はかなりいい感じですが、後半グダグダですね。
※「recognized text:」はOCRの結果ではありません

ソースコード自体弧を描いてるのはかなりまずい気がします。
が、とりあえず入力画像を2値化してみることにしました。


2値化した入力画像がこちらです。
f:id:panda531531:20161124233028j:plain
ゴミも残っていますが、文字自体は結構いい感じに2値化されています。

結果がこちらです。
f:id:panda531531:20161124233117p:plain
おぉ!?
少し良くなりましたね。
変な改行なんかが入っていますが改行文字を改行文字でも読み取ったんでしょうか。
ゴミの部分も無理やり文字化しているようですが、それを除くと数文字誤りがありますがそこそこの精度で読み取れているようです。

【今後の課題】

  • 日本語のコメントはどう見えるの?
  • ソースコードを線形に補正するような画像処理をかます(そんなものはあるんでしょうか?)
  • (きれいに読み込めた暁には)構文解析して強調表示なんか出来たらいいなぁ

読書記録(レガシーコード改善ガイド7章)

どーもpanjaです。
少し前からレガシーコード改善ガイドを読んでます。

レガシーコード改善ガイド

レガシーコード改善ガイド

文章の流れが少しわかりづらい箇所もありますが、普段C++で開発している私にとっては例は理解しやすく内容も文句なしです。

さて、今回は本書の「第7章 いつまで経っても変更作業が終わりません」を読んで思ったことを書いてみたいと思います。

この章では以下が述べられています。

  • どんなに綺麗にメンテナンスされているシステムでもコード量が増えてくると変更すべき場所を見つけるのは大変。
  • レガシーシステムの場合は変更自体も大変。(コーディングはすぐ終わるかもしれないけど、テストがないので既存の振る舞い含め確認に時間がかかる)
  • テストが揃っている環境だとしても、変更に対するフィードバックを素早く(5秒以内!)得る必要がある。
    • そのために必要なことは、システムの全てのクラスやモジュールを独立してテストハーネス(GoogleTestなどのテストフレームワーク)上でインスタンス化出来るようにすること
      • 例えばインターフェースの抽出とかで実現できるけど、具体的な手法は「アジャイルソフトウェア開発の奥義」に書いてあるよ!

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

こんなとこでしょうか。
ちげーよそんなこと書いてねーよ。お前間違ってるよ。
などなどご意見ありましたら是非コメントお願いします。


私は普段boostなどを使って開発しているので、そりゃあもうビルドは時間がかかります。が、そんなこと言ってても始まらないので依存箇所を出来るだけ小さく出来ないかなど考えることは色々ありそうです。
また、クラスの依存関係を調べるツールを使って既存のクラスがいかに単独でインスタンス化出来ないかも調べてみようと思います。C++で使える便利なツールをご存知の方はぜひぜひ教えてください!