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