Annotation of nono/wx/wxlogsetting.cpp, revision 1.1.1.5

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.