LinkLabel.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (c) 2020, Alex McGrath <amk@amk.ie>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibGUI/Action.h>
  7. #include <LibGUI/Clipboard.h>
  8. #include <LibGUI/Event.h>
  9. #include <LibGUI/LinkLabel.h>
  10. #include <LibGUI/Menu.h>
  11. #include <LibGUI/Painter.h>
  12. #include <LibGUI/Window.h>
  13. #include <LibGfx/Font.h>
  14. #include <LibGfx/Palette.h>
  15. REGISTER_WIDGET(GUI, LinkLabel)
  16. namespace GUI {
  17. LinkLabel::LinkLabel(String text)
  18. : Label(move(text))
  19. {
  20. set_override_cursor(Gfx::StandardCursor::Hand);
  21. set_foreground_role(Gfx::ColorRole::Link);
  22. set_focus_policy(FocusPolicy::TabFocus);
  23. setup_actions();
  24. }
  25. void LinkLabel::setup_actions()
  26. {
  27. m_open_action = GUI::Action::create("Show in File Manager", {}, Gfx::Bitmap::load_from_file("/res/icons/16x16/app-file-manager.png"), [&](const GUI::Action&) {
  28. if (on_click)
  29. on_click();
  30. });
  31. m_copy_action = CommonActions::make_copy_action([this](auto&) { Clipboard::the().set_plain_text(text()); }, this);
  32. }
  33. void LinkLabel::mousedown_event(MouseEvent& event)
  34. {
  35. if (event.button() != MouseButton::Left)
  36. return;
  37. Label::mousedown_event(event);
  38. if (on_click) {
  39. on_click();
  40. }
  41. }
  42. void LinkLabel::keydown_event(KeyEvent& event)
  43. {
  44. Label::keydown_event(event);
  45. if (event.key() == KeyCode::Key_Return || event.key() == KeyCode::Key_Space) {
  46. if (on_click)
  47. on_click();
  48. }
  49. }
  50. void LinkLabel::paint_event(PaintEvent& event)
  51. {
  52. Label::paint_event(event);
  53. GUI::Painter painter(*this);
  54. if (m_hovered)
  55. painter.draw_line({ 0, rect().bottom() }, { font().width(text()), rect().bottom() }, palette().link());
  56. if (is_focused())
  57. painter.draw_focus_rect(text_rect(), palette().focus_outline());
  58. }
  59. void LinkLabel::enter_event(Core::Event& event)
  60. {
  61. Label::enter_event(event);
  62. m_hovered = true;
  63. update();
  64. }
  65. void LinkLabel::leave_event(Core::Event& event)
  66. {
  67. Label::leave_event(event);
  68. m_hovered = false;
  69. update();
  70. }
  71. void LinkLabel::did_change_text()
  72. {
  73. Label::did_change_text();
  74. update_tooltip_if_needed();
  75. }
  76. void LinkLabel::update_tooltip_if_needed()
  77. {
  78. if (width() < font().width(text())) {
  79. set_tooltip(text());
  80. } else {
  81. set_tooltip({});
  82. }
  83. }
  84. void LinkLabel::resize_event(ResizeEvent& event)
  85. {
  86. Label::resize_event(event);
  87. update_tooltip_if_needed();
  88. }
  89. void LinkLabel::context_menu_event(ContextMenuEvent& event)
  90. {
  91. if (!m_context_menu) {
  92. m_context_menu = Menu::construct();
  93. m_context_menu->add_action(*m_open_action);
  94. m_context_menu->add_separator();
  95. m_context_menu->add_action(*m_copy_action);
  96. }
  97. m_context_menu->popup(event.screen_position(), m_open_action);
  98. }
  99. }