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

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

unix.superglobalmegacorp.com

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