2020-12-21 14:00:29 +00:00
/*
* Copyright ( c ) 2020 , Alex McGrath < amk @ amk . ie >
2022-03-13 16:09:41 -06:00
* Copyright ( c ) 2022 , the SerenityOS developers .
2020-12-21 14:00:29 +00:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-12-21 14:00:29 +00:00
*/
2021-02-22 00:06:38 +02:00
# include <LibGUI/Action.h>
# include <LibGUI/Clipboard.h>
2020-12-21 14:00:29 +00:00
# include <LibGUI/Event.h>
2020-12-26 13:00:24 +01:00
# include <LibGUI/LinkLabel.h>
2021-02-22 00:06:38 +02:00
# include <LibGUI/Menu.h>
2020-12-21 14:00:29 +00:00
# include <LibGUI/Painter.h>
# include <LibGUI/Window.h>
2022-04-09 09:28:38 +02:00
# include <LibGfx/Font/Font.h>
2020-12-21 14:00:29 +00:00
# include <LibGfx/Palette.h>
2021-01-02 16:30:13 -07:00
REGISTER_WIDGET ( GUI , LinkLabel )
2020-12-21 14:00:29 +00:00
namespace GUI {
2023-04-29 10:41:48 -04:00
LinkLabel : : LinkLabel ( String text )
2020-12-26 13:07:02 +01:00
: Label ( move ( text ) )
2020-12-21 14:00:29 +00:00
{
set_foreground_role ( Gfx : : ColorRole : : Link ) ;
2020-12-26 15:34:49 +01:00
set_focus_policy ( FocusPolicy : : TabFocus ) ;
2021-02-22 00:06:38 +02:00
setup_actions ( ) ;
}
void LinkLabel : : setup_actions ( )
{
2023-02-22 10:32:59 +00:00
m_open_action = GUI : : Action : : create (
" Show in File Manager " , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/app-file-manager.png " sv ) . release_value_but_fixme_should_propagate_errors ( ) , [ & ] ( const GUI : : Action & ) {
if ( on_click )
on_click ( ) ;
} ,
this ) ;
2021-02-22 00:06:38 +02:00
m_copy_action = CommonActions : : make_copy_action ( [ this ] ( auto & ) { Clipboard : : the ( ) . set_plain_text ( text ( ) ) ; } , this ) ;
2020-12-21 14:00:29 +00:00
}
2021-10-21 19:36:04 +02:00
void LinkLabel : : set_hovered ( bool hover )
{
if ( hover = = m_hovered )
return ;
m_hovered = hover ;
set_override_cursor ( hover ? Gfx : : StandardCursor : : Hand : Gfx : : StandardCursor : : None ) ;
update ( ) ;
}
void LinkLabel : : mousemove_event ( MouseEvent & event )
{
2022-03-13 16:09:41 -06:00
constexpr int extra_target_width = 3 ;
2021-10-21 19:36:04 +02:00
set_hovered ( event . position ( ) . x ( ) < = font ( ) . width ( text ( ) ) + extra_target_width ) ;
}
2020-12-26 13:17:57 +01:00
void LinkLabel : : mousedown_event ( MouseEvent & event )
2020-12-21 14:00:29 +00:00
{
2021-10-27 13:20:27 +02:00
if ( event . button ( ) ! = MouseButton : : Primary )
2021-02-22 00:06:38 +02:00
return ;
2020-12-26 13:17:57 +01:00
Label : : mousedown_event ( event ) ;
2021-10-21 19:36:04 +02:00
if ( m_hovered & & on_click ) {
2020-12-21 14:00:29 +00:00
on_click ( ) ;
}
}
2020-12-26 15:34:49 +01:00
void LinkLabel : : keydown_event ( KeyEvent & event )
{
Label : : keydown_event ( event ) ;
if ( event . key ( ) = = KeyCode : : Key_Return | | event . key ( ) = = KeyCode : : Key_Space ) {
if ( on_click )
on_click ( ) ;
}
}
2020-12-26 13:00:24 +01:00
void LinkLabel : : paint_event ( PaintEvent & event )
2020-12-21 14:00:29 +00:00
{
Label : : paint_event ( event ) ;
GUI : : Painter painter ( * this ) ;
if ( m_hovered )
2023-04-14 08:52:47 -04:00
painter . draw_line ( { 0 , rect ( ) . bottom ( ) } , { font ( ) . width_rounded_up ( text ( ) ) , rect ( ) . bottom ( ) } , palette ( ) . link ( ) ) ;
2020-12-26 15:34:49 +01:00
if ( is_focused ( ) )
painter . draw_focus_rect ( text_rect ( ) , palette ( ) . focus_outline ( ) ) ;
2020-12-21 14:00:29 +00:00
}
2020-12-26 13:17:57 +01:00
void LinkLabel : : leave_event ( Core : : Event & event )
2020-12-21 14:00:29 +00:00
{
2020-12-26 13:17:57 +01:00
Label : : leave_event ( event ) ;
2021-10-21 19:36:04 +02:00
set_hovered ( false ) ;
2020-12-21 14:00:29 +00:00
}
2020-12-26 13:17:57 +01:00
void LinkLabel : : did_change_text ( )
2020-12-21 14:00:29 +00:00
{
2020-12-26 13:17:57 +01:00
Label : : did_change_text ( ) ;
update_tooltip_if_needed ( ) ;
2020-12-21 14:00:29 +00:00
}
2020-12-26 13:17:57 +01:00
void LinkLabel : : update_tooltip_if_needed ( )
2020-12-21 14:00:29 +00:00
{
2020-12-26 13:17:57 +01:00
if ( width ( ) < font ( ) . width ( text ( ) ) ) {
2023-04-29 10:41:48 -04:00
set_tooltip ( text ( ) . to_deprecated_string ( ) ) ;
2020-12-21 14:00:29 +00:00
} else {
set_tooltip ( { } ) ;
}
}
2020-12-26 13:17:57 +01:00
void LinkLabel : : resize_event ( ResizeEvent & event )
{
Label : : resize_event ( event ) ;
update_tooltip_if_needed ( ) ;
}
2021-02-22 00:06:38 +02:00
void LinkLabel : : context_menu_event ( ContextMenuEvent & event )
{
if ( ! m_context_menu ) {
m_context_menu = Menu : : construct ( ) ;
m_context_menu - > add_action ( * m_open_action ) ;
m_context_menu - > add_separator ( ) ;
m_context_menu - > add_action ( * m_copy_action ) ;
}
m_context_menu - > popup ( event . screen_position ( ) , m_open_action ) ;
}
2020-12-21 14:00:29 +00:00
}