Annotation of nono/wx/wxlogsetting.cpp, revision 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.