home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / statusbr.cpp < prev    next >
C/C++ Source or Header  |  2002-11-22  |  13KB  |  454 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        generic/statusbr.cpp
  3. // Purpose:     wxStatusBarGeneric class implementation
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     01/02/97
  7. // RCS-ID:      $Id: statusbr.cpp,v 1.47.2.3 2002/11/22 07:13:39 GD Exp $
  8. // Copyright:   (c) Julian Smart and Markus Holzem
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "statusbr.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #if wxUSE_STATUSBAR
  24.  
  25. #ifndef WX_PRECOMP
  26. #include "wx/setup.h"
  27. #include "wx/frame.h"
  28. #include "wx/settings.h"
  29. #include "wx/dcclient.h"
  30. #endif
  31.  
  32. #ifdef __WXGTK20__
  33. #include "wx/gtk/private.h"
  34. #include "wx/gtk/win_gtk.h"
  35. #endif
  36.  
  37. #include "wx/statusbr.h"
  38.  
  39. // we only have to do it here when we use wxStatusBarGeneric in addition to the
  40. // standard wxStatusBar class, if wxStatusBarGeneric is the same as
  41. // wxStatusBar, then the corresponding IMPLEMENT_DYNAMIC_CLASS is already in
  42. // common/statbar.cpp
  43. #if defined(__WXMAC__) || \
  44.     (defined(wxUSE_NATIVE_STATUSBAR) && wxUSE_NATIVE_STATUSBAR)
  45.     #include "wx/generic/statusbr.h"
  46.  
  47.     IMPLEMENT_DYNAMIC_CLASS(wxStatusBarGeneric, wxWindow)
  48. #endif // wxUSE_NATIVE_STATUSBAR
  49.  
  50. BEGIN_EVENT_TABLE(wxStatusBarGeneric, wxWindow)
  51.     EVT_PAINT(wxStatusBarGeneric::OnPaint)
  52.     EVT_LEFT_DOWN(wxStatusBarGeneric::OnLeftDown)
  53.     EVT_RIGHT_DOWN(wxStatusBarGeneric::OnRightDown)
  54.     EVT_SYS_COLOUR_CHANGED(wxStatusBarGeneric::OnSysColourChanged)
  55. END_EVENT_TABLE()
  56.  
  57. // Default status border dimensions
  58. #define         wxTHICK_LINE_BORDER 2
  59. #define         wxTHICK_LINE_WIDTH  1
  60.  
  61. void wxStatusBarGeneric::Init()
  62. {
  63.   m_borderX = wxTHICK_LINE_BORDER;
  64.   m_borderY = wxTHICK_LINE_BORDER;
  65. }
  66.  
  67. wxStatusBarGeneric::~wxStatusBarGeneric()
  68. {
  69.     // VZ: what is this for? please comment...
  70. #ifdef __WXMSW__
  71.     SetFont(wxNullFont);
  72. #endif // MSW
  73. }
  74.  
  75. bool wxStatusBarGeneric::Create(wxWindow *parent,
  76.                                 wxWindowID id,
  77.                                 long style,
  78.                                 const wxString& name)
  79. {
  80.   if ( !wxWindow::Create(parent, id,
  81.                          wxDefaultPosition, wxDefaultSize,
  82.                          style | wxTAB_TRAVERSAL, name) )
  83.       return FALSE;
  84.  
  85.   // The status bar should have a themed background
  86.   SetThemeEnabled( TRUE );
  87.  
  88.   // Don't wish this to be found as a child
  89. #ifndef __WXMAC__
  90.   parent->GetChildren().DeleteObject(this);
  91. #endif
  92.   InitColours();
  93.  
  94.   SetFont(m_defaultStatusBarFont);
  95.  
  96.   // Set the height according to the font and the border size
  97.   wxClientDC dc(this);
  98.   dc.SetFont(GetFont());
  99.  
  100.   wxCoord y;
  101.   dc.GetTextExtent(_T("X"), NULL, &y );
  102.  
  103.   int height = (int)( (11*y)/10 + 2*GetBorderY());
  104.  
  105.   SetSize(-1, -1, -1, height);
  106.  
  107.   return TRUE;
  108. }
  109.  
  110. void wxStatusBarGeneric::SetFieldsCount(int number, const int *widths)
  111. {
  112.     wxASSERT_MSG( number >= 0, _T("negative number of fields in wxStatusBar?") );
  113.  
  114.     int i;
  115.     for(i = m_nFields; i < number; ++i)
  116.         m_statusStrings.Add( wxEmptyString );
  117.  
  118.     for (i = m_nFields - 1; i >= number; --i)
  119.         m_statusStrings.RemoveAt(i);
  120.  
  121.     m_nFields = number;
  122.  
  123.     wxASSERT_MSG( m_nFields == (int)m_statusStrings.GetCount(),
  124.                   _T("This really should never happen, can we do away with m_nFields here?") );
  125.  
  126.     SetStatusWidths(number, widths);
  127. }
  128.  
  129. void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
  130. {
  131.     wxCHECK_RET( (number >= 0) && (number < m_nFields),
  132.                  _T("invalid status bar field index") );
  133.  
  134.     m_statusStrings[number] = text;
  135.  
  136.     wxRect rect;
  137.     GetFieldRect(number, rect);
  138.  
  139.     Refresh( TRUE, &rect );
  140. }
  141.  
  142. wxString wxStatusBarGeneric::GetStatusText(int n) const
  143. {
  144.     wxCHECK_MSG( (n >= 0) && (n < m_nFields), wxEmptyString,
  145.                  _T("invalid status bar field index") );
  146.  
  147.     return m_statusStrings[n];
  148. }
  149.  
  150. void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[])
  151. {
  152.     // only set status widths, when n == number of statuswindows
  153.     wxCHECK_RET( n == m_nFields, _T("status bar field count mismatch") );
  154.  
  155.     // delete the old widths in any case - this function may be used to reset
  156.     // the widths to the default (all equal)
  157.     // MBN: this is incompatible with at least wxMSW and wxMAC and not
  158.     //      documented, but let's keep it for now
  159.     ReinitWidths();
  160.  
  161.     // forget the old cached pixel widths
  162.     m_widthsAbs.Empty();
  163.  
  164.     if ( !widths_field )
  165.     {
  166.         // not an error, see the comment above
  167.         Refresh();
  168.         return;
  169.     }
  170.  
  171.     wxStatusBarBase::SetStatusWidths(n, widths_field);
  172. }
  173.  
  174. void wxStatusBarGeneric::OnPaint(wxPaintEvent& WXUNUSED(event) )
  175. {
  176.     wxPaintDC dc(this);
  177.  
  178. #ifdef __WXGTK20__
  179.     // Draw grip first
  180.     if (HasFlag( wxST_SIZEGRIP ))
  181.     {
  182.         int width, height;
  183.         GetClientSize(&width, &height);
  184.         
  185.         gtk_paint_resize_grip( m_widget->style,
  186.                                GTK_PIZZA(m_wxwindow)->bin_window,
  187.                                (GtkStateType) GTK_WIDGET_STATE (m_widget),
  188.                                NULL,
  189.                                m_widget,
  190.                                "statusbar",
  191.                                GDK_WINDOW_EDGE_SOUTH_EAST,
  192.                                width-height-2, 1, height-2, height-3 );
  193.         
  194.     }
  195. #endif
  196.  
  197.   if (GetFont().Ok())
  198.         dc.SetFont(GetFont());
  199.     
  200.   dc.SetBackgroundMode(wxTRANSPARENT);
  201.  
  202. #ifdef __WXPM__
  203.   wxColour vColor;
  204.  
  205.   vColor = wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR);
  206.   ::WinFillRect(dc.m_hPS, &dc.m_vRclPaint, vColor.GetPixel());
  207. #endif
  208.  
  209.   for (int i = 0; i < m_nFields; i ++)
  210.         DrawField(dc, i);
  211. }
  212.  
  213. void wxStatusBarGeneric::DrawFieldText(wxDC& dc, int i)
  214. {
  215.   int leftMargin = 2;
  216.  
  217.   wxRect rect;
  218.   GetFieldRect(i, rect);
  219.  
  220.   wxString text(GetStatusText(i));
  221.  
  222.   long x, y;
  223.  
  224.   dc.GetTextExtent(text, &x, &y);
  225.  
  226.   int xpos = rect.x + leftMargin;
  227.   int ypos = (int) (((rect.height - y) / 2 ) + rect.y + 0.5) ;
  228.  
  229. #if defined( __WXGTK__ ) || defined(__WXMAC__)
  230.   xpos++;
  231.   ypos++;
  232. #endif
  233.  
  234.   dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height);
  235.  
  236.   dc.DrawText(text, xpos, ypos);
  237.  
  238.   dc.DestroyClippingRegion();
  239. }
  240.  
  241. void wxStatusBarGeneric::DrawField(wxDC& dc, int i)
  242. {
  243.     wxRect rect;
  244.     GetFieldRect(i, rect);
  245.  
  246.     // Draw border
  247.     // Have grey background, plus 3-d border -
  248.     // One black rectangle.
  249.     // Inside this, left and top sides - dark grey. Bottom and right -
  250.     // white.
  251.  
  252.     dc.SetPen(m_hilightPen);
  253.  
  254. #ifndef __WXPM__
  255.  
  256.     // Right and bottom white lines
  257.     dc.DrawLine(rect.x + rect.width, rect.y,
  258.                 rect.x + rect.width, rect.y + rect.height);
  259.     dc.DrawLine(rect.x + rect.width, rect.y + rect.height,
  260.                 rect.x, rect.y + rect.height);
  261.  
  262.     dc.SetPen(m_mediumShadowPen);
  263.  
  264.     // Left and top grey lines
  265.     dc.DrawLine(rect.x, rect.y + rect.height,
  266.            rect.x, rect.y);
  267.     dc.DrawLine(rect.x, rect.y,
  268.         rect.x + rect.width, rect.y);
  269. #else
  270.  
  271.     dc.DrawLine(rect.x + rect.width, rect.height + 2,
  272.                 rect.x, rect.height + 2);
  273.     dc.DrawLine(rect.x + rect.width, rect.y,
  274.                 rect.x + rect.width, rect.y + rect.height);
  275.  
  276.     dc.SetPen(m_mediumShadowPen);
  277.     dc.DrawLine(rect.x, rect.y,
  278.                 rect.x + rect.width, rect.y);
  279.     dc.DrawLine(rect.x, rect.y + rect.height,
  280.                 rect.x, rect.y);
  281.  
  282. #endif
  283.  
  284.     DrawFieldText(dc, i);
  285. }
  286.  
  287.   // Get the position and size of the field's internal bounding rectangle
  288. bool wxStatusBarGeneric::GetFieldRect(int n, wxRect& rect) const
  289. {
  290.     wxCHECK_MSG( (n >= 0) && (n < m_nFields), FALSE,
  291.                  _T("invalid status bar field index") );
  292.  
  293.     // FIXME: workarounds for OS/2 bugs have nothing to do here (VZ)
  294.     int width, height;
  295. #ifdef __WXPM__
  296.     GetSize(&width, &height);
  297. #else
  298.     GetClientSize(&width, &height);
  299. #endif
  300.  
  301.     // we cache m_widthsAbs between calls and recompute it if client
  302.     // width has changed (or when it is initially empty)
  303.     if ( m_widthsAbs.IsEmpty() || (m_lastClientWidth != width) )
  304.     {
  305.         wxConstCast(this, wxStatusBarGeneric)->
  306.             m_widthsAbs = CalculateAbsWidths(width);
  307.         // remember last width for which we have recomputed the widths in pixels
  308.         wxConstCast(this, wxStatusBarGeneric)->
  309.             m_lastClientWidth = width;
  310.     }
  311.  
  312.     rect.x = 0;
  313.     for ( int i = 0; i < n; i++ )
  314.     {
  315.         rect.x += m_widthsAbs[i];
  316.     }
  317.  
  318.     rect.x += m_borderX;
  319.     rect.y = m_borderY;
  320.  
  321.     rect.width = m_widthsAbs[n] - 2*m_borderX;
  322.     rect.height = height - 2*m_borderY;
  323.  
  324.     return TRUE;
  325. }
  326.  
  327. // Initialize colours
  328. void wxStatusBarGeneric::InitColours()
  329. {
  330.     // Shadow colours
  331. #if defined(__WIN95__)
  332.     wxColour mediumShadowColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW));
  333.     m_mediumShadowPen = wxPen(mediumShadowColour, 1, wxSOLID);
  334.  
  335.     wxColour hilightColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT));
  336.     m_hilightPen = wxPen(hilightColour, 1, wxSOLID);
  337. #elif defined(__WXPM__)
  338.     m_mediumShadowPen = wxPen(wxColour(127, 127, 127), 1, wxSOLID);
  339.     m_hilightPen = wxPen("WHITE", 1, wxSOLID);
  340.  
  341.     wxColour                        vColour;
  342.  
  343.     vColour.Set(wxString("LIGHT GREY"));
  344.     SetBackgroundColour(vColour);
  345.     vColour.Set(wxString("BLACK"));
  346.     SetForegroundColour(vColour);
  347.     m_defaultStatusBarFont = *wxSMALL_FONT;
  348. #else
  349.     m_mediumShadowPen = wxPen("GREY", 1, wxSOLID);
  350.     m_hilightPen = wxPen("WHITE", 1, wxSOLID);
  351. #endif
  352.  
  353. #ifndef __WXPM__
  354.     m_defaultStatusBarFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
  355.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
  356. #endif
  357. }
  358.  
  359. // Responds to colour changes, and passes event on to children.
  360. void wxStatusBarGeneric::OnSysColourChanged(wxSysColourChangedEvent& event)
  361. {
  362.     InitColours();
  363.     Refresh();
  364.  
  365.     // Propagate the event to the non-top-level children
  366.     wxWindow::OnSysColourChanged(event);
  367. }
  368.  
  369. void wxStatusBarGeneric::SetMinHeight(int height)
  370. {
  371.     // check that this min height is not less than minimal height for the
  372.     // current font
  373.     wxClientDC dc(this);
  374.     wxCoord y;
  375.     dc.GetTextExtent( wxT("X"), NULL, &y );
  376.  
  377.     if ( height > (11*y)/10 )
  378.     {
  379.         SetSize(-1, -1, -1, height + 2*m_borderY);
  380.     }
  381. }
  382.  
  383. void wxStatusBarGeneric::OnLeftDown(wxMouseEvent& event)
  384. {
  385. #ifdef __WXGTK20__
  386.     int width, height;
  387.     GetClientSize(&width, &height);
  388.     
  389.     if (HasFlag( wxST_SIZEGRIP ) && (event.GetX() > width-height))
  390.     {
  391.         GtkWidget *ancestor = gtk_widget_get_toplevel( m_widget );
  392.  
  393.         if (!GTK_IS_WINDOW (ancestor))
  394.             return;
  395.  
  396.         GdkWindow *source = GTK_PIZZA(m_wxwindow)->bin_window;
  397.  
  398.         int org_x = 0;
  399.         int org_y = 0;
  400.         gdk_window_get_origin( source, &org_x, &org_y );
  401.  
  402.         gtk_window_begin_resize_drag (GTK_WINDOW (ancestor),
  403.                                   GDK_WINDOW_EDGE_SOUTH_EAST,
  404.                                   1,
  405.                                   org_x + event.GetX(), 
  406.                                   org_y + event.GetY(), 
  407.                                   0);
  408.     }
  409.     else
  410.     {
  411.         event.Skip( TRUE );
  412.     }
  413. #else
  414.     event.Skip( TRUE );
  415. #endif
  416. }
  417.  
  418. void wxStatusBarGeneric::OnRightDown(wxMouseEvent& event)
  419. {
  420. #ifdef __WXGTK20__
  421.     int width, height;
  422.     GetClientSize(&width, &height);
  423.     
  424.     if (HasFlag( wxST_SIZEGRIP ) && (event.GetX() > width-height))
  425.     {
  426.         GtkWidget *ancestor = gtk_widget_get_toplevel( m_widget );
  427.  
  428.         if (!GTK_IS_WINDOW (ancestor))
  429.             return;
  430.  
  431.         GdkWindow *source = GTK_PIZZA(m_wxwindow)->bin_window;
  432.  
  433.         int org_x = 0;
  434.         int org_y = 0;
  435.         gdk_window_get_origin( source, &org_x, &org_y );
  436.     
  437.         gtk_window_begin_move_drag (GTK_WINDOW (ancestor),
  438.                                 2,
  439.                                 org_x + event.GetX(), 
  440.                                 org_y + event.GetY(), 
  441.                                 0);
  442.     }
  443.     else
  444.     {
  445.         event.Skip( TRUE );
  446.     }
  447. #else
  448.     event.Skip( TRUE );
  449. #endif
  450. }
  451.  
  452. #endif // wxUSE_STATUSBAR
  453.  
  454.