Annotation of nono/wx/wxmonitor.cpp, revision 1.1.1.13

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: //
1.1.1.7   root        8: // モニター
1.1       root        9: //
                     10: 
1.1.1.6   root       11: #include "wxmonitor.h"
1.1.1.7   root       12: #include "wxmainframe.h"
1.1.1.9   root       13: #include "monitor.h"
1.1.1.7   root       14: 
1.1.1.10  root       15: //#define WINDOW_DEBUG 1
                     16: 
                     17: #if defined(WINDOW_DEBUG)
                     18: #define DPRINTF(fmt...) printf(fmt)
                     19: #else
                     20: #define DPRINTF(fmt...) /**/
                     21: #endif
                     22: 
1.1.1.7   root       23: //
                     24: // モニターパネル
                     25: //
                     26: 
                     27: // イベントテーブル
                     28: wxBEGIN_EVENT_TABLE(WXMonitorPanel, inherited)
                     29:        EVT_TIMER(wxID_ANY, WXMonitorPanel::OnTimer)
                     30: wxEND_EVENT_TABLE()
                     31: 
                     32: // コンストラクタ
1.1.1.9   root       33: WXMonitorPanel::WXMonitorPanel(wxWindow *parent, Monitor *monitor_)
                     34:        : inherited(parent, monitor_->GetSize())
1.1.1.7   root       35:        , monitor(monitor_)
                     36: {
                     37:        timer.SetOwner(this);
                     38: 
                     39:        // 現在の設定値を適用
1.1.1.8   root       40:        auto mainframe = dynamic_cast<WXMainFrame*>(GetParent()->GetParent());
                     41:        SetRate(mainframe->GetMonitorRate());
1.1.1.7   root       42: 
1.1.1.13! root       43:        // 今の所パディングは変わらない。
        !            44:        monitor->SetPadding(WXTextScreen::DefaultPadding);
        !            45:        FontChanged();
        !            46: 
1.1.1.7   root       47:        // 最初に一回描画を起こす
                     48:        wxTimerEvent dummy(timer);
                     49:        AddPendingEvent(dummy);
                     50: }
                     51: 
                     52: // デストラクタ
                     53: WXMonitorPanel::~WXMonitorPanel()
                     54: {
                     55: }
                     56: 
1.1.1.13! root       57: // フォントサイズ変更
        !            58: void
        !            59: WXMonitorPanel::FontChanged()
        !            60: {
        !            61:        inherited::FontChanged();
        !            62: 
        !            63:        monitor->SetFontSize(font_width, font_height);
        !            64: }
        !            65: 
1.1.1.7   root       66: // タイマーイベント
                     67: void
                     68: WXMonitorPanel::OnTimer(wxTimerEvent& event)
                     69: {
                     70:        DoRefresh();
                     71: }
                     72: 
                     73: // 画面を更新して再描画する。
                     74: //
                     75: // 通常はタイマーイベントにより更新間隔ごとに呼ばれるが、
                     76: // ユーザ操作により画面の更新が必要ならその都度直接これを呼ぶ。
                     77: void
                     78: WXMonitorPanel::DoRefresh()
                     79: {
1.1.1.13! root       80:        bool updated = false;
        !            81: 
1.1.1.7   root       82:        // モニタースクリーンを更新して
1.1.1.13! root       83:        monitor->UpdateScreen(screen);
        !            84:        if (screen.GetBuf() != prevbuf) {
        !            85:                updated = true;
        !            86:        }
        !            87: 
        !            88:        // あればビットマップ描画を足して
        !            89:        if (monitor->UpdateBitmap(bitmap)) {
        !            90:                updated = true;
        !            91:        }
1.1.1.7   root       92: 
                     93:        // 必要なら再描画
1.1.1.13! root       94:        if (updated) {
1.1.1.7   root       95:                Refresh();
                     96:        }
                     97: }
                     98: 
                     99: // 画面更新頻度を Hz で設定する。
                    100: void
                    101: WXMonitorPanel::SetRate(int hz)
                    102: {
                    103:        timer.Start(1000 / hz);
                    104: }
                    105: 
                    106: 
                    107: //
                    108: // モニターウィンドウ
                    109: //
1.1.1.6   root      110: 
1.1       root      111: // コンストラクタ
1.1.1.5   root      112: WXMonitorWindow::WXMonitorWindow(wxWindow *parent, const wxString& name,
1.1.1.9   root      113:        Monitor *monitor_)
1.1.1.5   root      114:        : inherited(parent, wxID_ANY, name)
1.1       root      115: {
1.1.1.7   root      116:        // モニタパネル
                    117:        monpanel = new WXMonitorPanel(this, monitor_);
1.1.1.10  root      118:        Fit();
1.1       root      119: }
                    120: 
                    121: // デストラクタ
                    122: WXMonitorWindow::~WXMonitorWindow()
                    123: {
                    124: }
