Annotation of nono/wx/wxbutton.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 "wxbutton.h"
        !            12: #include "wxcolor.h"
        !            13: 
        !            14: // 通知イベント。
        !            15: // このボタンが押された時にイベントが発生する。
        !            16: // 引数は wxCommandEvent だが、イベントタイプは EVT_BUTTON ではなく
        !            17: // NONO_EVT_BUTTON を使用していることが異なる。
        !            18: wxDEFINE_EVENT(NONO_EVT_BUTTON, wxCommandEvent);
        !            19: 
        !            20: // イベント
        !            21: wxBEGIN_EVENT_TABLE(WXButton, inherited)
        !            22:        EVT_MOUSE_EVENTS(WXButton::OnMouse)
        !            23:        EVT_TIMER(wxID_ANY, WXButton::OnTimer)
        !            24: wxEND_EVENT_TABLE()
        !            25: 
        !            26: // コンストラクタ
        !            27: WXButton::WXButton(wxWindow *parent, wxWindowID id,
        !            28:        const wxSize& size, const wxString& text, const wxPoint& position)
        !            29:        : inherited(parent, id, position, size)
        !            30: {
        !            31:        // テキストを SJIS に変換し std::string として保存しておく
        !            32:        wxCSConv conv("SJIS");
        !            33:        sjistext = text.mb_str(conv);
        !            34: 
        !            35:        timer.SetOwner(this);
        !            36: 
        !            37:        FontChanged();
        !            38: }
        !            39: 
        !            40: // デストラクタ
        !            41: WXButton::~WXButton()
        !            42: {
        !            43: }
        !            44: 
        !            45: bool
        !            46: WXButton::Enable(bool enable_)
        !            47: {
        !            48:        // 無効にするとイベントが来なくなるため、
        !            49:        // 押し下げた状態で無効にする場合は押し下げを解放してからにする。
        !            50:        if (enable_ == false && IsPressed()) {
        !            51:                Press(false);
        !            52:        }
        !            53: 
        !            54:        return inherited::Enable(enable_);
        !            55: }
        !            56: 
        !            57: void
        !            58: WXButton::FontChanged()
        !            59: {
        !            60:        inherited::FontChanged();
        !            61: 
        !            62:        const auto& sz = GetClientSize();
        !            63: 
        !            64:        // テキスト描画位置はセンタリング。
        !            65:        // クライアント領域の上下左右 2 ピクセルはボタンの描画領域のため、
        !            66:        // テキストは上下左右 2ピクセルずつを除いた部分。
        !            67:        textsize.x = sjistext.size() * font_width;
        !            68:        textsize.y = font_height;
        !            69:        if (textsize.x > sz.x - 4) {
        !            70:                textsize.x = sz.x - 4;
        !            71:        }
        !            72:        if (textsize.y > sz.y - 4) {
        !            73:                textsize.y = sz.y - 4;
        !            74:        }
        !            75:        textpos.x = (sz.x - textsize.x) / 2;
        !            76:        textpos.y = (sz.y - textsize.y) / 2;
        !            77: 
        !            78:        Fill();
        !            79: }
        !            80: 
        !            81: void
        !            82: WXButton::OnMouse(wxMouseEvent& event)
        !            83: {
        !            84:        if (event.LeftDown() || event.LeftDClick()) {
        !            85:                // ボタンを押して..
        !            86:                Press(true);
        !            87: 
        !            88:                // 押しっぱなし判定のためタイマーを開始。
        !            89:                timer.Start(500);
        !            90:        }
        !            91:        if (event.LeftUp()) {
        !            92:                Press(false);
        !            93:        }
        !            94: }
        !            95: 
        !            96: // タイマーイベント
        !            97: void
        !            98: WXButton::OnTimer(wxTimerEvent& event)
        !            99: {
        !           100:        if (IsPressed()) {
        !           101:                // 左クリックが続いていたらもう一度
        !           102:                Press(true);
        !           103: 
        !           104:                // キーリピートと同じ要領で2回目以降は短くする。
        !           105:                timer.Start(100);
        !           106:        } else {
        !           107:                // 左クリックが終わっていたら終了
        !           108:                timer.Stop();
        !           109:        }
        !           110: }
        !           111: 
        !           112: // ボタンを押したか離したときの処理
        !           113: void
        !           114: WXButton::Press(bool pressed_)
        !           115: {
        !           116:        // 状態が変化すれば再描画
        !           117:        if (pressed != pressed_) {
        !           118:                Refresh();
        !           119:        }
        !           120: 
        !           121:        // 代入
        !           122:        pressed = pressed_;
        !           123: 
        !           124:        // 状態変化に関わらず、今押していればイベント発行
        !           125:        if (IsPressed()) {
        !           126:                wxCommandEvent newev(NONO_EVT_BUTTON, GetId());
        !           127:                newev.SetEventObject(this);
        !           128:                AddPendingEvent(newev);
        !           129:        }
        !           130: }
        !           131: 
        !           132: void
        !           133: WXButton::Draw()
        !           134: {
        !           135:        // サイズ未指定の時など
        !           136:        const wxSize cs = GetClientSize();
        !           137:        if (__predict_false(cs.x < 1 || cs.y < 1)) {
        !           138:                return;
        !           139:        }
        !           140: 
        !           141:        // 文字
        !           142:        Color c = IsEnabled() ? UD_BLACK : UD_GREY;
        !           143:        DrawStringSJIS(c, textpos.x, textpos.y, sjistext.c_str());
        !           144: 
        !           145:        // 枠
        !           146:        int l = 0;
        !           147:        int t = 0;
        !           148:        int r = GetClientSize().x - 1;
        !           149:        int b = GetClientSize().y - 1;
        !           150: 
        !           151:        if (__predict_true(IsPressed() == false)) {
        !           152:                // この場合外寸 7x7、内寸 3x3。
        !           153:                // 空白「 」のところが内側。
        !           154:                // 「・」は背景色で塗りつぶす (オンオフ逆側の陰影があるため)
        !           155:                //
        !           156:                // □□□□□□■ <- (1)
        !           157:                // □・・・・灰■ <- (2)
        !           158:                // □・   灰■
        !           159:                // □・   灰■
        !           160:                // □・   灰■
        !           161:                // □灰灰灰灰灰■ <- (3)
        !           162:                // ■■■■■■■ <- (4)
        !           163:                // ^ ^       ^ ^
        !           164:                //(5)(6)    (7)(8)
        !           165: 
        !           166:                bitmap.DrawLineH(UD_WHITE, l, t, r);                            // (1)
        !           167:                bitmap.DrawLineH(BGPANEL,  l + 1, t + 1, r -1);         // (2)
        !           168:                bitmap.DrawLineH(UD_GREY,  l + 1, b - 1, r);            // (3)
        !           169:                bitmap.DrawLineH(UD_BLACK, l, b, r + 1);                        // (4)
        !           170:                bitmap.DrawLineV(UD_WHITE, l, t + 1, b);                        // (5)
        !           171:                bitmap.DrawLineV(BGPANEL,  l + 1, t + 2, b - 1);        // (6)
        !           172:                bitmap.DrawLineV(UD_GREY,  r - 1, t + 1, b - 1);        // (7)
        !           173:                bitmap.DrawLineV(UD_BLACK, r, t, b);                            // (8)
        !           174:        } else {
        !           175:                // ■■■■■■□ <- (1)
        !           176:                // ■灰灰灰灰灰□ <- (2)
        !           177:                // ■灰   ・□
        !           178:                // ■灰   ・□
        !           179:                // ■灰   ・□
        !           180:                // ■灰・・・・□ <- (3)
        !           181:                // □□□□□□□ <- (4)
        !           182:                // ^ ^       ^ ^
        !           183:                //(5)(6)    (7)(8)
        !           184:                bitmap.DrawLineH(UD_BLACK, l, t, r);                            // (1)
        !           185:                bitmap.DrawLineH(UD_GREY,  l + 1, t + 1, r);            // (2)
        !           186:                bitmap.DrawLineH(BGPANEL,  l + 2, b - 1, r);            // (3)
        !           187:                bitmap.DrawLineH(UD_WHITE, l, b, r + 1);                        // (4)
        !           188:                bitmap.DrawLineV(UD_BLACK, l, t + 1, b);                        // (5)
        !           189:                bitmap.DrawLineV(UD_GREY,  l + 1, t + 1, b);            // (6)
        !           190:                bitmap.DrawLineV(BGPANEL,  r - 1, t + 2, b);            // (7)
        !           191:                bitmap.DrawLineV(UD_WHITE, r, t, b);                            // (8)
        !           192:        }
        !           193: }

unix.superglobalmegacorp.com

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