|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // 独自ボタン
9: //
10:
11: #include "wxbutton.h"
12: #include "wxcolor.h"
13:
14: // 通知イベント。
15: // このボタンが押された時にイベントが発生する。
16: // 引数は wxCommandEvent だが、イベントタイプは EVT_BUTTON ではなく
17: // NONO_EVT_BUTTON を使用していることが異なる。
18: wxDEFINE_EVENT(NONO_EVT_BUTTON, wxCommandEvent);
19:
20: // イベント
21: wxBEGIN_EVENT_TABLE(WXButton, inherited)
22: EVT_MOUSE_EVENTS(WXButton::OnMouse)
23: EVT_TIMER(wxID_ANY, WXButton::OnTimer)
24: wxEND_EVENT_TABLE()
25:
26: // コンストラクタ
27: WXButton::WXButton(wxWindow *parent, wxWindowID id,
28: const wxSize& size, const wxString& text, const wxPoint& position)
29: : inherited(parent, id, position, size)
30: {
31: // テキストを SJIS に変換し std::string として保存しておく
32: wxCSConv conv("SJIS");
33: sjistext = text.mb_str(conv);
34:
35: timer.SetOwner(this);
36:
37: FontChanged();
38: }
39:
40: // デストラクタ
41: WXButton::~WXButton()
42: {
43: }
44:
45: bool
46: WXButton::Enable(bool enable_)
47: {
48: // 無効にするとイベントが来なくなるため、
49: // 押し下げた状態で無効にする場合は押し下げを解放してからにする。
50: if (enable_ == false && IsPressed()) {
51: Press(false);
52: }
53:
54: return inherited::Enable(enable_);
55: }
56:
57: void
58: WXButton::FontChanged()
59: {
60: inherited::FontChanged();
61:
62: const auto& sz = GetClientSize();
63:
64: // テキスト描画位置はセンタリング。
65: // クライアント領域の上下左右 2 ピクセルはボタンの描画領域のため、
66: // テキストは上下左右 2ピクセルずつを除いた部分。
67: textsize.x = sjistext.size() * font_width;
68: textsize.y = font_height;
69: if (textsize.x > sz.x - 4) {
70: textsize.x = sz.x - 4;
71: }
72: if (textsize.y > sz.y - 4) {
73: textsize.y = sz.y - 4;
74: }
75: textpos.x = (sz.x - textsize.x) / 2;
76: textpos.y = (sz.y - textsize.y) / 2;
77:
78: Fill();
79: }
80:
81: void
82: WXButton::OnMouse(wxMouseEvent& event)
83: {
84: if (event.LeftDown() || event.LeftDClick()) {
85: // ボタンを押して..
86: Press(true);
87:
88: // 押しっぱなし判定のためタイマーを開始。
89: timer.Start(500);
90: }
91: if (event.LeftUp()) {
92: Press(false);
93: }
94: }
95:
96: // タイマーイベント
97: void
98: WXButton::OnTimer(wxTimerEvent& event)
99: {
100: if (IsPressed()) {
101: // 左クリックが続いていたらもう一度
102: Press(true);
103:
104: // キーリピートと同じ要領で2回目以降は短くする。
105: timer.Start(100);
106: } else {
107: // 左クリックが終わっていたら終了
108: timer.Stop();
109: }
110: }
111:
112: // ボタンを押したか離したときの処理
113: void
114: WXButton::Press(bool pressed_)
115: {
116: // 状態が変化すれば再描画
117: if (pressed != pressed_) {
118: Refresh();
119: }
120:
121: // 代入
122: pressed = pressed_;
123:
124: // 状態変化に関わらず、今押していればイベント発行
125: if (IsPressed()) {
126: wxCommandEvent newev(NONO_EVT_BUTTON, GetId());
127: newev.SetEventObject(this);
128: AddPendingEvent(newev);
129: }
130: }
131:
132: void
133: WXButton::Draw()
134: {
135: // サイズ未指定の時など
136: const wxSize cs = GetClientSize();
137: if (__predict_false(cs.x < 1 || cs.y < 1)) {
138: return;
139: }
140:
141: // 文字
142: Color c = IsEnabled() ? UD_BLACK : UD_GREY;
143: DrawStringSJIS(c, textpos.x, textpos.y, sjistext.c_str());
144:
145: // 枠
146: int l = 0;
147: int t = 0;
148: int r = GetClientSize().x - 1;
149: int b = GetClientSize().y - 1;
150:
151: if (__predict_true(IsPressed() == false)) {
152: // この場合外寸 7x7、内寸 3x3。
153: // 空白「 」のところが内側。
154: // 「・」は背景色で塗りつぶす (オンオフ逆側の陰影があるため)
155: //
156: // □□□□□□■ <- (1)
157: // □・・・・灰■ <- (2)
158: // □・ 灰■
159: // □・ 灰■
160: // □・ 灰■
161: // □灰灰灰灰灰■ <- (3)
162: // ■■■■■■■ <- (4)
163: // ^ ^ ^ ^
164: //(5)(6) (7)(8)
165:
166: bitmap.DrawLineH(UD_WHITE, l, t, r); // (1)
167: bitmap.DrawLineH(BGPANEL, l + 1, t + 1, r -1); // (2)
168: bitmap.DrawLineH(UD_GREY, l + 1, b - 1, r); // (3)
169: bitmap.DrawLineH(UD_BLACK, l, b, r + 1); // (4)
170: bitmap.DrawLineV(UD_WHITE, l, t + 1, b); // (5)
171: bitmap.DrawLineV(BGPANEL, l + 1, t + 2, b - 1); // (6)
172: bitmap.DrawLineV(UD_GREY, r - 1, t + 1, b - 1); // (7)
173: bitmap.DrawLineV(UD_BLACK, r, t, b); // (8)
174: } else {
175: // ■■■■■■□ <- (1)
176: // ■灰灰灰灰灰□ <- (2)
177: // ■灰 ・□
178: // ■灰 ・□
179: // ■灰 ・□
180: // ■灰・・・・□ <- (3)
181: // □□□□□□□ <- (4)
182: // ^ ^ ^ ^
183: //(5)(6) (7)(8)
184: bitmap.DrawLineH(UD_BLACK, l, t, r); // (1)
185: bitmap.DrawLineH(UD_GREY, l + 1, t + 1, r); // (2)
186: bitmap.DrawLineH(BGPANEL, l + 2, b - 1, r); // (3)
187: bitmap.DrawLineH(UD_WHITE, l, b, r + 1); // (4)
188: bitmap.DrawLineV(UD_BLACK, l, t + 1, b); // (5)
189: bitmap.DrawLineV(UD_GREY, l + 1, t + 1, b); // (6)
190: bitmap.DrawLineV(BGPANEL, r - 1, t + 2, b); // (7)
191: bitmap.DrawLineV(UD_WHITE, r, t, b); // (8)
192: }
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.