1.1.1.7   root      125: 
                    126: 
                    127: //
                    128: // 縦スクロールバー付きモニタウィンドウ
                    129: //
                    130: 
                    131: // コンストラクタ
                    132: WXScrollMonitorWindow::WXScrollMonitorWindow(wxWindow *parent,
1.1.1.9   root      133:        const wxString& name, Monitor *monitor_)
1.1.1.7   root      134:        : inherited(parent, wxID_ANY, name, DEFAULT_STYLE | wxRESIZE_BORDER)
                    135: {
1.1.1.10  root      136:        DPRINTF("%s begin\n", __method__);
                    137: 
1.1.1.7   root      138:        // +--------------+---------+
                    139:        // | MonitorPanel | VScroll |
                    140:        // +--------------+---------+
                    141: 
                    142:        // モニタパネル
                    143:        monpanel = new WXMonitorPanel(this, monitor_);
                    144: 
                    145:        // スクロールバー
                    146:        vscroll = new WXScrollBar(this, wxID_ANY, wxSB_VERTICAL);
                    147: 
1.1.1.11  root      148:        // 自前レイアウト。
                    149:        SetMyLayout();
1.1.1.7   root      150: 
                    151:        // ウィンドウサイズを確定させる
1.1.1.10  root      152:        FontChanged();
1.1.1.7   root      153: 
                    154:        // スクロールのために (パネル領域での) MouseWheel イベントもここで
                    155:        // 受け取りたい。スクロールバー上のマウスホイール操作はスクロールバーが
                    156:        // 処理しているので問題ないが、パネル領域でのマウスホイール操作はここ
                    157:        // (wxFrame)ではなくパネルに対して飛んでくる。
                    158:        // ここで一緒に処理したほうが楽なので、こちらに回す。
1.1.1.13! root      159:        monpanel->Bind(wxEVT_MOUSEWHEEL,
        !           160:                &WXScrollMonitorWindow::OnMouseWheel, this);
1.1.1.7   root      161: 
                    162:        // スクロールバーからの位置変更通知
1.1.1.13! root      163:        vscroll->Bind(NONO_EVT_SCROLL, &WXScrollMonitorWindow::OnScroll, this);
        !           164: 
1.1.1.10  root      165:        DPRINTF("%s done\n", __method__);
1.1.1.7   root      166: }
                    167: 
                    168: // デストラクタ
                    169: WXScrollMonitorWindow::~WXScrollMonitorWindow()
                    170: {
                    171: }
                    172: 
1.1.1.10  root      173: void
                    174: WXScrollMonitorWindow::FontChanged()
1.1.1.7   root      175: {
1.1.1.10  root      176:        monpanel->FontChanged();
                    177:        vscroll->FontChanged();
                    178:        DPRINTF("%s %d\n", __method__, monpanel->GetFontHeight());
                    179: 
                    180:        Fit();
1.1.1.7   root      181: }
                    182: 
1.1.1.11  root      183: // 自前レイアウト方式のサイズに関する情報を返す。
                    184: bool
                    185: WXScrollMonitorWindow::GetMySizeHints(wxSize *newp, wxSize *minp, wxSize *maxp,
                    186:        wxSize *incp)
