2020-01-18 09:38:21 +01:00
/*
* Copyright ( c ) 2018 - 2020 , Andreas Kling < kling @ serenityos . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* 1. Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2020-02-06 20:33:02 +01:00
# include <LibGUI/Action.h>
# include <LibGUI/ActionGroup.h>
# include <LibGUI/Application.h>
# include <LibGUI/Button.h>
# include <LibGUI/MenuItem.h>
2020-07-23 19:52:18 +02:00
# include <LibGUI/Window.h>
2019-02-12 14:09:48 +01:00
2020-02-02 15:07:41 +01:00
namespace GUI {
2019-09-14 22:10:44 +02:00
2020-02-02 15:07:41 +01:00
namespace CommonActions {
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_open_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Open... " , { Mod_Ctrl , Key_O } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/open.png " ) , move ( callback ) , parent ) ;
}
2019-09-20 19:36:39 +02:00
2020-05-27 16:53:57 +03:00
NonnullRefPtr < Action > make_save_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Save " , { Mod_Ctrl , Key_S } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/save.png " ) , move ( callback ) , parent ) ;
}
2020-08-25 01:06:11 +04:30
NonnullRefPtr < Action > make_save_as_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Save As... " , { Mod_Ctrl | Mod_Shift , Key_S } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/save.png " ) , move ( callback ) , parent ) ;
}
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_move_to_front_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Move to front " , { Mod_Ctrl | Mod_Shift , Key_Up } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/move-to-front.png " ) , move ( callback ) , parent ) ;
}
2019-09-14 22:42:02 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_move_to_back_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Move to back " , { Mod_Ctrl | Mod_Shift , Key_Down } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/move-to-back.png " ) , move ( callback ) , parent ) ;
}
2019-09-14 22:42:02 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_undo_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Undo " , { Mod_Ctrl , Key_Z } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/undo.png " ) , move ( callback ) , parent ) ;
}
2019-09-14 22:23:49 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_redo_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Redo " , { Mod_Ctrl , Key_Y } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/redo.png " ) , move ( callback ) , parent ) ;
}
2019-09-14 22:23:49 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_delete_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Delete " , { Mod_None , Key_Delete } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/delete.png " ) , move ( callback ) , parent ) ;
}
2019-09-14 22:10:44 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_cut_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
2020-04-24 20:37:57 +02:00
return Action : : create ( " Cut " , { Mod_Ctrl , Key_X } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/edit-cut.png " ) , move ( callback ) , parent ) ;
2020-04-21 17:19:27 +02:00
}
2019-09-01 15:28:07 -05:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_copy_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Copy " , { Mod_Ctrl , Key_C } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/edit-copy.png " ) , move ( callback ) , parent ) ;
}
2019-09-01 15:28:07 -05:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_paste_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
2020-08-24 07:02:03 -04:00
return Action : : create ( " Paste " , { Mod_Ctrl , Key_V } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/paste.png " ) , move ( callback ) , parent ) ;
2020-04-21 17:19:27 +02:00
}
2019-09-01 15:28:07 -05:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_fullscreen_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Fullscreen " , { Mod_None , Key_F11 } , move ( callback ) , parent ) ;
}
2019-09-16 18:42:38 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_quit_action ( Function < void ( Action & ) > callback )
{
return Action : : create ( " Quit " , { Mod_Alt , Key_F4 } , move ( callback ) ) ;
}
2019-09-14 22:10:44 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_go_back_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Go back " , { Mod_Alt , Key_Left } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/go-back.png " ) , move ( callback ) , parent ) ;
}
2019-10-05 09:21:55 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_go_forward_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Go forward " , { Mod_Alt , Key_Right } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/go-forward.png " ) , move ( callback ) , parent ) ;
}
2019-10-05 09:21:55 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_go_home_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Go home " , { Mod_Alt , Key_Home } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/go-home.png " ) , move ( callback ) , parent ) ;
}
2019-10-06 21:59:46 +02:00
2020-04-21 17:19:27 +02:00
NonnullRefPtr < Action > make_reload_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Reload " , { Mod_Ctrl , Key_R } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/reload.png " ) , move ( callback ) , parent ) ;
}
2019-10-05 10:14:09 +02:00
2020-07-03 20:54:38 +02:00
NonnullRefPtr < Action > make_select_all_action ( Function < void ( Action & ) > callback , Core : : Object * parent )
{
return Action : : create ( " Select all " , { Mod_Ctrl , Key_A } , Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/select-all.png " ) , move ( callback ) , parent ) ;
}
2019-09-01 15:28:07 -05:00
}
2020-04-21 17:19:27 +02:00
Action : : Action ( const StringView & text , Function < void ( Action & ) > on_activation_callback , Core : : Object * parent , bool checkable )
2020-02-02 12:34:39 +01:00
: Core : : Object ( parent )
2020-02-02 01:57:57 +01:00
, on_activation ( move ( on_activation_callback ) )
2019-02-20 02:39:46 +01:00
, m_text ( text )
2020-04-21 17:19:27 +02:00
, m_checkable ( checkable )
2019-02-12 14:09:48 +01:00
{
}
2020-04-21 17:19:27 +02:00
Action : : Action ( const StringView & text , RefPtr < Gfx : : Bitmap > & & icon , Function < void ( Action & ) > on_activation_callback , Core : : Object * parent , bool checkable )
2020-02-02 12:34:39 +01:00
: Core : : Object ( parent )
2020-02-02 01:57:57 +01:00
, on_activation ( move ( on_activation_callback ) )
2019-02-20 02:39:46 +01:00
, m_text ( text )
, m_icon ( move ( icon ) )
2020-04-21 17:19:27 +02:00
, m_checkable ( checkable )
2019-02-20 02:39:46 +01:00
{
}
2020-04-21 17:19:27 +02:00
Action : : Action ( const StringView & text , const Shortcut & shortcut , Function < void ( Action & ) > on_activation_callback , Core : : Object * parent , bool checkable )
: Action ( text , shortcut , nullptr , move ( on_activation_callback ) , parent , checkable )
2019-03-03 02:52:22 +01:00
{
}
2020-04-21 17:19:27 +02:00
Action : : Action ( const StringView & text , const Shortcut & shortcut , RefPtr < Gfx : : Bitmap > & & icon , Function < void ( Action & ) > on_activation_callback , Core : : Object * parent , bool checkable )
2020-02-02 12:34:39 +01:00
: Core : : Object ( parent )
2020-02-02 01:57:57 +01:00
, on_activation ( move ( on_activation_callback ) )
2019-03-02 10:04:49 +01:00
, m_text ( text )
, m_icon ( move ( icon ) )
, m_shortcut ( shortcut )
2020-04-21 17:19:27 +02:00
, m_checkable ( checkable )
2019-03-02 10:04:49 +01:00
{
2020-07-26 17:16:35 +02:00
if ( parent & & is < Widget > ( * parent ) ) {
2019-04-20 21:56:56 +02:00
m_scope = ShortcutScope : : WidgetLocal ;
2020-07-26 17:16:35 +02:00
} else if ( parent & & is < Window > ( * parent ) ) {
2020-02-02 01:57:57 +01:00
m_scope = ShortcutScope : : WindowLocal ;
2019-04-20 21:56:56 +02:00
} else {
m_scope = ShortcutScope : : ApplicationGlobal ;
2020-07-23 19:52:18 +02:00
if ( auto * app = Application : : the ( ) ) {
2020-07-04 16:52:01 +02:00
app - > register_global_shortcut_action ( { } , * this ) ;
2020-07-23 19:52:18 +02:00
}
2019-04-20 21:56:56 +02:00
}
2019-03-02 10:04:49 +01:00
}
2020-02-02 15:07:41 +01:00
Action : : ~ Action ( )
2019-02-12 14:09:48 +01:00
{
2020-07-04 16:52:01 +02:00
if ( m_shortcut . is_valid ( ) & & m_scope = = ShortcutScope : : ApplicationGlobal ) {
if ( auto * app = Application : : the ( ) )
app - > unregister_global_shortcut_action ( { } , * this ) ;
}
2019-02-12 14:09:48 +01:00
}
2020-02-02 15:07:41 +01:00
void Action : : activate ( Core : : Object * activator )
2019-02-12 14:09:48 +01:00
{
2020-04-21 17:19:27 +02:00
if ( ! on_activation )
return ;
2019-12-09 21:25:48 +01:00
if ( activator )
m_activator = activator - > make_weak_ptr ( ) ;
2020-04-21 17:19:27 +02:00
if ( is_checkable ( ) ) {
if ( m_action_group ) {
if ( m_action_group - > is_unchecking_allowed ( ) )
set_checked ( ! is_checked ( ) ) ;
else
set_checked ( true ) ;
} else {
set_checked ( ! is_checked ( ) ) ;
}
}
on_activation ( * this ) ;
2019-12-09 21:25:48 +01:00
m_activator = nullptr ;
2019-02-12 14:09:48 +01:00
}
2019-04-12 02:53:27 +02:00
2020-02-02 15:07:41 +01:00
void Action : : register_button ( Badge < Button > , Button & button )
2019-04-12 02:53:27 +02:00
{
m_buttons . set ( & button ) ;
}
2020-02-02 15:07:41 +01:00
void Action : : unregister_button ( Badge < Button > , Button & button )
2019-04-12 02:53:27 +02:00
{
m_buttons . remove ( & button ) ;
}
2020-02-02 15:07:41 +01:00
void Action : : register_menu_item ( Badge < MenuItem > , MenuItem & menu_item )
2019-04-12 02:53:27 +02:00
{
m_menu_items . set ( & menu_item ) ;
}
2020-02-02 15:07:41 +01:00
void Action : : unregister_menu_item ( Badge < MenuItem > , MenuItem & menu_item )
2019-04-12 02:53:27 +02:00
{
m_menu_items . remove ( & menu_item ) ;
}
template < typename Callback >
2020-02-02 15:07:41 +01:00
void Action : : for_each_toolbar_button ( Callback callback )
2019-04-12 02:53:27 +02:00
{
for ( auto & it : m_buttons )
callback ( * it ) ;
}
template < typename Callback >
2020-02-02 15:07:41 +01:00
void Action : : for_each_menu_item ( Callback callback )
2019-04-12 02:53:27 +02:00
{
for ( auto & it : m_menu_items )
callback ( * it ) ;
}
2020-02-02 15:07:41 +01:00
void Action : : set_enabled ( bool enabled )
2019-04-12 02:53:27 +02:00
{
if ( m_enabled = = enabled )
return ;
m_enabled = enabled ;
2020-02-02 15:07:41 +01:00
for_each_toolbar_button ( [ enabled ] ( auto & button ) {
2019-04-12 02:53:27 +02:00
button . set_enabled ( enabled ) ;
} ) ;
2020-02-02 15:07:41 +01:00
for_each_menu_item ( [ enabled ] ( auto & item ) {
2019-04-12 02:53:27 +02:00
item . set_enabled ( enabled ) ;
} ) ;
}
2019-04-26 21:09:56 +02:00
2020-02-02 15:07:41 +01:00
void Action : : set_checked ( bool checked )
2019-04-26 21:09:56 +02:00
{
if ( m_checked = = checked )
return ;
m_checked = checked ;
2019-07-09 22:10:03 +02:00
if ( m_checked & & m_action_group ) {
m_action_group - > for_each_action ( [ this ] ( auto & other_action ) {
if ( this = = & other_action )
return IterationDecision : : Continue ;
if ( other_action . is_checkable ( ) )
other_action . set_checked ( false ) ;
return IterationDecision : : Continue ;
} ) ;
}
2020-02-02 15:07:41 +01:00
for_each_toolbar_button ( [ checked ] ( auto & button ) {
2019-04-26 21:09:56 +02:00
button . set_checked ( checked ) ;
} ) ;
2020-02-02 15:07:41 +01:00
for_each_menu_item ( [ checked ] ( MenuItem & item ) {
2019-04-26 21:09:56 +02:00
item . set_checked ( checked ) ;
} ) ;
}
2019-07-09 22:10:03 +02:00
2020-02-02 15:07:41 +01:00
void Action : : set_group ( Badge < ActionGroup > , ActionGroup * group )
2019-07-09 22:10:03 +02:00
{
m_action_group = group ? group - > make_weak_ptr ( ) : nullptr ;
}
2020-02-02 15:07:41 +01:00
2020-02-14 23:02:47 +01:00
void Action : : set_icon ( const Gfx : : Bitmap * icon )
{
m_icon = icon ;
}
2020-02-02 15:07:41 +01:00
}