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

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"
                     12: #include "wxcolor.h"
                     13: #include "wxtextscreen.h"
                     14: #include "mainapp.h"
                     15: #include <algorithm>
                     16: 
                     17: //
                     18: // パネル部分
                     19: //
                     20: 
                     21: // イベントテーブル
                     22: wxBEGIN_EVENT_TABLE(WXLogSettingPanel, inherited)
                     23:        EVT_LEFT_DOWN(WXLogSettingPanel::OnLeftDown)
                     24:        EVT_LEFT_UP(WXLogSettingPanel::OnLeftUp)
                     25: wxEND_EVENT_TABLE()
                     26: 
                     27: // コンストラクタ
                     28: WXLogSettingPanel::WXLogSettingPanel(wxWindow *parent)
                     29:        : inherited(parent)
                     30: {
                     31:        // エイリアスを持つオブジェクトだけ抜き出す
                     32:        for (const auto obj : gMainApp.GetObjects()) {
                     33:                if (obj->GetAliases().empty() == false) {
                     34:                        objs.emplace_back(obj);
                     35:                }
                     36:        }
                     37: 
                     38:        // ログ名でソート。
                     39:        // ただし普通にソートすると "(BusErr)" とかの括弧付きがアルファベット
                     40:        // より上に来てしまうが、ここではこれらは重要ではないので下にしたい。
                     41:        std::sort(objs.begin(), objs.end(), [](Object *a, Object *b) {
                     42:                std::string aname = a->GetName();
                     43:                std::string bname = b->GetName();
                     44:                if (aname[0] == '(') {
                     45:                        aname[0] = '{';
                     46:                }
                     47:                if (bname[0] == '(') {
                     48:                        bname[0] = '{';
                     49:                }
                     50:                return aname < bname;
                     51:        });
                     52: 
                     53:        // 名前の最大長
                     54:        maxnamelen = 0;
                     55:        for (const auto obj : objs) {
                     56:                maxnamelen = std::max(maxnamelen, (int)obj->GetName().length());
                     57:        }
                     58: 
                     59:        FontChanged();
                     60: }
                     61: 
                     62: // デストラクタ
                     63: WXLogSettingPanel::~WXLogSettingPanel()
                     64: {
                     65: }
                     66: 
                     67: // 桁数 col の左端ピクセル座標を返す
                     68: inline int
                     69: WXLogSettingPanel::Col2PX(int col) const
                     70: {
                     71:        return col * GetFontWidth() + Padding;
                     72: }
                     73: 
                     74: // 行数 row の上端ピクセル座標を返す
                     75: inline int
                     76: WXLogSettingPanel::Row2PY(int row) const
                     77: {
                     78:        // 縦はボタン描画の分少し広げてある
                     79:        return row * (GetFontHeight() + 3) + Padding;
                     80: }
                     81: 
                     82: // ピクセル x が含まれる桁を返す。
                     83: // py がパディング領域を指していると(テキストとしての)範囲外の値を返す。
                     84: inline int
                     85: WXLogSettingPanel::PX2Col(int px) const
                     86: {
                     87:        return (px - Padding) / GetFontWidth();
                     88: }
                     89: 
                     90: // ピクセル y が含まれる行を返す。
                     91: // py がパディング領域を指していると(テキストとしての)範囲外の値を返す。
                     92: inline int
                     93: WXLogSettingPanel::PY2Row(int py) const
                     94: {
                     95:        return (py - Padding) / (GetFontHeight() + 3);
                     96: }
                     97: 
                     98: // フォントサイズ変更
                     99: void
                    100: WXLogSettingPanel::FontChanged()
                    101: {
                    102:        inherited::FontChanged();
                    103: 
                    104:        // 行数×桁数を基本とする
                    105:        int col = maxnamelen + 10;
                    106:        int row = objs.size() + 1;
                    107: 
                    108:        int width  = Col2PX(col) + Padding;
                    109:        int height = Row2PY(row) + Padding;
                    110:        SetClientSize(width, height);
                    111:        SetMinClientSize(wxSize(width, height));
                    112: }
                    113: 
                    114: // ボタンのようなものを描画する。rect は外寸。
                    115: void
                    116: WXLogSettingPanel::DrawButton(const Rect& rect, bool button_pressed)
                    117: {
                    118:        int l = rect.x;
                    119:        int t = rect.y;
                    120:        int r = rect.GetRight();
                    121:        int b = rect.GetBottom();
                    122: 
                    123:        if (__predict_true(button_pressed == false)) {
                    124:                // この場合外寸 7x7、内寸 3x3。
                    125:                // 空白「 」のところが内側。
                    126:                // 「・」は背景色で塗りつぶす (オンオフ逆側の陰影があるため)
                    127:                //
                    128:                // □□□□□□■ <- (1)
                    129:                // □・・・・灰■ <- (2)
                    130:                // □・   灰■
                    131:                // □・   灰■
                    132:                // □・   灰■
                    133:                // □灰灰灰灰灰■ <- (3)
                    134:                // ■■■■■■■ <- (4)
                    135:                // ^ ^       ^ ^
                    136:                //(5)(6)    (7)(8)
                    137: 
                    138:                bitmap.DrawLineH(UD_WHITE, l, t, r);                            // (1)
                    139:                bitmap.DrawLineH(BGPANEL,  l + 1, t + 1, r -1);         // (2)
                    140:                bitmap.DrawLineH(UD_GREY,  l + 1, b - 1, r);            // (3)
                    141:                bitmap.DrawLineH(UD_BLACK, l, b, r + 1);                        // (4)
                    142:                bitmap.DrawLineV(UD_WHITE, l, t + 1, b);                        // (5)
                    143:                bitmap.DrawLineV(BGPANEL,  l + 1, t + 2, b - 1);        // (6)
                    144:                bitmap.DrawLineV(UD_GREY,  r - 1, t + 1, b - 1);        // (7)
                    145:                bitmap.DrawLineV(UD_BLACK, r, t, b);                            // (8)
                    146:        } else {
                    147:                // ■■■■■■□ <- (1)
                    148:                // ■灰灰灰灰灰□ <- (2)
                    149:                // ■灰   ・□
                    150:                // ■灰   ・□
                    151:                // ■灰   ・□
                    152:                // ■灰・・・・□ <- (3)
                    153:                // □□□□□□□ <- (4)
                    154:                // ^ ^       ^ ^
                    155:                //(5)(6)    (7)(8)
                    156:                bitmap.DrawLineH(UD_BLACK, l, t, r);                            // (1)
                    157:                bitmap.DrawLineH(UD_GREY,  l + 1, t + 1, r);            // (2)
                    158:                bitmap.DrawLineH(BGPANEL,  l + 2, b - 1, r);            // (3)
                    159:                bitmap.DrawLineH(UD_WHITE, l, b, r + 1);                        // (4)
                    160:                bitmap.DrawLineV(UD_BLACK, l, t + 1, b);                        // (5)
                    161:                bitmap.DrawLineV(UD_GREY,  l + 1, t + 1, b);            // (6)
                    162:                bitmap.DrawLineV(BGPANEL,  r - 1, t + 2, b);            // (7)
                    163:                bitmap.DrawLineV(UD_WHITE, r, t, b);                            // (8)
                    164:        }
                    165: }
                    166: 
                    167: // 描画本体
                    168: void
                    169: WXLogSettingPanel::Draw()
                    170: {
                    171:        const int width  = GetFontWidth();
                    172:        const int height = GetFontHeight();
                    173:        int row;
                    174:        int y;
                    175: 
                    176:        // ヘッダ
                    177:        y = Row2PY(0);
                    178:        DrawStringSJIS(Col2PX(0), y, "Name");
                    179:        DrawStringSJIS(Col2PX(maxnamelen + 1), y, "LogLevel");
                    180: 
                    181:        row = 1;
                    182:        for (const auto obj : objs) {
                    183:                Rect rect;
                    184:                Color c;
                    185: 
                    186:                y = Row2PY(row);
                    187: 
                    188:                DrawStringSJIS(Col2PX(0), y, obj->GetName().c_str());
                    189: 
                    190:                // 左ボタン (領域はテキスト2文字分)
                    191:                int x = Col2PX(maxnamelen + 1);
                    192:                if (obj->loglevel < 0) {
                    193:                        c = UD_GREY;
                    194:                } else {
                    195:                        c = GetTextForeColor();
                    196:                }
                    197:                DrawStringSJIS(c, x + (width / 2), y, "<");
                    198:                rect = Rect(x, y - 1, width * 2 + 2, height + 2);
                    199:                DrawButton(rect, (row == -pressed));
                    200: 
                    201:                // 値
                    202:                char lvstr[2];
                    203:                if (__predict_false(obj->loglevel < 0)) {
                    204:                        lvstr[0] = '-';
                    205:                } else if (__predict_true(obj->loglevel < 10)) {
                    206:                        lvstr[0] = obj->loglevel + '0';
                    207:                } else {
                    208:                        lvstr[0] = '?';
                    209:                }
                    210:                lvstr[1] = '\0';
                    211:                DrawStringSJIS(Col2PX(maxnamelen + 5), y, lvstr);
                    212: 
                    213:                // 値の枠
                    214:                x = Col2PX(maxnamelen + 4);
                    215:                rect = Rect(x, y - 1, width * 3, height + 1);
                    216:                int l = rect.x;
                    217:                int t = rect.y;
                    218:                int r = rect.GetRight();
                    219:                int b = rect.GetBottom();
                    220:                bitmap.DrawLineH(UD_GREY,  l, t, r);
                    221:                bitmap.DrawLineH(UD_WHITE, l, b, r + 1);
                    222:                bitmap.DrawLineV(UD_GREY,  l, t + 1, b);
                    223:                bitmap.DrawLineV(UD_WHITE, r, t, b);
                    224: 
                    225:                // 右ボタン
                    226:                x = Col2PX(maxnamelen + 8);
                    227:                if (obj->loglevel >= 9) {
                    228:                        c = UD_GREY;
                    229:                } else {
                    230:                        c = GetTextForeColor();
                    231:                }
                    232:                DrawStringSJIS(c, x + (width / 2), y, ">");
                    233:                rect = Rect(x, y - 1, width * 2 + 2, height + 2);
                    234:                DrawButton(rect, (row == pressed));
                    235: 
                    236:                row++;
                    237:        }
                    238: }
                    239: 
                    240: // 左クリック (Down) イベント
                    241: void
                    242: WXLogSettingPanel::OnLeftDown(wxMouseEvent& event)
                    243: {
                    244:        const wxPoint& pos = event.GetPosition();
                    245:        int x = PX2Col(pos.x);
                    246:        int y = PY2Row(pos.y);
                    247: 
                    248:        // 上下のパディング領域とヘッダ行を先に除いておく
                    249:        // (左右は影響しないので放置でいい)
                    250:        if (y < 1 || y >= objs.size()) {
                    251:                return;
                    252:        }
                    253: 
                    254:        Object *obj = objs[y - 1];
                    255:        int level = obj->loglevel;
                    256: 
                    257:        // クリックされた場所がボタンの位置か
                    258:        if (maxnamelen + 1 <= x && x <= maxnamelen + 2) {
                    259:                if (level > -1) {
                    260:                        level--;
                    261:                }
                    262:                // "<" ボタンは負数で覚えておく (0 はないので大丈夫)
                    263:                pressed = -y;
                    264:        } else if (maxnamelen + 8 <= x) {
                    265:                // 今の所上限は未定だけど、表示上の都合で一桁にしておくか
                    266:                if (level < 9) {
                    267:                        level++;
                    268:                }
                    269:                // ">" ボタンは正数で覚えておく
                    270:                pressed = y;
                    271:        }
                    272: 
                    273:        if (level != obj->loglevel) {
                    274:                obj->SetLogLevel(level);
                    275:        }
                    276: 
                    277:        Refresh();
                    278: }
                    279: 
                    280: // 左クリック (Up) イベント
                    281: void
                    282: WXLogSettingPanel::OnLeftUp(wxMouseEvent& event)
                    283: {
                    284:        // クリックを上げた場所は問わない
                    285:        pressed = 0;
                    286:        Refresh();
                    287: }
                    288: 
                    289: 
                    290: //
                    291: // ウィンドウ
                    292: //
                    293: 
                    294: // コンストラクタ
                    295: WXLogSettingWindow::WXLogSettingWindow(wxWindow *parent)
                    296:        : inherited(parent, wxID_ANY, _("Log Level Setting"))
                    297: {
                    298:        panel = new WXLogSettingPanel(this);
                    299: 
                    300:        DoSize();
                    301: }
                    302: 
                    303: // デストラクタ
                    304: WXLogSettingWindow::~WXLogSettingWindow()
                    305: {
                    306: }

unix.superglobalmegacorp.com

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