1.1.1.7   root      187: {
1.1.1.11  root      188:        auto psize = monpanel->GetSize();
                    189:        auto vsize = vscroll->GetSize();
1.1.1.7   root      190: 
1.1.1.11  root      191:        // 幅は monpanel 幅 + スクロールバーの幅、高さは monpanel の高さで決まる。
                    192:        // monpanel には四辺に Padding があることに注意。
                    193:        int x = psize.x + vsize.x;
                    194:        int min_y = std::max(vscroll->GetMinSize().y, monpanel->GetScreenHeight(1));
                    195:        int new_y = std::max(psize.y, min_y);
                    196:        wxSize newsize(x, new_y);
                    197:        wxSize minsize(x, min_y);
                    198:        wxSize maxsize(x, GetMaxClientSize().y);
                    199:        wxSize incsize(0, monpanel->GetFontHeight());
                    200: 
                    201:        if (newp) *newp = newsize;
                    202:        if (minp) *minp = minsize;
                    203:        if (maxp) *maxp = maxsize;
                    204:        if (incp) *incp = incsize;
                    205:        return true;
1.1.1.10  root      206: }
1.1.1.7   root      207: 
1.1.1.10  root      208: bool
                    209: WXScrollMonitorWindow::Layout()
                    210: {
1.1.1.11  root      211:        if (MyLayout() == false) {
                    212:                // コントロールを配置。
                    213:                wxSize client = GetClientSize();
                    214:                const wxSize vsize = vscroll->GetSize();
                    215: 
                    216:                int mon_width  = client.x - vsize.x;
                    217:                int mon_height = client.y;
                    218:                // 最低でも 1px ないと GTK とかに怒られる。今は起きないはず?
                    219:                if (__predict_false(mon_width < 1)) {
                    220:                        mon_width = 1;
                    221:                }
                    222:                if (__predict_false(mon_height < 1)) {
                    223:                        mon_height = 1;
                    224:                }
1.1.1.10  root      225: #if defined(WINDOW_DEBUG)
1.1.1.11  root      226:                const wxSize win = GetSize();
                    227:                const wxSize minwin = GetMinSize();
                    228:                printf("%s  WinSize   =(%d,%d) MinWin   =(%d,%d) Shown=%u\n",
                    229:                        __method__, win.x, win.y, minwin.x, minwin.y, IsShown());
                    230:                const wxSize min = GetMinClientSize();
                    231:                printf("%s  ClientSize=(%d,%d) MinClient=(%d,%d)\n",
                    232:                        __method__, client.x, client.y, min.x, min.y);
1.1.1.10  root      233: #endif
                    234: 
1.1.1.11  root      235:                monpanel->SetSize(0, 0, mon_width, mon_height);
                    236:                vscroll->SetSize(mon_width, 0, vsize.x, mon_height);
1.1.1.10  root      237: 
1.1.1.11  root      238: #if defined(WINDOW_DEBUG)
                    239:                const wxSize monsize = monpanel->GetSize();
                    240:                const wxSize vsize1 = vscroll->GetSize();
                    241:                int py = monsize.y - monpanel->GetPaddingY();
                    242:                int height = monpanel->GetFontHeight();
                    243:                int row = (height != 0) ? (py / height) : 0;
                    244:                int res = (height != 0) ? (py % height) : 0;
                    245:                printf("%s  mon=(%d,%d) vscroll=(%d,%d), row=%d%s\n", __method__,
                    246:                        monsize.x, monsize.y, vsize1.x, vsize1.y,
                    247:                        row, (res == 0 ? "" : "+"));
                    248: #endif
1.1.1.10  root      249: 
1.1.1.11  root      250:                // スクロールバーを再設定。
                    251:                // 今の所ヘッダが常に1行ある。
                    252:                static int HEADLINES = 1;
                    253:                int pos = (int)monpanel->GetUserData();
                    254:                int thumbsize = monpanel->GetRow() - HEADLINES;
                    255:                int range = monpanel->GetMonitor()->GetMaxHeight() - HEADLINES;
                    256:                int pagesize = thumbsize - 1;
                    257:                if (pos > range - thumbsize) {
                    258:                        pos = range - thumbsize;
                    259:                        DoScroll(pos);
                    260:                }
                    261:                vscroll->SetScrollParam(pos, thumbsize, range, pagesize);
1.1.1.7   root      262:        }
1.1.1.10  root      263:        return true;
                    264: }
                    265: 
1.1.1.7   root      266: // マウスホイールイベント (WXTextScreen 上で起きたやつをこっちに回してある)
                    267: void
                    268: WXScrollMonitorWindow::OnMouseWheel(wxMouseEvent& event)
                    269: {
                    270:        // GetWheelRotation() は上(奥)向きに回すと +120、下(手前)に回すと -120。
                    271:        // どこの決まりか知らんけど、スクロールバーのほうはホイール1段階で3行
                    272:        // スクロールするのでそれに合わせる。
                    273:        int pos = (int)monpanel->GetUserData();
                    274:        pos = pos - event.GetWheelRotation() / 40;
                    275: 
                    276:        int maxpos = vscroll->GetRange() - vscroll->GetThumbSize();
                    277:        if (pos < 0)
                    278:                pos = 0;
                    279:        if (pos > maxpos)
                    280:                pos = maxpos;
                    281: 
                    282:        DoScroll(pos);
                    283:        // スクロールバーの位置を追従
                    284:        vscroll->SetThumbPosition(pos);
                    285: }
                    286: 
                    287: // スクロールバーからの通知イベント
                    288: void
                    289: WXScrollMonitorWindow::OnScroll(wxScrollEvent& event)
                    290: {
                    291:        DoScroll(event.GetPosition());
                    292: }
                    293: 
                    294: // スクロール処理 (OnScroll() と OnMouseWheel() から呼ばれる)
                    295: void
                    296: WXScrollMonitorWindow::DoScroll(int pos)
                    297: {
                    298:        // userdata が表示開始位置になっている
                    299:        monpanel->SetUserData(pos);
                    300:        monpanel->DoRefresh();
                    301: }

unix.superglobalmegacorp.com

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