|
|
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 "wxlogsetting.h"
1.1.1.2 root 12: #include "wxbutton.h"
1.1 root 13: #include "wxcolor.h"
14: #include "wxtextscreen.h"
15: #include "mainapp.h"
16: #include <algorithm>
17:
18: //
19: // パネル部分
20: //
21:
1.1.1.2 root 22: enum {
23: ID_BUTTON0 = IDGROUP_LOGSETTING,
1.1.1.3 root 24: ID_local_end = ID_BUTTON0 + 100 * 2, // 適当
1.1.1.2 root 25: };
26: static_assert(ID_local_end - 1 <= (int)IDGROUP_LOGSETTING_END, "ID exceeded");
1.1 root 27:
28: // コンストラクタ
29: WXLogSettingPanel::WXLogSettingPanel(wxWindow *parent)
30: : inherited(parent)
31: {
1.1.1.4 root 32: SetName("LogSettingPanel");
33:
1.1 root 34: // エイリアスを持つオブジェクトだけ抜き出す
35: for (const auto obj : gMainApp.GetObjects()) {
1.1.1.5 ! root 36: if (obj->GetAliases().empty() == false) {
1.1 root 37: objs.emplace_back(obj);
38: }
39: }
40:
41: // ログ名でソート。
42: // ただし普通にソートすると "(BusErr)" とかの括弧付きがアルファベット
43: // より上に来てしまうが、ここではこれらは重要ではないので下にしたい。
44: std::sort(objs.begin(), objs.end(), [](Object *a, Object *b) {
45: std::string aname = a->GetName();
46: std::string bname = b->GetName();
47: if (aname[0] == '(') {
48: aname[0] = '{';
49: }
50: if (bname[0] == '(') {
51: bname[0] = '{';
52: }
53: return aname < bname;
54: });
55:
56: // 名前の最大長
57: maxnamelen = 0;
58: for (const auto obj : objs) {
59: maxnamelen = std::max(maxnamelen, (int)obj->GetName().length());
60: }
61:
1.1.1.2 root 62: // ボタンを用意
63: int nbuttons = objs.size() * 2;
64: assertmsg(ID_BUTTON0 + nbuttons < ID_local_end, "nbuttons=%d", nbuttons);
65: for (int i = 0; i < nbuttons; i++) {
66: auto btn = new WXButton(this, ID_BUTTON0 + i, wxDefaultSize,
67: (i % 2 == 0 ? "<" : ">"));
68: buttons.push_back(btn);
69:
70: // イベントを接続
71: btn->Connect(NONO_EVT_BUTTON,
72: wxCommandEventHandler(WXLogSettingPanel::OnButton), NULL, this);
73: }
74:
75: // Sizer 使わず自前でレイアウトする。
76: SetAutoLayout(true);
1.1 root 77: FontChanged();
78: }
79:
80: // デストラクタ
81: WXLogSettingPanel::~WXLogSettingPanel()
82: {
83: }
84:
85: // 桁数 col の左端ピクセル座標を返す
86: inline int
87: WXLogSettingPanel::Col2PX(int col) const
88: {
89: return col * GetFontWidth() + Padding;
90: }
91:
92: // 行数 row の上端ピクセル座標を返す
93: inline int
94: WXLogSettingPanel::Row2PY(int row) const
95: {
96: // 縦はボタン描画の分少し広げてある
1.1.1.2 root 97: return row * (GetFontHeight() + 4) + Padding;
1.1 root 98: }
99:
1.1.1.4 root 100: // フォントサイズ変更
101: void
102: WXLogSettingPanel::FontChanged()
1.1 root 103: {
1.1.1.4 root 104: inherited::FontChanged();
105:
106: // 子コントロールに伝搬。
107: for (auto *btn : buttons) {
108: btn->FontChanged();
1.1.1.2 root 109: }
1.1 root 110:
1.1.1.4 root 111: Fit();
112: }
113:
114: void
115: WXLogSettingPanel::Fit()
116: {
117: // 行数×桁数を基本とする
118: int col = maxnamelen + 10;
119: int row = objs.size() + 1;
120: wxSize size(Col2PX(col) + Padding, Row2PY(row) + Padding);
121:
122: // バックバッファのサイズを固定。
123: SetMinBitmapSize(size);
124:
125: SetSize(size);
126: }
1.1.1.2 root 127:
1.1.1.4 root 128: bool
129: WXLogSettingPanel::Layout()
130: {
131: // ボタンを再配置。
132: wxSize btnsize(GetFontWidth() * 2 + 4, GetFontHeight() + 4);
1.1.1.2 root 133: for (int i = 0, end = buttons.size(); i < end; i++) {
134: int x;
135: if (i % 2 == 0) {
136: x = Col2PX(maxnamelen + 1) + 2;
137: } else {
138: x = Col2PX(maxnamelen + 8) - 2;
139: }
140: int y = Row2PY((i / 2) + 1);
1.1.1.4 root 141: buttons[i]->SetSize(x - 2, y - 2, btnsize.x, btnsize.y);
1.1.1.2 root 142: }
143:
144: return true;
1.1 root 145: }
146:
147: // 描画本体
148: void
149: WXLogSettingPanel::Draw()
150: {
151: const int width = GetFontWidth();
152: const int height = GetFontHeight();
153: int row;
154: int y;
155:
156: // ヘッダ
157: y = Row2PY(0);
158: DrawStringSJIS(Col2PX(0), y, "Name");
159: DrawStringSJIS(Col2PX(maxnamelen + 1), y, "LogLevel");
160:
161: row = 1;
162: for (const auto obj : objs) {
163: Rect rect;
164: Color c;
165:
166: y = Row2PY(row);
167:
1.1.1.2 root 168: // 名前
1.1 root 169: DrawStringSJIS(Col2PX(0), y, obj->GetName().c_str());
170:
171: // 値
172: char lvstr[2];
173: if (__predict_false(obj->loglevel < 0)) {
174: lvstr[0] = '-';
175: } else if (__predict_true(obj->loglevel < 10)) {
176: lvstr[0] = obj->loglevel + '0';
177: } else {
178: lvstr[0] = '?';
179: }
180: lvstr[1] = '\0';
181: DrawStringSJIS(Col2PX(maxnamelen + 5), y, lvstr);
182:
183: // 値の枠
1.1.1.2 root 184: int x = Col2PX(maxnamelen + 4);
1.1 root 185: rect = Rect(x, y - 1, width * 3, height + 1);
186: int l = rect.x;
187: int t = rect.y;
188: int r = rect.GetRight();
189: int b = rect.GetBottom();
190: bitmap.DrawLineH(UD_GREY, l, t, r);
191: bitmap.DrawLineH(UD_WHITE, l, b, r + 1);
192: bitmap.DrawLineV(UD_GREY, l, t + 1, b);
193: bitmap.DrawLineV(UD_WHITE, r, t, b);
194:
1.1.1.2 root 195: // ボタンは Layout() で配置してある
1.1 root 196:
197: row++;
198: }
199: }
200:
201: void
1.1.1.2 root 202: WXLogSettingPanel::OnButton(wxCommandEvent& event)
1.1 root 203: {
1.1.1.2 root 204: int n = event.GetId() - ID_BUTTON0; // ボタン番号
205: int idx = n / 2; // オブジェクト番号
206: bool isdown = (n % 2 == 0); // "<" なら true
1.1 root 207:
1.1.1.2 root 208: Object *obj = objs[idx];
1.1 root 209: int level = obj->loglevel;
210:
1.1.1.2 root 211: if (isdown) {
1.1 root 212: if (level > -1) {
213: level--;
214: }
1.1.1.2 root 215: } else {
1.1 root 216: // 今の所上限は未定だけど、表示上の都合で一桁にしておくか
217: if (level < 9) {
218: level++;
219: }
220: }
221:
222: if (level != obj->loglevel) {
223: obj->SetLogLevel(level);
224:
1.1.1.2 root 225: // レベルが上下端ならボタンを無効に、そうでなければ有効にする
226: int down;
227: int up;
228: if (isdown) {
229: down = n;
230: up = n + 1;
231: } else {
232: down = n - 1;
233: up = n;
234: }
235: buttons[down]->Enable((level > -1));
236: buttons[up]->Enable((level < 9));
1.1 root 237:
1.1.1.2 root 238: Refresh();
239: }
1.1 root 240: }
241:
242:
243: //
244: // ウィンドウ
245: //
246:
247: // コンストラクタ
248: WXLogSettingWindow::WXLogSettingWindow(wxWindow *parent)
249: : inherited(parent, wxID_ANY, _("Log Level Setting"))
250: {
1.1.1.4 root 251: new WXLogSettingPanel(this);
252: Fit();
1.1 root 253: }
254:
255: // デストラクタ
256: WXLogSettingWindow::~WXLogSettingWindow()
257: {
258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.