home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / gizmos / ledctrl.cpp < prev    next >
C/C++ Source or Header  |  2002-01-28  |  10KB  |  361 lines

  1. // ============================================================================
  2. // headers
  3. // ============================================================================
  4.  
  5. #ifdef __GNUG__
  6.     #pragma  implementation "wxLEDNumberCtrl.h"
  7. #endif
  8.  
  9. #include "wx/wxprec.h"
  10.  
  11. #ifdef __BORLANDC__
  12.     #pragma hdrstop
  13. #endif  //__BORLANDC__
  14.  
  15. #ifndef WX_PRECOMP
  16.     #include "wx/dcclient.h"
  17.     #include "wx/dcmemory.h"
  18.     #include "wx/intl.h"
  19. #endif
  20.  
  21. #include "wx/gizmos/ledctrl.h"
  22.  
  23. // ----------------------------------------------------------------------------
  24. // constants
  25. // ----------------------------------------------------------------------------
  26.  
  27. // A LED digit is build up like this, with maximum 7 Lines :
  28. //
  29. // 111
  30. // 6 2
  31. // 777
  32. // 5 3
  33. // 444
  34. //
  35. // Each number contains combinations of the lines, and they are set up below.
  36.  
  37. const int LINE1 = 1;
  38. const int LINE2 = 2;
  39. const int LINE3 = 4;
  40. const int LINE4 = 8;
  41. const int LINE5 = 16;
  42. const int LINE6 = 32;
  43. const int LINE7 = 64;
  44.  
  45. const int DIGIT0 = LINE1 | LINE2 | LINE3 | LINE4 | LINE5 | LINE6;
  46. const int DIGIT1 = LINE2 | LINE3;
  47. const int DIGIT2 = LINE1 | LINE2 | LINE4 | LINE5 | LINE7;
  48. const int DIGIT3 = LINE1 | LINE2 | LINE3 | LINE4 | LINE7;
  49. const int DIGIT4 = LINE2 | LINE3 | LINE6 | LINE7;
  50. const int DIGIT5 = LINE1 | LINE3 | LINE4 | LINE6 | LINE7;
  51. const int DIGIT6 = LINE1 | LINE3 | LINE4 | LINE5 | LINE6 | LINE7;
  52. const int DIGIT7 = LINE1 | LINE2 | LINE3;
  53. const int DIGIT8 = LINE1 | LINE2 | LINE3 | LINE4 | LINE5 | LINE6 | LINE7;
  54. const int DIGIT9 = LINE1 | LINE2 | LINE3 | LINE6 | LINE7;
  55. const int DASH   = LINE7;
  56.  
  57. const int DIGITALL = -1;
  58.  
  59. // ============================================================================
  60. // wxLEDNumberCtrl class implementation
  61. // ============================================================================
  62.  
  63. wxLEDNumberCtrl::wxLEDNumberCtrl()
  64. :   m_Alignment(wxLED_ALIGN_LEFT),
  65.     m_LineMargin(-1),
  66.     m_DigitMargin(-1),
  67.     m_LineLength(-1),
  68.     m_LineWidth(-1),
  69.     m_DrawFaded(FALSE),
  70.     m_LeftStartPos(-1)
  71. {
  72. }
  73.  
  74.  
  75. wxLEDNumberCtrl::wxLEDNumberCtrl(wxWindow *parent, wxWindowID id,
  76.                                  const wxPoint& pos, const wxSize& size,
  77.                                  long style)
  78. :   m_Alignment(wxLED_ALIGN_LEFT),
  79.     m_LineMargin(-1),
  80.     m_DigitMargin(-1),
  81.     m_LineLength(-1),
  82.     m_LineWidth(-1),
  83.     m_DrawFaded(FALSE),
  84.     m_LeftStartPos(-1)
  85. {
  86.     Create(parent, id, pos, size, style);
  87. }
  88.  
  89.  
  90. bool wxLEDNumberCtrl::Create(wxWindow *parent, wxWindowID id,
  91.                                  const wxPoint& pos, const wxSize& size,
  92.                                  long style)
  93. {
  94.     bool RetVal = wxControl::Create(parent, id, pos, size, style);
  95.  
  96.     if ((style & wxLED_DRAW_FADED) != 0)
  97.         SetDrawFaded(TRUE);
  98.     if ((style & wxLED_ALIGN_MASK) != 0)
  99.         SetAlignment((wxLEDValueAlign)(style & wxLED_ALIGN_MASK));
  100.  
  101.     SetBackgroundColour(*wxBLACK);
  102.     SetForegroundColour(*wxGREEN);
  103.  
  104.     return RetVal;
  105. }
  106.  
  107.  
  108. void wxLEDNumberCtrl::SetAlignment(wxLEDValueAlign Alignment, bool Redraw)
  109. {
  110.     if (Alignment != m_Alignment)
  111.     {
  112.         m_Alignment = Alignment;
  113.         RecalcInternals(GetClientSize());
  114.  
  115.         if (Redraw)
  116.             Refresh(FALSE);
  117.     }
  118. }
  119.  
  120.  
  121. void wxLEDNumberCtrl::SetDrawFaded(bool DrawFaded, bool Redraw)
  122. {
  123.     if (DrawFaded != m_DrawFaded)
  124.     {
  125.         m_DrawFaded = DrawFaded;
  126.  
  127.         if (Redraw)
  128.             Refresh(FALSE);
  129.     }
  130. }
  131.  
  132.  
  133. void wxLEDNumberCtrl::SetValue(wxString const &Value, bool Redraw)
  134. {
  135.     if (Value != m_Value)
  136.     {
  137. #ifdef __WXDEBUG__
  138.         if (!Value.IsEmpty())
  139.         {
  140.             for(size_t i=0; i<Value.Length(); i++) {
  141.                 wxChar ch = Value[i];
  142.                 wxASSERT_MSG((ch>='0' && ch<='9') || ch=='-' || ch==' ',
  143.                              wxT("wxLEDNumberCtrl can only display numeric string values."));
  144.             }
  145.         }
  146. #endif
  147.  
  148.         m_Value = Value;
  149.         RecalcInternals(GetClientSize());
  150.  
  151.         if (Redraw)
  152.             Refresh(FALSE);
  153.     }
  154. }
  155.  
  156.  
  157. BEGIN_EVENT_TABLE(wxLEDNumberCtrl, wxControl)
  158.     EVT_ERASE_BACKGROUND(wxLEDNumberCtrl::OnEraseBackground)
  159.     EVT_PAINT(wxLEDNumberCtrl::OnPaint)
  160.     EVT_SIZE(wxLEDNumberCtrl::OnSize)
  161. END_EVENT_TABLE()
  162.  
  163.  
  164. void wxLEDNumberCtrl::OnEraseBackground(wxEraseEvent &Event)
  165. {
  166. }
  167.  
  168.  
  169. void wxLEDNumberCtrl::OnPaint(wxPaintEvent &Event)
  170. {
  171.     wxPaintDC Dc(this);
  172.  
  173.     int Width, Height;
  174.     GetClientSize(&Width, &Height);
  175.  
  176.     wxBitmap *pMemoryBitmap = new wxBitmap(Width, Height);
  177.     wxMemoryDC MemDc;
  178.  
  179.     MemDc.SelectObject(*pMemoryBitmap);
  180.     MemDc.BeginDrawing();
  181.  
  182.     // Draw background.
  183.     MemDc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
  184.     MemDc.DrawRectangle(wxRect(0, 0, Width, Height));
  185.     MemDc.SetBrush(wxNullBrush);
  186.  
  187.     // Iterate each digit in the value, and draw.
  188.     const int DigitCount = m_Value.Len();
  189.     for (int i = 0; i < DigitCount; ++i)
  190.     {
  191.         // Draw faded lines if wanted.
  192.         if (m_DrawFaded)
  193.             DrawDigit(MemDc, DIGITALL, i);
  194.  
  195.         // Draw the digits.
  196.         switch (m_Value.GetChar(i))
  197.         {
  198.             case '0' :
  199.                 DrawDigit(MemDc, DIGIT0, i);
  200.                 break;
  201.             case '1' :
  202.                 DrawDigit(MemDc, DIGIT1, i);
  203.                 break;
  204.             case '2' :
  205.                 DrawDigit(MemDc, DIGIT2, i);
  206.                 break;
  207.             case '3' :
  208.                 DrawDigit(MemDc, DIGIT3, i);
  209.                 break;
  210.             case '4' :
  211.                 DrawDigit(MemDc, DIGIT4, i);
  212.                 break;
  213.             case '5' :
  214.                 DrawDigit(MemDc, DIGIT5, i);
  215.                 break;
  216.             case '6' :
  217.                 DrawDigit(MemDc, DIGIT6, i);
  218.                 break;
  219.             case '7' :
  220.                 DrawDigit(MemDc, DIGIT7, i);
  221.                 break;
  222.             case '8' :
  223.                 DrawDigit(MemDc, DIGIT8, i);
  224.                 break;
  225.             case '9' :
  226.                 DrawDigit(MemDc, DIGIT9, i);
  227.                 break;
  228.             case '-' :
  229.                 DrawDigit(MemDc, DASH, i);
  230.                 break;
  231.             case ' ' :
  232.                 // just skip it
  233.                 break;
  234.             default :
  235.                 wxFAIL_MSG(wxT("Unknown digit value"));
  236.                 break;
  237.         }
  238.     }
  239.  
  240.     MemDc.EndDrawing();
  241.  
  242.     // Blit the memory dc to screen.
  243.     Dc.Blit(0, 0, Width, Height, &MemDc, 0, 0, wxCOPY);
  244.     delete pMemoryBitmap;
  245. }
  246.  
  247.  
  248. void wxLEDNumberCtrl::DrawDigit(wxDC &Dc, int Digit, int Column)
  249. {
  250.     wxColour LineColor(GetForegroundColour());
  251.  
  252.     if (Digit == DIGITALL)
  253.     {
  254.         const int R = LineColor.Red() / 3;
  255.         const int G = LineColor.Green() / 3;
  256.         const int B = LineColor.Blue() / 3;
  257.  
  258.         LineColor.Set(R, G, B);
  259.     }
  260.  
  261.     int XPos = m_LeftStartPos;
  262.  
  263.     if (Column > 0)
  264.         XPos += (Column * m_LineLength) + (m_DigitMargin) * Column;
  265.  
  266.     // Create a pen and draw the lines.
  267.     wxPen Pen(LineColor, m_LineWidth, wxSOLID);
  268.     Dc.SetPen(Pen);
  269.  
  270.     if ((Digit & LINE1))
  271.     {
  272.         Dc.DrawLine(XPos + m_LineMargin*2, m_LineMargin,
  273.             XPos + m_LineLength, m_LineMargin);
  274.     }
  275.  
  276.     if (Digit & LINE2)
  277.     {
  278.         Dc.DrawLine(XPos + m_LineLength + m_LineMargin, m_LineMargin*2,
  279.             XPos + m_LineLength + m_LineMargin, m_LineLength + (m_LineMargin*2));
  280.     }
  281.  
  282.     if (Digit & LINE3)
  283.     {
  284.         Dc.DrawLine(XPos + m_LineLength + m_LineMargin, m_LineLength + (m_LineMargin*4),
  285.             XPos + m_LineLength + m_LineMargin, m_LineLength*2 + (m_LineMargin*3));
  286.     }
  287.  
  288.     if (Digit & LINE4)
  289.     {
  290.         Dc.DrawLine(XPos + m_LineMargin*2, m_LineLength*2 + (m_LineMargin*4),
  291.             XPos + m_LineLength, m_LineLength*2 + (m_LineMargin*4));
  292.     }
  293.  
  294.     if (Digit & LINE5)
  295.     {
  296.         Dc.DrawLine(XPos + m_LineMargin, m_LineLength + (m_LineMargin*4),
  297.             XPos + m_LineMargin, m_LineLength*2 + (m_LineMargin*3));
  298.     }
  299.  
  300.     if (Digit & LINE6)
  301.     {
  302.         Dc.DrawLine(XPos + m_LineMargin, m_LineMargin*2,
  303.             XPos + m_LineMargin, m_LineLength + (m_LineMargin*2));
  304.     }
  305.  
  306.     if (Digit & LINE7)
  307.     {
  308.         Dc.DrawLine(XPos + m_LineMargin*2, m_LineLength + (m_LineMargin*3),
  309.             XPos + m_LineMargin + m_LineLength - m_LineMargin, m_LineLength + (m_LineMargin*3));
  310.     }
  311.  
  312.     Dc.SetPen(wxNullPen);
  313. }
  314.  
  315.  
  316. void wxLEDNumberCtrl::RecalcInternals(const wxSize &CurrentSize)
  317. {
  318.     const int Height = CurrentSize.GetHeight();
  319.  
  320.     if ((Height * 0.07) < 1)
  321.         m_LineMargin = 1;
  322.     else
  323.         m_LineMargin = (int)(Height * 0.07);
  324.  
  325.     if ((Height * 0.35) < 1)
  326.         m_LineLength = 1;
  327.     else
  328.         m_LineLength = (int)(Height * 0.35);
  329.  
  330.     m_LineWidth = m_LineMargin;
  331.  
  332.     m_DigitMargin = m_LineMargin * 4;
  333.  
  334.     const int ValueWidth = (m_LineLength + m_DigitMargin) * m_Value.Len();
  335.     const int ClientWidth = CurrentSize.GetWidth();
  336.  
  337.     switch (m_Alignment)
  338.     {
  339.         case wxLED_ALIGN_LEFT :
  340.             m_LeftStartPos = 0;
  341.             break;
  342.         case wxLED_ALIGN_RIGHT :
  343.             m_LeftStartPos = ClientWidth - ValueWidth;
  344.             break;
  345.         case wxLED_ALIGN_CENTER :
  346.             m_LeftStartPos = (ClientWidth - ValueWidth) / 2;
  347.             break;
  348.         default :
  349.             wxFAIL_MSG(wxT("Unknown alignent value for wxLEDNumberCtrl."));
  350.             break;
  351.     }
  352. }
  353.  
  354.  
  355. void wxLEDNumberCtrl::OnSize(wxSizeEvent &Event)
  356. {
  357.     RecalcInternals(Event.GetSize());
  358.  
  359.     Event.Skip();
  360. }
  361.