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

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