LCOV - code coverage report
Current view: top level - utils/cursesINDI - cursesTableGrid.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 0.0 % 120 0
Test Date: 2026-01-03 21:03:39 Functions: 0.0 % 10 0

            Line data    Source code
       1              : 
       2              : #ifndef cursesTableGrid_hpp
       3              : #define cursesTableGrid_hpp
       4              : 
       5              : #include <fstream>
       6              : 
       7              : #include <ncurses.h>
       8              : 
       9              : class cursesTableGrid
      10              : {
      11              : public:
      12              : 
      13              :    std::ofstream * fpout {nullptr};
      14              : 
      15              :    int m_xLeft {1};
      16              :    int m_yTop {1};
      17              :    int m_xRight {-1};
      18              :    int m_yBot {-1};
      19              : 
      20              :    int m_minWidth {78};
      21              : 
      22              :    size_t m_currX {0};
      23              :    size_t m_currY {0};
      24              : 
      25              :    size_t m_startRow {0};
      26              : 
      27              :    std::vector<std::vector<std::string>> m_cellContents;
      28              : 
      29              :    std::vector<float> m_colFraction;
      30              : 
      31              : 
      32              :    WINDOW * m_boxWin {nullptr};
      33              :    std::vector<std::vector<WINDOW *>> m_gridWin;
      34              : 
      35              :    int minWidth( int mw );
      36              : 
      37              :    int colWidth( const std::vector<int> & cw );
      38              : 
      39              :    int colFraction( const std::vector<float> & cf );
      40              : 
      41            0 :    int tabHeight()
      42              :    {
      43            0 :       return m_gridWin.size();
      44              :    }
      45              : 
      46              :    bool hasContent( size_t y,
      47              :                     size_t x
      48              :                   );
      49              : 
      50              :    int draw();
      51            0 :    virtual int postDraw()
      52              :    {
      53            0 :       return 0;
      54              :    }
      55              : 
      56              :    int print();
      57              : 
      58            0 :    virtual int postPrint()
      59              :    {
      60            0 :       return 0;
      61              :    }
      62              : 
      63              :    int moveSelected( int nextY,
      64              :                      int nextX
      65              :                    );
      66              : 
      67              :    //Call after setting fraction.
      68              :    int testContents(int nrows);
      69              : };
      70              : 
      71              : inline
      72            0 : int cursesTableGrid::minWidth( int mw )
      73              : {
      74            0 :    m_minWidth = mw;
      75            0 :    return 0;
      76              : }
      77              : 
      78              : inline
      79            0 : int cursesTableGrid::colWidth( const std::vector<int> & cw )
      80              : {
      81              : 
      82            0 :    int mw = 0;
      83            0 :    for(size_t i=0;i<cw.size();++i) mw += cw[i];
      84              : 
      85            0 :    if( minWidth(mw) < 0)
      86              :    {
      87            0 :       return -1;
      88              :    }
      89              : 
      90            0 :    std::vector<float> cf(cw.size());
      91              : 
      92            0 :    for(size_t i=0;i<cf.size();++i)
      93              :    {
      94            0 :       cf[i] = cw[i];
      95            0 :       cf[i] /= m_minWidth;
      96              :    }
      97              : 
      98            0 :    return colFraction(cf);
      99            0 : }
     100              : 
     101              : inline
     102            0 : int cursesTableGrid::colFraction( const std::vector<float> & cf )
     103              : {
     104            0 :    m_colFraction = cf;
     105              : 
     106            0 :    return 0;
     107              : }
     108              : 
     109              : inline
     110            0 : bool cursesTableGrid::hasContent( size_t y,
     111              :                                   size_t x
     112              :                                 )
     113              : {
     114            0 :    bool hascontent = false;
     115            0 :    if(y < m_cellContents.size())
     116              :    {
     117            0 :       if(x < m_cellContents[y].size()) hascontent = true;
     118              :    }
     119              : 
     120            0 :    return hascontent;
     121              : }
     122              : 
     123              : inline
     124            0 : int cursesTableGrid::draw()
     125              : {
     126              :    //Todo: box on/off selectable
     127              :    //Todo: if box on, must be y0>=1, x0>=1
     128              : 
     129            0 :    int tabHeight = LINES - m_yTop - 1;
     130            0 :    if(m_yBot > 0 ) tabHeight -= m_yBot; //else  -= 1.
     131              : 
     132            0 :    int tabWidth = COLS - m_xLeft - 1;
     133            0 :    if(m_xRight > 0 ) tabWidth -= m_xRight + 1;
     134              : 
     135            0 :    if(m_boxWin)
     136            0 :    {  werase(m_boxWin);
     137            0 :       wrefresh(m_boxWin);
     138            0 :       delwin(m_boxWin);
     139              :    }
     140              : 
     141            0 :    m_boxWin = newwin(tabHeight+2, tabWidth+2, m_yTop-1,m_xLeft-1);
     142            0 :    box(m_boxWin, 0, 0);
     143            0 :    wrefresh(m_boxWin);
     144              : 
     145            0 :    if(m_gridWin.size() > 0)
     146              :    {
     147            0 :       for(size_t y =0; y < m_gridWin.size(); ++y)
     148              :       {
     149            0 :          for(size_t x=0; x < m_gridWin[y].size(); ++x)
     150              :          {
     151            0 :             delwin(m_gridWin[y][x]);
     152              :          }
     153              :       }
     154              :    }
     155              : 
     156            0 :    int nDispRow = tabHeight;
     157              : 
     158            0 :    int workingWidth = tabWidth;
     159            0 :    if(workingWidth < m_minWidth) workingWidth = m_minWidth;
     160              : 
     161            0 :    int spos = 0;
     162            0 :    std::vector<int> dispCol_start;
     163            0 :    std::vector<int> dispCol_width;
     164            0 :    for(size_t i=0; i< m_colFraction.size(); ++i)
     165              :    {
     166            0 :       int cw = m_colFraction[i] * workingWidth + 0.5; //rounded
     167              : 
     168            0 :       if(spos + cw > tabWidth) cw = tabWidth-spos;
     169              : 
     170            0 :       if(cw == 0 ) break;
     171              : 
     172            0 :       dispCol_start.push_back(spos);
     173            0 :       dispCol_width.push_back(cw);
     174              : 
     175            0 :       spos += cw;
     176              : 
     177            0 :       if(spos >= tabWidth) break;
     178              :    }
     179              : 
     180            0 :    m_gridWin.resize(nDispRow);
     181              : 
     182            0 :    std::string ch;
     183              : 
     184            0 :    for(size_t y=0; y< m_gridWin.size(); ++y)
     185              :    {
     186            0 :       m_gridWin[y].resize(dispCol_start.size());
     187              : 
     188            0 :       if(fpout) *fpout << y;
     189            0 :       for(size_t x=0; x< m_gridWin[y].size(); ++x)
     190              :       {
     191            0 :          m_gridWin[y][x] = newwin(1, dispCol_width[x], m_yTop+y,m_xLeft + dispCol_start[x]);
     192              : 
     193            0 :          if(fpout) *fpout << ": " << x << " (" <<  dispCol_start[x] << "," << dispCol_width[x] << ")";
     194              : 
     195            0 :          if(hasContent(m_startRow+y,x)) wprintw(m_gridWin[y][x], "%s", m_cellContents[m_startRow + y][x].c_str());
     196              :          //else wprintw(m_gridWin[y][x], ".");
     197            0 :          wrefresh(m_gridWin[y][x]);
     198              :       }
     199            0 :       if(fpout) *fpout << std::endl;
     200              :    }
     201              : 
     202              :    //Move cursor if needed.
     203            0 :    if(m_currY >= m_gridWin.size()) m_currY = m_gridWin.size()-1;
     204            0 :    if(m_currX >= m_gridWin[m_currY].size()) m_currX = m_gridWin[m_currY].size()-1;
     205              : 
     206            0 :    wattron(m_gridWin[m_currY][m_currX], A_REVERSE);
     207            0 :    wclear(m_gridWin[m_currY][m_currX]);
     208            0 :    if(hasContent(m_startRow + m_currY, m_currX))  wprintw(m_gridWin[m_currY][m_currX], "%s", m_cellContents[m_startRow+m_currY][m_currX].c_str());
     209            0 :    wrefresh(m_gridWin[m_currY][m_currX]);
     210              : 
     211              : 
     212            0 :    if(fpout) *fpout << "drawn" << std::endl;
     213              : 
     214            0 :    return postDraw();
     215            0 : }
     216              : 
     217              : inline
     218            0 : int cursesTableGrid::print()
     219              : {
     220            0 :    for(size_t y=0; y< m_gridWin.size(); ++y)
     221              :    {
     222            0 :       for(size_t x=0; x< m_gridWin[y].size(); ++x)
     223              :       {
     224            0 :          wclear(m_gridWin[y][x]);
     225            0 :          if(hasContent(m_startRow+y,x)) wprintw(m_gridWin[y][x], "%s", m_cellContents[m_startRow + y][x].c_str());
     226            0 :          wrefresh(m_gridWin[y][x]);
     227              :       }
     228              :    }
     229              : 
     230            0 :    return postPrint();
     231              : }
     232              : 
     233              : inline
     234              : int cursesTableGrid::testContents(int nrows)
     235              : {
     236              :    m_cellContents.resize(nrows);
     237              : 
     238              :    for(size_t y=0;y<m_cellContents.size(); ++y)
     239              :    {
     240              :       m_cellContents[y].resize(m_colFraction.size());
     241              :    }
     242              : 
     243              :    std::string ch;
     244              :    for(size_t y=0;y<m_cellContents.size(); ++y)
     245              :    {
     246              :       for(size_t x=0; x< m_colFraction.size(); ++x)
     247              :       {
     248              :          size_t cw = m_colFraction[x] * m_minWidth + 0.5;
     249              : 
     250              :          ch=std::to_string(y) + "," + std::to_string(x);
     251              :          if( cw > ch.size()+1) ch += std::string( cw-ch.size()-1,'*');
     252              :          ch += "|";
     253              : 
     254              :          if(ch.size() > cw) ch.erase(cw);
     255              : 
     256              :          m_cellContents[y][x] = ch;
     257              :       }
     258              :    }
     259              : 
     260              :    return 0;
     261              : }
     262              : 
     263              : 
     264              : inline
     265            0 : int cursesTableGrid::moveSelected( int nextY,
     266              :                                    int nextX
     267              :                                  )
     268              : {
     269              :    //Do some bounds checks
     270            0 :    if(m_cellContents.size() == 0 || m_currY >= m_gridWin.size()) return 0;
     271            0 :    if(m_currX >= m_gridWin[m_currY].size()) return 0;
     272              : 
     273              :    //Now turn off the reverse
     274            0 :    wattroff(m_gridWin[m_currY][m_currX], A_REVERSE);
     275              : 
     276            0 :    wclear(m_gridWin[m_currY][m_currX]);
     277            0 :    if(hasContent(m_startRow + m_currY, m_currX))  wprintw(m_gridWin[m_currY][m_currX], "%s", m_cellContents[m_startRow+m_currY][m_currX].c_str());
     278            0 :    wrefresh(m_gridWin[m_currY][m_currX]);
     279              : 
     280            0 :    if(fpout) *fpout << "nextY: " << nextY << " m_gridWin.size(): " <<  m_gridWin.size() << std::endl;
     281              : 
     282            0 :    bool reprint = false;
     283            0 :    if(nextY >= (int64_t) m_gridWin.size())
     284              :    {
     285            0 :       size_t oldSR = m_startRow;
     286            0 :       m_startRow += nextY - m_gridWin.size() + 1;
     287              : 
     288            0 :       if(m_startRow >= m_cellContents.size()) m_startRow = m_cellContents.size()-1;
     289              : 
     290            0 :       if( oldSR != m_startRow) reprint = true;
     291              : 
     292            0 :       if(fpout) *fpout << "+m_startRow: " << m_startRow << " " << reprint << std::endl;
     293              : 
     294            0 :       nextY = m_gridWin.size()-1;
     295              :    }
     296              : 
     297            0 :    if(nextY < 0)
     298              :    {
     299            0 :       size_t oldSR = m_startRow;
     300              : 
     301            0 :       if(m_startRow > 0)
     302              :       {
     303            0 :          if(m_startRow < (size_t) (-nextY)) m_startRow = 0;
     304            0 :          else m_startRow += nextY;
     305              :       }
     306              : 
     307            0 :       if( oldSR != m_startRow) reprint = true;
     308              : 
     309            0 :       if(fpout) *fpout << "-m_startRow: " << m_startRow << " " << reprint << std::endl;
     310              : 
     311            0 :       nextY = 0;
     312              :    }
     313              : 
     314            0 :    if(reprint) print();
     315              : 
     316              :    //Move the cursor position
     317            0 :    if(nextY >= 0 &&  nextY < (int64_t) m_gridWin.size() && nextX >= 0 && nextX < (int64_t) m_gridWin[0].size())
     318              :    {
     319            0 :       m_currY = nextY;
     320            0 :       m_currX = nextX;
     321              :    }
     322              : 
     323              :    //Turn it back on
     324            0 :    wattron(m_gridWin[m_currY][m_currX], A_REVERSE);
     325              : 
     326            0 :    wclear(m_gridWin[m_currY][m_currX]);
     327            0 :    if(hasContent(m_startRow + m_currY, m_currX))  wprintw(m_gridWin[m_currY][m_currX], "%s", m_cellContents[m_startRow+m_currY][m_currX].c_str());
     328            0 :    else wprintw(m_gridWin[m_currY][m_currX], " ");
     329            0 :    wrefresh(m_gridWin[m_currY][m_currX]);
     330              : 
     331            0 :    wattroff(m_gridWin[m_currY][m_currX], A_REVERSE);
     332              : 
     333            0 :    return 0;
     334              : }
     335              : 
     336              : 
     337              : #endif //cursesTableGrid_hpp
        

Generated by: LCOV version 2.0-1