You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
9.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020 Ian McInerney <ian.s.mcinerney@ieee.org>
  5. * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef INFOBAR_H_
  21. #define INFOBAR_H_
  22. #include <core/optional.h>
  23. #include <wx/event.h>
  24. #include <wx/infobar.h>
  25. #include <wx/timer.h>
  26. #include <wx/panel.h>
  27. #include <wx/sizer.h>
  28. class wxAuiManager;
  29. class wxHyperlinkCtrl;
  30. enum
  31. {
  32. /// ID for the close button on the frame's infobar
  33. ID_CLOSE_INFOBAR = 2000,
  34. };
  35. wxDECLARE_EVENT( KIEVT_SHOW_INFOBAR, wxCommandEvent );
  36. wxDECLARE_EVENT( KIEVT_DISMISS_INFOBAR, wxCommandEvent );
  37. /**
  38. * A modified version of the wxInfoBar class that allows us to:
  39. * * Show the close button along with the other buttons
  40. * * Remove all user-provided buttons at once
  41. * * Allow automatically hiding the infobar after a time period
  42. * * Show/hide using events
  43. * * Place it inside an AUI manager
  44. *
  45. * This inherits from the generic infobar because the native infobar
  46. * on GTK doesn't include the icon on the left and it looks worse.
  47. *
  48. * There are 2 events associated with the infobar:
  49. *
  50. * KIEVT_SHOW_INFOBAR:
  51. * An event that tells the infobar to show a message.
  52. *
  53. * The message text is contained inside the string component,
  54. * and the message flag is contained inside the int component.
  55. *
  56. * Sample event creation code:
  57. * wxCommandEvent* evt = new wxCommandEvent( KIEVT_SHOW_INFOBAR );
  58. * evt->SetString( "A message to show" );
  59. * evt->SetInt( wxICON_WARNING );
  60. *
  61. * KIEVT_DISMISS_INFOBAR:
  62. * An event that tells the infobar to hide itself.
  63. */
  64. class WX_INFOBAR : public wxInfoBarGeneric
  65. {
  66. public:
  67. /**
  68. * Construct an infobar that can exist inside an AUI managed frame.
  69. *
  70. * @param aParent is the parent
  71. * @param aMgr is the AUI manager that this infobar is added to
  72. * @param aWinId is the ID for this infobar object
  73. */
  74. WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr = nullptr, wxWindowID aWinid = wxID_ANY );
  75. ~WX_INFOBAR();
  76. /**
  77. * Sets the type of message for special handling if needed
  78. */
  79. enum class MESSAGE_TYPE
  80. {
  81. GENERIC, /**< GENERIC Are messages that do not have special handling */
  82. OUTDATED_SAVE, /**< OUTDATED_SAVE Messages that should be cleared on save */
  83. DRC_RULES_ERROR,
  84. DRC_VIOLATION
  85. };
  86. MESSAGE_TYPE GetMessageType() const { return m_type; }
  87. /**
  88. * Set the time period to show the infobar.
  89. *
  90. * This only applies for the next showing of the infobar,
  91. * so it must be reset every time. A value of 0 disables
  92. * the automatic hiding (this is the default).
  93. *
  94. * @param aTime is the time in milliseconds to show the infobar
  95. */
  96. void SetShowTime( int aTime );
  97. /**
  98. * Add the default close button to the infobar on the right side.
  99. *
  100. * @param aTooltip is the tooltip to give the close button
  101. */
  102. void AddCloseButton( const wxString& aTooltip = _( "Hide this message." ) );
  103. /**
  104. * Add an already created button to the infobar.
  105. * New buttons are added in the right-most position.
  106. *
  107. * @param aButton is the button to add
  108. */
  109. void AddButton( wxButton* aButton );
  110. /**
  111. * Add an already created hypertext link to the infobar.
  112. * New buttons are added in the right-most position.
  113. *
  114. * @param aHypertextButton is the button to add
  115. */
  116. void AddButton( wxHyperlinkCtrl* aHypertextButton );
  117. /**
  118. * Add a button with the provided ID and text.
  119. * The new button is created on the right-most position.
  120. *
  121. * @param aId is the ID to assign to the button
  122. * @param aLabel is the text for the button
  123. */
  124. void AddButton( wxWindowID aId, const wxString& aLabel = wxEmptyString ) override;
  125. /**
  126. * Remove all the buttons that have been added by the user.
  127. */
  128. void RemoveAllButtons();
  129. bool HasCloseButton() const;
  130. /**
  131. * Provide a callback to be called when the infobar is dismissed (either by user action
  132. * or timer).
  133. * @param aCallback
  134. */
  135. void SetCallback( std::function<void(void)> aCallback )
  136. {
  137. m_callback = aCallback;
  138. }
  139. /**
  140. * Show the infobar with the provided message and icon for a specific period
  141. * of time.
  142. *
  143. * @param aMessage is the message to display
  144. * @param aTime is the amount of time in milliseconds to show the infobar
  145. * @param aFlags is the flag containing the icon to display on the left side of the infobar
  146. */
  147. void ShowMessageFor( const wxString& aMessage, int aTime, int aFlags = wxICON_INFORMATION,
  148. MESSAGE_TYPE aType = WX_INFOBAR::MESSAGE_TYPE::GENERIC );
  149. /**
  150. * Show the info bar with the provided message and icon.
  151. *
  152. * @param aMessage is the message to display
  153. * @param aFlags is the flag containing the icon to display on the left side of the infobar
  154. */
  155. void ShowMessage( const wxString& aMessage, int aFlags = wxICON_INFORMATION ) override;
  156. /**
  157. * Show the info bar with the provided message and icon, setting the type
  158. *
  159. * @param aMessage is the message to display
  160. * @param aFlags is the flag containing the icon to display on the left side of the infobar
  161. * @param aType is the type of message being displayed
  162. */
  163. void ShowMessage( const wxString& aMessage, int aFlags, MESSAGE_TYPE aType );
  164. /**
  165. * Dismisses the infobar and updates the containing layout and AUI manager
  166. * (if one is provided).
  167. */
  168. void Dismiss() override;
  169. /**
  170. * Send the infobar an event telling it to show a message.
  171. *
  172. * @param aMessage is the message to display
  173. * @param aFlags is the flag containing the icon to display on the left side of the infobar
  174. */
  175. void QueueShowMessage( const wxString& aMessage, int aFlags = wxICON_INFORMATION );
  176. /**
  177. * Send the infobar an event telling it to hide itself.
  178. */
  179. void QueueDismiss();
  180. /**
  181. * Returns true if the infobar is being updated.
  182. */
  183. bool IsLocked()
  184. {
  185. return m_updateLock;
  186. }
  187. protected:
  188. /**
  189. * Event handler for showing the infobar using a wxCommandEvent of the type
  190. * KIEVT_SHOW_INFOBAR. The message is stored inside the string field, and the
  191. * icon flag is stored inside the int field.
  192. */
  193. void onShowInfoBar( wxCommandEvent& aEvent );
  194. /**
  195. * Event handler for dismissing the infobar using a wxCommandEvent of the type
  196. * KIEVT_DISMISS_INFOBAR.
  197. */
  198. void onDismissInfoBar( wxCommandEvent& aEvent );
  199. /**
  200. * Event handler for the close button.
  201. * This is bound to ID_CLOSE_INFOBAR on the infobar.
  202. */
  203. void onCloseButton( wxCommandEvent& aEvent );
  204. /**
  205. * Event handler for the automatic closing timer.
  206. */
  207. void onTimer( wxTimerEvent& aEvent );
  208. void onSize( wxSizeEvent& aEvent );
  209. /**
  210. * Update the AUI pane to show or hide this infobar.
  211. *
  212. * @param aShow is true to show the pane
  213. */
  214. void updateAuiLayout( bool aShow );
  215. protected:
  216. int m_showTime; ///< The time to show the infobar. 0 = don't auto hide
  217. bool m_updateLock; ///< True if this infobar requested the UI update
  218. wxTimer* m_showTimer; ///< The timer counting the autoclose period
  219. wxAuiManager* m_auiManager; ///< The AUI manager that contains this infobar
  220. MESSAGE_TYPE m_type; ///< The type of message being displayed
  221. OPT<std::function<void(void)>> m_callback; ///< Optional callback made when closing infobar
  222. DECLARE_EVENT_TABLE()
  223. };
  224. /**
  225. * A wxPanel derived class that hold an infobar and another control.
  226. * The infobar is located at the top of the panel, and the other control
  227. * is located below it.
  228. *
  229. * This allows the infobar to be controlled nicely by an AUI manager,
  230. * since adding the infobar on its own to the AUI manager produces
  231. * artifacts when showing/hiding it due to the AUI pane layout.
  232. *
  233. * Note that this implementation currently has issues on Windows with
  234. * event processing inside the GAL canvas, see:
  235. * https://gitlab.com/kicad/code/kicad/-/issues/4501
  236. *
  237. */
  238. class EDA_INFOBAR_PANEL : public wxPanel
  239. {
  240. public:
  241. EDA_INFOBAR_PANEL( wxWindow* aParent, wxWindowID aId = wxID_ANY,
  242. const wxPoint& aPos = wxDefaultPosition,
  243. const wxSize& aSize = wxSize( -1,-1 ),
  244. long aStyle = wxTAB_TRAVERSAL,
  245. const wxString& aName = wxEmptyString );
  246. /**
  247. * Add the given infobar object to the panel
  248. *
  249. * @param aInfoBar is the infobar to add
  250. */
  251. void AddInfoBar( WX_INFOBAR* aInfoBar );
  252. /**
  253. * Add the other item to the panel.
  254. * This item will expand to fill up the vertical space left.
  255. *
  256. * @param aOtherItem is the item to add
  257. */
  258. void AddOtherItem( wxWindow* aOtherItem );
  259. protected:
  260. // The sizer containing the infobar and the other object
  261. wxFlexGridSizer* m_mainSizer;
  262. };
  263. #endif // INFOBAR_H_