@@ -14,7 +14,7 @@ use std::{
1414} ;
1515
1616use clipboard:: { ClipboardContext , ClipboardProvider } ;
17- use egui:: { mutex:: Mutex , Color32 , OpenUrl , Ui , WidgetText } ;
17+ use egui:: { mutex:: Mutex , Color32 , Context , OpenUrl , Ui , WidgetText } ;
1818use egui_commonmark:: { CommonMarkCache , CommonMarkViewer } ;
1919use egui_dock:: { DockArea , DockState , Style , TabViewer } ;
2020use egui_extras:: { Size , StripBuilder } ;
@@ -46,7 +46,7 @@ use crate::{
4646 replay_parser:: { self , Replay , SharedReplayParserTabState } ,
4747 task:: { self , BackgroundTask , BackgroundTaskCompletion , BackgroundTaskKind } ,
4848 twitch:: { Token , TwitchState } ,
49- wows_data:: { load_replay, WorldOfWarshipsData } ,
49+ wows_data:: { load_replay, parse_replay , WorldOfWarshipsData } ,
5050} ;
5151
5252#[ macro_export]
@@ -948,6 +948,70 @@ impl WowsToolkitApp {
948948 }
949949 self . checked_for_updates = true ;
950950 }
951+
952+ fn ui_file_drag_and_drop ( & mut self , ctx : & Context ) {
953+ use egui:: { Align2 , Color32 , Id , LayerId , Order , TextStyle } ;
954+
955+ // Preview hovering files:
956+ if !ctx. input ( |i| i. raw . hovered_files . is_empty ( ) ) {
957+ let text = ctx. input ( |i| {
958+ if i. raw . hovered_files . len ( ) > 1 {
959+ return Some ( "Only one file at a time, please." . to_owned ( ) ) ;
960+ }
961+
962+ if let Some ( file) = i. raw . hovered_files . first ( ) {
963+ if let Some ( path) = & file. path {
964+ if path. is_file ( ) {
965+ return Some ( format ! ( "Drop to load\n {}" , path. file_name( ) ?. to_str( ) ?) ) ;
966+ }
967+ }
968+ }
969+
970+ None
971+ } ) ;
972+
973+ if let Some ( text) = text {
974+ let painter = ctx. layer_painter ( LayerId :: new ( Order :: Foreground , Id :: new ( "file_drop_target" ) ) ) ;
975+
976+ let screen_rect = ctx. screen_rect ( ) ;
977+ painter. rect_filled ( screen_rect, 0.0 , Color32 :: from_black_alpha ( 192 ) ) ;
978+ painter. text (
979+ screen_rect. center ( ) ,
980+ Align2 :: CENTER_CENTER ,
981+ text,
982+ TextStyle :: Heading . resolve ( & ctx. style ( ) ) ,
983+ Color32 :: WHITE ,
984+ ) ;
985+ }
986+ }
987+
988+ let mut dropped_files = Vec :: new ( ) ;
989+
990+ // Collect dropped files:
991+ ctx. input ( |i| {
992+ if !i. raw . dropped_files . is_empty ( ) {
993+ dropped_files. clone_from ( & i. raw . dropped_files ) ;
994+ }
995+ } ) ;
996+
997+ // Only perform operations if we have one file
998+ if dropped_files. len ( ) == 1 {
999+ if let Some ( path) = & dropped_files[ 0 ] . path {
1000+ if let Some ( wows_data) = self . tab_state . world_of_warships_data . as_ref ( ) {
1001+ self . tab_state . settings . current_replay_path = path. clone ( ) ;
1002+ println ! ( "Updating background task" ) ;
1003+ update_background_task ! (
1004+ self . tab_state. background_tasks,
1005+ parse_replay(
1006+ Arc :: clone( & self . tab_state. game_constants) ,
1007+ Arc :: clone( wows_data) ,
1008+ self . tab_state. settings. current_replay_path. clone( )
1009+ )
1010+ ) ;
1011+ }
1012+ }
1013+ }
1014+ }
9511015}
9521016
9531017impl eframe:: App for WowsToolkitApp {
@@ -1081,6 +1145,10 @@ impl eframe::App for WowsToolkitApp {
10811145 . enumerate ( )
10821146 . filter_map ( |( idx, viewer) | if !remove_viewers. contains ( & idx) { Some ( viewer) } else { None } )
10831147 . collect ( ) ;
1148+ drop ( file_viewer) ;
1149+
1150+ // Handle replay drag and drop events
1151+ self . ui_file_drag_and_drop ( ctx) ;
10841152 }
10851153}
10861154
0 commit comments