New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
アクティブタブの上部にトップバンドを描画する #1684
アクティブタブの上部にトップバンドを描画する #1684
Conversation
|
✅ Build sakura 1.0.3804 completed (commit 7c1f08ebbe by @suconbu) |
|
トップバンドの色をタイトルバーとお揃いにしてみました。
タイトルバーの色 (アクセントカラー) の取得に使用する |
19fe079
to
97bfeae
Compare
|
✅ Build sakura 1.0.3805 completed (commit d84d6b879a by @suconbu) |
|
✅ Build sakura 1.0.3806 completed (commit 8422e4b052 by @suconbu) |
|
✅ Build sakura 1.0.3807 completed (commit 5d8301bff0 by @suconbu) |
* トップバンドの横幅がタブに対してすこし狭く見えるのを調整する * 表示スケールが100%より大きい時にトップバンドの上に隙間が空かないようにする * 左側はみだし判定が冗長なので廃止する
97bfeae
to
07e6167
Compare
|
✅ Build sakura 1.0.3808 completed (commit 369349c232 by @suconbu) |
|
MinGWビルドでエラーが出ています。 たぶん、Makefileにインポートライブラリを追加してないことが原因です。 この辺にDwmapi.libを追加してやれば解消するはず。 Lines 92 to 93 in 5135813
|
|
あ、👆はunittestsのMakefileにも必要だと思います。 |
sakura_core/window/CTabWnd.cpp
Outdated
| @param[in] lprcClient タブウィンドウのクライアント領域 | ||
| @param[in] nTabIndex 対象タブのインデックス | ||
| */ | ||
| void CTabWnd::DrawTopBand( const CGraphics& gr, const RECT* prcClient, int nTabIndex ) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これは知らなくて今回 SonarCloud の指摘で気付いたのですが、(他の関数にならい) const LPRECT hoge とした場合は hoge の参照先 (hoge->left など) は書き込み可能となってしまうようでした。
RECT rect = {};
const RECT* pRect = ▭
const LPRECT lpRect = ▭
pRect = ▭ // OK
pRect->left = 1; // コンパイルエラー
lpRect = ▭ // コンパイルエラー
lpRect->left = 1; // OK (予想外)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const RECT *
RECT const *
の違いですかね・・・
const RECT&
とすれば、おかしなことは起きないですが、参照渡しを嫌がる人は結構いるらしいです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
出力引数が参照渡しとなっていると、呼び出し側のコードを見た時に出力ということが分かりづらい、出力不要 (NULL) を表現できない、というのはあると思いますけど、今回のような必須の入力引数であれば参照の方が良さそうです。
第一引数と同じく RECT も参照渡しに変更しておこうと思います。
|
✅ Build sakura 1.0.3811 completed (commit 7aa40f3ef0 by @suconbu) |
ありがとうございます。 |
|
CTabWnd::DrawTopBand の定義を置く位置がちょっとおかしいので直させて下さい。 |
478f458
to
54a79bd
Compare
|
Kudos, SonarCloud Quality Gate passed! |
トップバンドの描画処理 (DrawTopBand) 追加により CTabWnd::OnPaint の処理時間が 0.15 ms ほど増加しましたが、操作性への影響はないものと判断します。 変更前:
変更後:
DrawTopBand の内訳を見ると、GetSystemAccentColor (アクセントカラー取得) が半分程度 (0.135 ms 中の 0.065 ms) を占めていました。 変更後 (DrawTopBand 内訳):
|
|
✅ Build sakura 1.0.3813 completed (commit 0747cf7977 by @suconbu) |
|
✅ Build sakura 1.0.3814 completed (commit 0a600a9b18 by @suconbu) |
|
✅ Build sakura 1.0.3815 completed (commit 366aac0fdb by @suconbu) |
| bool bResult = FALSE; | ||
| if( SUCCEEDED( ::DwmGetColorizationColor( &dwArgb, &bOpaque ) ) ){ | ||
| if( pColorOut != nullptr ){ | ||
| *pColorOut = RGB( (dwArgb >> 16) & 0xFFU, (dwArgb >> 8) & 0xFFU, dwArgb & 0xFFU ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 0xAARRGGBB to 0x00BBGGRR(COLORREF)
*pColorOut = ((dwArgb & 0xFF0000U) >> 16) | (dwArgb & 0xFF00U) | ((dwArgb & 0xFFU) << 16);このように書くと少し命令数が少なくなる事を確認しました。
処理時間の確認はしていませんが、DwmGetColorizationColor の呼び出しの時間が支配的なので変化無いと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
やりたいことがソレ(BGRA→RGBの変換)なら、そう書けばいいように思いました。
数式をインラインで書くと、コピペして変数名を修正するときにミスることあります。
C言語のマクロ関数ならば、変数名が変わっても大丈夫です。
C++のconstexpr関数ならば、普通の関数みたいに処理を書いてインライン化できます。
//! 0xAARRGGBB to 0x00BBGGRR
constexpr COLORREF ConvertBgraToRgb(DWORD bgra)
{
COLORREF rgb = bgra & 0x0000FF00;
rgb |= (bgra & 0x000000FF) << 16;
rgb |= (bgra & 0x00FF0000) >> 16;
return rgb;
//※beruさんが書いたのと同じ意味のコードのつもりっす。
}この試みに関して思ったことが2つあります。
・いまやらないといかんの?(≒指摘事項なの?)
・どこに書くの?(≒関数が属する適切なヘッダファイルはどれ?)
総合的に考えて、PR指摘としてはスルーでいいんじゃないかな・・・。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requested change ではないのでもちろん対応は不要です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 0xAARRGGBB to 0x00BBGGRR(COLORREF) *pColorOut = ((dwArgb & 0xFF0000U) >> 16) | (dwArgb & 0xFF00U) | ((dwArgb & 0xFFU) << 16);
代入文100万回実行時の合計処理時間で比較してみました所、RGB マクロの 1.5 ms (1.5ns/回) 程度から 1.2 ms (1.2ns/回) 程度へと 20% も高速化していました。
処理時間 0.15 ms なら、単体では影響なしと言ってよいと思います。 現代のゲーマースペックPCは、240fps出せるものがあるようですが、 実は、アクティブタブの決定処理はかなり非効率であると考えられるので、 測定した処理時間を見る限りでは、なんかあってもこのPRのせいじゃねぇ!と判断するのは妥当であるように思います。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTMです。
目視動作確認はできないためapproveにはしませんが、
コードは問題なさそうに見えます。
| BOOL bOpaque = FALSE; | ||
| bool bResult = FALSE; | ||
| if( SUCCEEDED( ::DwmGetColorizationColor( &dwArgb, &bOpaque ) ) ){ | ||
| if( pColorOut != nullptr ){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
指摘じゃないっすけども、out引数に出力可能でない場合にシステムコールするのは無駄なので、NULLチェックはもう少し早いほうがいいと思います。
あと、CErrorInfoの仕組みを活用すれば HRESULT 値から「例外」を生成できるので、戻り値は bool じゃなくても良い(=COLORREFを返したら良い)ような気もします。
たぶん、周りの作りに合わせて書いていくと「アクセントカラーの取得」が失敗したときに適切に異常終了させるようにコードを書くよりも、失敗した時に使う値を決めてベタ書きしておいて、呼出元で失敗を考慮する必要がないように設計していくのが良さそうに思います。
繰り返しますが指摘じゃないっす。地味にレベル高い要求してる自覚はありますので 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
指摘じゃないっすけども、out引数に出力可能でない場合にシステムコールするのは無駄なので、NULLチェックはもう少し早いほうがいいと思います。
ここは呼び元でもし出力値が不要な (取得成否のみが欲しい) 場合には nullptr を指定してもらう、という意図であえてこのようにしてしまいました。
アクセントカラーの取得成否だけが必要、というケースはほぼないとは思いますけど😅
取得できなかった時にどんな色にしないかは、多分ですが呼び出し元の処理により様々だと思いますで、今回のように正常/異常を区別できるようにする、あるいは GetProfileInt の nDefault のように取得失敗時の既定値を呼び出し元から受け取る、というのが良いのかもしれません。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
問題無いと思います。
|
レビューありがとうございました。マージします。 |
|
本 PR の対応にあたって現状のタブバーの処理を調査する中で、 |
|
多段タブバーが有効時にズレないようにする対応を楽しみに待ってます😆 |



PR の目的
アクティブなタブの上部に目印 (トップバンド) を表示することで、多数のタブの中からでもすぐに発見できるようにします。
カテゴリ
PR の背景
アクティブタブは他のタブよりも少し明るく/少し大きく表示されてはいますが、多数のタブが表示されている状況ではよく目を凝らさないと発見できません。長時間の作業で疲れた目には応えます。
※ ODSN のフォーラムにも関連しそうな要望がありました。
https://osdn.net/projects/sakura-editor/forums/34071/44160/
PR のメリット
目的に記載の通りです。
PR のデメリット (トレードオフとかあれば)
描画物が増えるので操作レスポンスが悪化する可能性があります。
仕様・動作説明
トップバンドの描画処理は 2006 年頃から存在していたようなのですが、条件判定により「クラシック表示以外」の場合には描画がされないようになっています。
sakura/sakura_core/window/CTabWnd.cpp
Lines 1607 to 1609 in 5135813
WindowsXP の標準タブコントロールではアクティブタブに自動的に色が付くので、クラシック表示以外ではトップバンドの描画は不要だったと考えられますが、WindowsVista 以降の標準タブコントロールはこの色付けはなくなり、さらにフラットな意匠になっているためトップバンドなしではアクティブタブを見つけづらくなっています。
本 PR ではこの条件を見直してトップバンドが常時描画されるように変更します。
PR の影響範囲
タブバーの表示内容・性能への影響があります。
テスト内容
トップバンドが正しく表示されることと、性能劣化がないことを確認する予定です。
関連 issue, PR
参考資料