2025-08-02 20:10:33 +03:00
# include "TextBoxEditTool.hpp"
# include "DrawingProgram.hpp"
# include "../MainProgram.hpp"
# include "../DrawData.hpp"
# include "Helpers/SCollision.hpp"
# include <cereal/types/vector.hpp>
2025-11-04 17:31:23 +03:00
# include <include/core/SkFontStyle.h>
2025-08-02 20:10:33 +03:00
# include <memory>
# include "EditTool.hpp"
TextBoxEditTool : : TextBoxEditTool ( DrawingProgram & initDrawP ) :
DrawingProgramEditToolBase ( initDrawP )
{ }
bool TextBoxEditTool : : edit_gui ( const std : : shared_ptr < DrawComponent > & comp ) {
std : : shared_ptr < DrawTextBox > a = std : : static_pointer_cast < DrawTextBox > ( comp ) ;
Toolbar & t = drawP . world . main . toolbar ;
t . gui . push_id ( " edit tool text " ) ;
t . gui . text_label_centered ( " Edit Text " ) ;
2025-11-04 17:31:23 +03:00
if ( t . gui . text_button_wide ( " Bold button " , " Bold " ) ) {
auto boldMod = std : : make_shared < WeightTextStyleModifier > ( ) ;
boldMod - > set_weight ( SkFontStyle : : kBold_Weight ) ;
a - > textBox - > set_text_style_modifier_between ( a - > cursor - > selectionBeginPos , a - > cursor - > selectionEndPos , boldMod ) ;
}
if ( t . gui . text_button_wide ( " Italic button " , " Italic " ) ) {
auto italicMod = std : : make_shared < SlantTextStyleModifier > ( ) ;
italicMod - > set_slant ( SkFontStyle : : Slant : : kItalic_Slant ) ;
a - > textBox - > set_text_style_modifier_between ( a - > cursor - > selectionBeginPos , a - > cursor - > selectionEndPos , italicMod ) ;
}
if ( t . gui . text_button_wide ( " Red button " , " Red " ) ) {
auto redMod = std : : make_shared < ColorTextStyleModifier > ( ) ;
redMod - > color = { 1.0f , 0.0f , 0.0f , 1.0f } ;
a - > textBox - > set_text_style_modifier_between ( a - > cursor - > selectionBeginPos , a - > cursor - > selectionEndPos , redMod ) ;
}
2025-11-04 19:04:09 +03:00
if ( t . gui . text_button_wide ( " Green button " , " Green " ) ) {
auto redMod = std : : make_shared < ColorTextStyleModifier > ( ) ;
redMod - > color = { 0.0f , 1.0f , 0.0f , 1.0f } ;
a - > textBox - > set_text_style_modifier_between ( a - > cursor - > selectionBeginPos , a - > cursor - > selectionEndPos , redMod ) ;
}
if ( t . gui . text_button_wide ( " Blue button " , " Blue " ) ) {
auto redMod = std : : make_shared < ColorTextStyleModifier > ( ) ;
redMod - > color = { 0.0f , 0.0f , 1.0f , 1.0f } ;
a - > textBox - > set_text_style_modifier_between ( a - > cursor - > selectionBeginPos , a - > cursor - > selectionEndPos , redMod ) ;
}
2025-10-25 17:31:55 +03:00
//t.gui.left_to_right_line_layout([&]() {
// CLAY({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(40), .height = CLAY_SIZING_FIXED(40)}}}) {
// if(t.gui.color_button("Text Color", &a->d.textColor, &a->d.textColor == t.colorRight))
// t.color_selector_right(&a->d.textColor == t.colorRight ? nullptr : &a->d.textColor);
// }
// t.gui.text_label("Text Color");
//});
2025-08-02 20:10:33 +03:00
t . gui . pop_id ( ) ;
2025-10-25 17:31:55 +03:00
2025-11-04 10:58:26 +03:00
return true ; // NOTE: In general, the update data should always be sent even if no changes were made, because we're sending the data over an unreliable channel.
2025-08-02 20:10:33 +03:00
}
void TextBoxEditTool : : commit_edit_updates ( const std : : shared_ptr < DrawComponent > & comp , std : : any & prevData ) {
std : : shared_ptr < DrawTextBox > a = std : : static_pointer_cast < DrawTextBox > ( comp ) ;
a - > d . editing = false ;
2025-10-25 17:31:55 +03:00
auto pData = std : : any_cast < TextBoxEditToolAllData > ( prevData ) ;
TextBoxEditToolAllData cData = get_all_data ( a ) ;
RichTextBox : : RichTextData richText = a - > textBox - > get_rich_text_data ( ) ;
2025-08-02 20:10:33 +03:00
drawP . world . undo . push ( UndoManager : : UndoRedoPair {
2025-10-25 17:31:55 +03:00
[ & drawP = drawP , a , pData ] ( ) {
a - > d = pData . textboxData ;
a - > textBox - > set_rich_text_data ( pData . richText ) ;
2025-08-02 20:10:33 +03:00
a - > d . editing = false ;
2025-10-01 08:59:44 +03:00
a - > client_send_update ( drawP , true ) ;
2025-08-02 20:10:33 +03:00
a - > commit_update ( drawP ) ;
return true ;
} ,
2025-10-25 17:31:55 +03:00
[ & drawP = drawP , a , cData ] ( ) {
a - > d = cData . textboxData ;
a - > textBox - > set_rich_text_data ( cData . richText ) ;
2025-08-02 20:10:33 +03:00
a - > d . editing = false ;
2025-10-01 08:59:44 +03:00
a - > client_send_update ( drawP , true ) ;
2025-08-02 20:10:33 +03:00
a - > commit_update ( drawP ) ;
return true ;
}
} ) ;
}
2025-10-25 17:31:55 +03:00
TextBoxEditTool : : TextBoxEditToolAllData TextBoxEditTool : : get_all_data ( const std : : shared_ptr < DrawTextBox > & a ) {
return {
. textboxData = a - > d ,
. richText = a - > textBox - > get_rich_text_data ( )
} ;
}
2025-08-02 20:10:33 +03:00
void TextBoxEditTool : : edit_start ( EditTool & editTool , const std : : shared_ptr < DrawComponent > & comp , std : : any & prevData ) {
std : : shared_ptr < DrawTextBox > a = std : : static_pointer_cast < DrawTextBox > ( comp ) ;
2025-10-20 17:30:36 +03:00
auto & cur = a - > cursor ;
2025-08-02 20:10:33 +03:00
auto & textbox = a - > textBox ;
2025-10-20 17:30:36 +03:00
cur = std : : make_shared < RichTextBox : : Cursor > ( ) ;
2025-08-02 20:10:33 +03:00
Vector2f textSelectPos = a - > get_mouse_pos ( drawP ) ;
2025-10-20 17:30:36 +03:00
textbox - > process_mouse_left_button ( * cur , textSelectPos , true , false , false ) ;
2025-11-04 10:58:26 +03:00
prevData = get_all_data ( a ) ;
2025-08-02 20:10:33 +03:00
a - > d . editing = true ;
2025-10-01 08:59:44 +03:00
a - > client_send_update ( drawP , false ) ;
2025-08-02 20:10:33 +03:00
editTool . add_point_handle ( { & a - > d . p1 , nullptr , & a - > d . p2 } ) ;
editTool . add_point_handle ( { & a - > d . p2 , & a - > d . p1 , nullptr } ) ;
}
bool TextBoxEditTool : : edit_update ( const std : : shared_ptr < DrawComponent > & comp ) {
std : : shared_ptr < DrawTextBox > a = std : : static_pointer_cast < DrawTextBox > ( comp ) ;
SCollision : : ColliderCollection < float > mousePointCollection ;
mousePointCollection . circle . emplace_back ( drawP . world . main . input . mouse . pos , 1.0f ) ;
mousePointCollection . recalculate_bounds ( ) ;
2025-10-20 17:30:36 +03:00
a - > textBox - > set_width ( std : : abs ( a - > d . p2 . x ( ) - a - > d . p1 . x ( ) ) ) ;
2025-08-02 20:10:33 +03:00
InputManager & input = drawP . world . main . input ;
2025-10-20 17:30:36 +03:00
bool collidesWithBox = a - > collides_with_cam_coords ( drawP . world . drawData . cam . c , mousePointCollection ) ;
2025-08-02 20:10:33 +03:00
2025-10-20 17:30:36 +03:00
input . text . set_rich_text_box_input ( a - > textBox , a - > cursor ) ;
a - > textBox - > process_mouse_left_button ( * a - > cursor , a - > get_mouse_pos ( drawP ) , drawP . controls . leftClick & & collidesWithBox , drawP . controls . leftClickHeld , input . key ( InputManager : : KEY_GENERIC_LSHIFT ) . held ) ;
2025-08-02 20:10:33 +03:00
return true ;
}