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

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

unix.superglobalmegacorp.com

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