CI-Build 2022-08-01
This commit is contained in:
commit
4e8c02d38f
28 changed files with 1300 additions and 11 deletions
541
CMakeLists.txt
Normal file
541
CMakeLists.txt
Normal file
|
@ -0,0 +1,541 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
project(Aegisub)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include_directories("build")
|
||||
include_directories("libaegisub/include")
|
||||
include_directories("vendor/luajit/include")
|
||||
|
||||
add_library(libaegisub STATIC
|
||||
libaegisub/common/parser.cpp
|
||||
libaegisub/ass/dialogue_parser.cpp
|
||||
libaegisub/ass/time.cpp
|
||||
libaegisub/ass/uuencode.cpp
|
||||
libaegisub/audio/provider.cpp
|
||||
libaegisub/audio/provider_convert.cpp
|
||||
libaegisub/audio/provider_dummy.cpp
|
||||
libaegisub/audio/provider_hd.cpp
|
||||
libaegisub/audio/provider_lock.cpp
|
||||
libaegisub/audio/provider_pcm.cpp
|
||||
libaegisub/audio/provider_ram.cpp
|
||||
libaegisub/common/cajun/elements.cpp
|
||||
libaegisub/common/cajun/reader.cpp
|
||||
libaegisub/common/cajun/writer.cpp
|
||||
libaegisub/lua/modules/lfs.cpp
|
||||
libaegisub/lua/modules/re.cpp
|
||||
libaegisub/lua/modules/unicode.cpp
|
||||
libaegisub/lua/modules/lpeg.c
|
||||
libaegisub/lua/modules.cpp
|
||||
libaegisub/lua/script_reader.cpp
|
||||
libaegisub/lua/utils.cpp
|
||||
libaegisub/common/calltip_provider.cpp
|
||||
libaegisub/common/character_count.cpp
|
||||
libaegisub/common/charset.cpp
|
||||
libaegisub/common/charset_6937.cpp
|
||||
libaegisub/common/charset_conv.cpp
|
||||
libaegisub/common/color.cpp
|
||||
libaegisub/common/file_mapping.cpp
|
||||
libaegisub/common/format.cpp
|
||||
libaegisub/common/fs.cpp
|
||||
libaegisub/common/hotkey.cpp
|
||||
libaegisub/common/io.cpp
|
||||
libaegisub/common/json.cpp
|
||||
libaegisub/common/kana_table.cpp
|
||||
libaegisub/common/karaoke_matcher.cpp
|
||||
libaegisub/common/keyframe.cpp
|
||||
libaegisub/common/line_iterator.cpp
|
||||
libaegisub/common/log.cpp
|
||||
libaegisub/common/mru.cpp
|
||||
libaegisub/common/option.cpp
|
||||
libaegisub/common/option_value.cpp
|
||||
libaegisub/common/path.cpp
|
||||
libaegisub/common/thesaurus.cpp
|
||||
libaegisub/common/util.cpp
|
||||
libaegisub/common/vfr.cpp
|
||||
libaegisub/common/ycbcr_conv.cpp
|
||||
libaegisub/common/dispatch.cpp
|
||||
)
|
||||
if (UNIX)
|
||||
target_sources(libaegisub PRIVATE
|
||||
libaegisub/unix/access.cpp
|
||||
libaegisub/unix/fs.cpp
|
||||
libaegisub/unix/log.cpp
|
||||
libaegisub/unix/path.cpp
|
||||
libaegisub/unix/util.cpp
|
||||
)
|
||||
elseif(WIN32)
|
||||
target_sources(libaegisub PRIVATE
|
||||
libaegisub/windows/access.cpp
|
||||
libaegisub/windows/charset_conv_win.cpp
|
||||
libaegisub/windows/fs.cpp
|
||||
libaegisub/windows/lagi_pre.cpp
|
||||
libaegisub/windows/log_win.cpp
|
||||
libaegisub/windows/path_win.cpp
|
||||
libaegisub/windows/util_win.cpp
|
||||
)
|
||||
endif(UNIX)
|
||||
SET_TARGET_PROPERTIES(libaegisub PROPERTIES PREFIX "")
|
||||
|
||||
add_library(luabins STATIC
|
||||
vendor/luabins/src/fwrite.c
|
||||
vendor/luabins/src/load.c
|
||||
vendor/luabins/src/luabins.c
|
||||
vendor/luabins/src/luainternals.c
|
||||
vendor/luabins/src/save.c
|
||||
vendor/luabins/src/savebuffer.c
|
||||
vendor/luabins/src/write.c
|
||||
)
|
||||
|
||||
add_executable(luajit-minilua vendor/luajit/src/host/minilua.c)
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(luajit-minilua m)
|
||||
endif(NOT MSVC)
|
||||
add_custom_command(TARGET luajit-minilua POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vendor/luajit/src/gen
|
||||
COMMAND luajit-minilua ../dynasm/dynasm.lua -D P64 -D JIT -D FFI -D FPU -D HFABI -D VER= -o gen/buildvm_arch.h vm_x86.dasc
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
add_custom_command(TARGET luajit-minilua POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_win.json ${PROJECT_SOURCE_DIR}/src/libresrc/default_config_platform.json
|
||||
COMMAND luajit-minilua ../../tools/respack.lua manifest.respack default_config.cpp default_config.h
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/libresrc
|
||||
BYPRODUCTS ${PROJECT_SOURCE_DIR}/src/libresrc/default_config.cpp ${PROJECT_SOURCE_DIR}/src/libresrc/default_config.h
|
||||
)
|
||||
add_custom_command(TARGET luajit-minilua POST_BUILD
|
||||
COMMAND luajit-minilua ../../tools/respack.lua manifest.respack ../libresrc/bitmap.cpp ../libresrc/bitmap.h
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bitmaps
|
||||
BYPRODUCTS ${PROJECT_SOURCE_DIR}/src/libresrc/bitmap.cpp ${PROJECT_SOURCE_DIR}/src/libresrc/bitmap.h
|
||||
)
|
||||
|
||||
add_executable(luajit-buildvm
|
||||
vendor/luajit/src/host/buildvm.c
|
||||
vendor/luajit/src/host/buildvm_asm.c
|
||||
vendor/luajit/src/host/buildvm_peobj.c
|
||||
vendor/luajit/src/host/buildvm_lib.c
|
||||
vendor/luajit/src/host/buildvm_fold.c
|
||||
)
|
||||
target_include_directories(luajit-buildvm PRIVATE vendor/luajit/src vendor/luajit/src/gen)
|
||||
add_dependencies(luajit-buildvm luajit-minilua)
|
||||
if(UNIX)
|
||||
add_custom_command(TARGET luajit-buildvm POST_BUILD
|
||||
COMMAND luajit-buildvm -m elfasm -o lj_vm.s
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
BYPRODUCTS ${PROJECT_SOURCE_DIR}/vendor/luajit/src/lj_vm.s
|
||||
)
|
||||
set_property(SOURCE vendor/luajit/src/lj_vm.s PROPERTY LANGUAGE C)
|
||||
elseif(MSVC)
|
||||
add_custom_command(TARGET luajit-buildvm POST_BUILD
|
||||
COMMAND luajit-buildvm -m peobj -o lj_vm.obj
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
BYPRODUCTS ${PROJECT_SOURCE_DIR}/vendor/luajit/src/lj_vm.obj
|
||||
)
|
||||
endif(UNIX)
|
||||
add_custom_command(TARGET luajit-buildvm POST_BUILD
|
||||
COMMAND luajit-buildvm -m ffdef -o gen/lj_ffdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
COMMAND luajit-buildvm -m bcdef -o gen/lj_bcdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
COMMAND luajit-buildvm -m folddef -o gen/lj_folddef.h lj_opt_fold.c
|
||||
COMMAND luajit-buildvm -m recdef -o gen/lj_recdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
COMMAND luajit-buildvm -m libdef -o gen/lj_libdef.h lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
COMMAND luajit-buildvm -m vmdef -o jit/vmdef.lua lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vendor/luajit/src
|
||||
)
|
||||
|
||||
|
||||
add_library(luajit STATIC
|
||||
vendor/luajit/src/lj_gc.c
|
||||
vendor/luajit/src/lj_err.c
|
||||
vendor/luajit/src/lj_char.c
|
||||
vendor/luajit/src/lj_bc.c
|
||||
vendor/luajit/src/lj_obj.c
|
||||
vendor/luajit/src/lj_str.c
|
||||
vendor/luajit/src/lj_tab.c
|
||||
vendor/luajit/src/lj_func.c
|
||||
vendor/luajit/src/lj_udata.c
|
||||
vendor/luajit/src/lj_meta.c
|
||||
vendor/luajit/src/lj_debug.c
|
||||
vendor/luajit/src/lj_state.c
|
||||
vendor/luajit/src/lj_dispatch.c
|
||||
vendor/luajit/src/lj_vmevent.c
|
||||
vendor/luajit/src/lj_vmmath.c
|
||||
vendor/luajit/src/lj_strscan.c
|
||||
vendor/luajit/src/lj_api.c
|
||||
vendor/luajit/src/lj_lex.c
|
||||
vendor/luajit/src/lj_parse.c
|
||||
vendor/luajit/src/lj_bcread.c
|
||||
vendor/luajit/src/lj_bcwrite.c
|
||||
vendor/luajit/src/lj_load.c
|
||||
vendor/luajit/src/lj_ir.c
|
||||
vendor/luajit/src/lj_opt_mem.c
|
||||
vendor/luajit/src/lj_opt_fold.c
|
||||
vendor/luajit/src/lj_opt_narrow.c
|
||||
vendor/luajit/src/lj_opt_dce.c
|
||||
vendor/luajit/src/lj_opt_loop.c
|
||||
vendor/luajit/src/lj_opt_split.c
|
||||
vendor/luajit/src/lj_opt_sink.c
|
||||
vendor/luajit/src/lj_mcode.c
|
||||
vendor/luajit/src/lj_snap.c
|
||||
vendor/luajit/src/lj_record.c
|
||||
vendor/luajit/src/lj_crecord.c
|
||||
vendor/luajit/src/lj_ffrecord.c
|
||||
vendor/luajit/src/lj_asm.c
|
||||
vendor/luajit/src/lj_trace.c
|
||||
vendor/luajit/src/lj_gdbjit.c
|
||||
vendor/luajit/src/lj_ctype.c
|
||||
vendor/luajit/src/lj_cdata.c
|
||||
vendor/luajit/src/lj_cconv.c
|
||||
vendor/luajit/src/lj_ccall.c
|
||||
vendor/luajit/src/lj_ccallback.c
|
||||
vendor/luajit/src/lj_carith.c
|
||||
vendor/luajit/src/lj_clib.c
|
||||
vendor/luajit/src/lj_cparse.c
|
||||
vendor/luajit/src/lj_lib.c
|
||||
vendor/luajit/src/lj_alloc.c
|
||||
vendor/luajit/src/lib_aux.c
|
||||
vendor/luajit/src/lib_base.c
|
||||
vendor/luajit/src/lib_math.c
|
||||
vendor/luajit/src/lib_bit.c
|
||||
vendor/luajit/src/lib_string.c
|
||||
vendor/luajit/src/lib_table.c
|
||||
vendor/luajit/src/lib_io.c
|
||||
vendor/luajit/src/lib_os.c
|
||||
vendor/luajit/src/lib_package.c
|
||||
vendor/luajit/src/lib_debug.c
|
||||
vendor/luajit/src/lib_jit.c
|
||||
vendor/luajit/src/lib_ffi.c
|
||||
vendor/luajit/src/lib_init.c
|
||||
)
|
||||
if(MSVC)
|
||||
target_sources(luajit PRIVATE vendor/luajit/src/lj_vm.obj)
|
||||
else(MSVC)
|
||||
target_sources(luajit PRIVATE vendor/luajit/src/lj_vm.s)
|
||||
set_property(SOURCE vendor/luajit/src/lj_vm.s PROPERTY LANGUAGE C)
|
||||
target_link_libraries(luajit dl)
|
||||
endif(MSVC)
|
||||
target_include_directories(luajit PRIVATE vendor/luajit/src/gen)
|
||||
add_dependencies(luajit luajit-buildvm)
|
||||
target_compile_definitions(luajit PRIVATE LUAJIT_ENABLE_LUA52COMPAT)
|
||||
|
||||
add_library(resrc STATIC
|
||||
src/libresrc/bitmap.cpp
|
||||
src/libresrc/default_config.cpp
|
||||
src/libresrc/libresrc.cpp
|
||||
)
|
||||
add_dependencies(resrc luajit-minilua)
|
||||
|
||||
add_library(csri STATIC
|
||||
vendor/csri/lib/list.c
|
||||
vendor/csri/lib/wrap.c
|
||||
vendor/csri/subhelp/logging.c
|
||||
)
|
||||
target_include_directories(csri PRIVATE "vendor/csri/include")
|
||||
IF (WIN32)
|
||||
target_include_directories(csri PRIVATE "vendor/csri/lib/win32")
|
||||
target_sources(csri PRIVATE vendor/csri/lib/win32/enumerate.c)
|
||||
ELSE()
|
||||
target_include_directories(csri PRIVATE "vendor/csri/lib/posix")
|
||||
target_sources(csri PRIVATE vendor/csri/lib/posix/enumerate.c)
|
||||
ENDIF()
|
||||
|
||||
add_executable(Aegisub WIN32
|
||||
src/command/app.cpp
|
||||
src/command/audio.cpp
|
||||
src/command/automation.cpp
|
||||
src/command/command.cpp
|
||||
src/command/edit.cpp
|
||||
src/command/grid.cpp
|
||||
src/command/help.cpp
|
||||
src/command/keyframe.cpp
|
||||
src/command/recent.cpp
|
||||
src/command/subtitle.cpp
|
||||
src/command/time.cpp
|
||||
src/command/timecode.cpp
|
||||
src/command/tool.cpp
|
||||
src/command/video.cpp
|
||||
src/command/vis_tool.cpp
|
||||
src/dialog_about.cpp
|
||||
src/dialog_align.cpp
|
||||
src/dialog_attachments.cpp
|
||||
src/dialog_automation.cpp
|
||||
src/dialog_autosave.cpp
|
||||
src/dialog_colorpicker.cpp
|
||||
src/dialog_detached_video.cpp
|
||||
src/dialog_dummy_video.cpp
|
||||
src/dialog_export.cpp
|
||||
src/dialog_export_ebu3264.cpp
|
||||
src/dialog_fonts_collector.cpp
|
||||
src/dialog_jumpto.cpp
|
||||
src/dialog_kara_timing_copy.cpp
|
||||
src/dialog_log.cpp
|
||||
src/dialog_paste_over.cpp
|
||||
src/dialog_progress.cpp
|
||||
src/dialog_properties.cpp
|
||||
src/dialog_resample.cpp
|
||||
src/dialog_search_replace.cpp
|
||||
src/dialog_selected_choices.cpp
|
||||
src/dialog_selection.cpp
|
||||
src/dialog_shift_times.cpp
|
||||
src/dialog_spellchecker.cpp
|
||||
src/dialog_style_editor.cpp
|
||||
src/dialog_style_manager.cpp
|
||||
src/dialog_styling_assistant.cpp
|
||||
src/dialog_text_import.cpp
|
||||
src/dialog_timing_processor.cpp
|
||||
src/dialog_translation.cpp
|
||||
src/dialog_version_check.cpp
|
||||
src/dialog_video_details.cpp
|
||||
src/dialog_video_properties.cpp
|
||||
src/subtitle_format.cpp
|
||||
src/subtitle_format_ass.cpp
|
||||
src/subtitle_format_ebu3264.cpp
|
||||
src/subtitle_format_encore.cpp
|
||||
src/subtitle_format_microdvd.cpp
|
||||
src/subtitle_format_mkv.cpp
|
||||
src/subtitle_format_srt.cpp
|
||||
src/subtitle_format_ssa.cpp
|
||||
src/subtitle_format_transtation.cpp
|
||||
src/subtitle_format_ttxt.cpp
|
||||
src/subtitle_format_txt.cpp
|
||||
src/visual_tool.cpp
|
||||
src/visual_tool_clip.cpp
|
||||
src/visual_tool_cross.cpp
|
||||
src/visual_tool_drag.cpp
|
||||
src/visual_tool_rotatexy.cpp
|
||||
src/visual_tool_rotatez.cpp
|
||||
src/visual_tool_scale.cpp
|
||||
src/visual_tool_vector_clip.cpp
|
||||
src/MatroskaParser.c
|
||||
src/aegisublocale.cpp
|
||||
src/ass_attachment.cpp
|
||||
src/ass_dialogue.cpp
|
||||
src/ass_entry.cpp
|
||||
src/ass_export_filter.cpp
|
||||
src/ass_exporter.cpp
|
||||
src/ass_file.cpp
|
||||
src/ass_karaoke.cpp
|
||||
src/ass_override.cpp
|
||||
src/ass_parser.cpp
|
||||
src/ass_style.cpp
|
||||
src/ass_style_storage.cpp
|
||||
src/async_video_provider.cpp
|
||||
src/audio_box.cpp
|
||||
src/audio_colorscheme.cpp
|
||||
src/audio_controller.cpp
|
||||
src/audio_display.cpp
|
||||
src/audio_karaoke.cpp
|
||||
src/audio_marker.cpp
|
||||
src/audio_player.cpp
|
||||
src/audio_provider_factory.cpp
|
||||
src/audio_renderer.cpp
|
||||
src/audio_renderer_spectrum.cpp
|
||||
src/audio_renderer_waveform.cpp
|
||||
src/audio_timing_dialogue.cpp
|
||||
src/audio_timing_karaoke.cpp
|
||||
src/auto4_base.cpp
|
||||
src/auto4_lua.cpp
|
||||
src/auto4_lua_assfile.cpp
|
||||
src/auto4_lua_dialog.cpp
|
||||
src/auto4_lua_progresssink.cpp
|
||||
src/base_grid.cpp
|
||||
src/charset_detect.cpp
|
||||
src/colorspace.cpp
|
||||
src/colour_button.cpp
|
||||
src/compat.cpp
|
||||
src/context.cpp
|
||||
src/export_fixstyle.cpp
|
||||
src/export_framerate.cpp
|
||||
src/fft.cpp
|
||||
src/font_file_lister.cpp
|
||||
src/frame_main.cpp
|
||||
src/gl_text.cpp
|
||||
src/gl_wrap.cpp
|
||||
src/grid_column.cpp
|
||||
src/help_button.cpp
|
||||
src/hotkey.cpp
|
||||
src/hotkey_data_view_model.cpp
|
||||
src/image_position_picker.cpp
|
||||
src/initial_line_state.cpp
|
||||
src/main.cpp
|
||||
src/menu.cpp
|
||||
src/mkv_wrap.cpp
|
||||
src/pen.cpp
|
||||
src/persist_location.cpp
|
||||
src/preferences.cpp
|
||||
src/preferences_base.cpp
|
||||
src/project.cpp
|
||||
src/resolution_resampler.cpp
|
||||
src/search_replace_engine.cpp
|
||||
src/selection_controller.cpp
|
||||
src/spellchecker.cpp
|
||||
src/spline.cpp
|
||||
src/spline_curve.cpp
|
||||
src/string_codec.cpp
|
||||
src/subs_controller.cpp
|
||||
src/subs_edit_box.cpp
|
||||
src/subs_edit_ctrl.cpp
|
||||
src/subs_preview.cpp
|
||||
src/subtitles_provider.cpp
|
||||
src/subtitles_provider_libass.cpp
|
||||
src/text_file_reader.cpp
|
||||
src/text_file_writer.cpp
|
||||
src/text_selection_controller.cpp
|
||||
src/thesaurus.cpp
|
||||
src/timeedit_ctrl.cpp
|
||||
src/toggle_bitmap.cpp
|
||||
src/toolbar.cpp
|
||||
src/tooltip_manager.cpp
|
||||
src/utils.cpp
|
||||
src/validators.cpp
|
||||
src/vector2d.cpp
|
||||
src/version.cpp
|
||||
src/video_box.cpp
|
||||
src/video_controller.cpp
|
||||
src/video_display.cpp
|
||||
src/video_frame.cpp
|
||||
src/video_out_gl.cpp
|
||||
src/video_provider_cache.cpp
|
||||
src/video_provider_dummy.cpp
|
||||
src/video_provider_manager.cpp
|
||||
src/video_provider_yuv4mpeg.cpp
|
||||
src/video_slider.cpp
|
||||
src/visual_feature.cpp
|
||||
)
|
||||
target_link_libraries(Aegisub ${CMAKE_DL_LIBS} libaegisub luabins luajit resrc csri)
|
||||
|
||||
if (MSVC)
|
||||
set_target_properties(libaegisub PROPERTIES COMPILE_FLAGS "/Yu${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h" COMPILE_FLAGS "/FI${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h")
|
||||
else(MSVC)
|
||||
target_compile_options(libaegisub PRIVATE -include "${PROJECT_SOURCE_DIR}/libaegisub/lagi_pre.h")
|
||||
endif(MSVC)
|
||||
|
||||
set_property(
|
||||
SOURCE libaegisub/unix/path.cpp
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
P_DATA="${CMAKE_INSTALL_PREFIX}/share/aegisub/"
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_definitions("-DNOMINMAX -MP -DINITGUID")
|
||||
set_target_properties(Aegisub PROPERTIES COMPILE_FLAGS "/Yu${PROJECT_SOURCE_DIR}/src/agi_pre.h" COMPILE_FLAGS "/FI${PROJECT_SOURCE_DIR}/src/agi_pre.h")
|
||||
target_link_libraries (Aegisub Usp10)
|
||||
#target_sources(Aegisub PRIVATE src/res/res.rc src/res/strings.rc src/crash_writer_minidump.cpp)
|
||||
target_sources(Aegisub PRIVATE src/res/res.rc src/res/strings.rc src/crash_writer.cpp src/dpi_aware.manifest)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Aegisub)
|
||||
else(MSVC)
|
||||
target_sources(Aegisub PRIVATE src/crash_writer.cpp)
|
||||
target_compile_options(Aegisub PRIVATE -include "${PROJECT_SOURCE_DIR}/src/agi_pre.h")
|
||||
endif(MSVC)
|
||||
|
||||
if (WIN32)
|
||||
target_sources(Aegisub PRIVATE src/font_file_lister_gdi.cpp)
|
||||
else (WIN32)
|
||||
find_package(Fontconfig REQUIRED)
|
||||
target_link_libraries (Aegisub ${Fontconfig_LIBRARIES})
|
||||
target_sources(Aegisub PRIVATE src/font_file_lister_fontconfig.cpp)
|
||||
set_property(SOURCE src/font_file_lister_fontconfig.cpp PROPERTY INCLUDE_DIRECTORIES "${Fontconfig_INCLUDE_DIRS}")
|
||||
endif (WIN32)
|
||||
|
||||
find_package(ass REQUIRED)
|
||||
include_directories(${ass_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${ass_LIBRARIES})
|
||||
|
||||
find_package(Boost REQUIRED chrono filesystem locale regex system thread)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_directories(Aegisub PRIVATE ${Boost_LIBRARY_DIRS})
|
||||
target_link_libraries(Aegisub ${Boost_LIBRARIES})
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
target_link_libraries (Aegisub ${OPENGL_LIBRARIES})
|
||||
|
||||
find_package(Hunspell REQUIRED)
|
||||
include_directories(${HUNSPELL_INCLUDE_DIR})
|
||||
target_link_libraries (Aegisub ${HUNSPELL_LIBRARIES})
|
||||
add_definitions("-DWITH_HUNSPELL")
|
||||
target_sources(Aegisub PRIVATE src/spellchecker_hunspell.cpp)
|
||||
|
||||
find_package(Iconv REQUIRED)
|
||||
include_directories(${Iconv_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${Iconv_LIBRARIES})
|
||||
add_definitions("-DHAVE_ICONV")
|
||||
if (NOT Iconv_IS_BUILT_IN)
|
||||
set_property(
|
||||
SOURCE libaegisub/common/charset_conv.cpp
|
||||
PROPERTY COMPILE_DEFINITIONS AGI_ICONV_CONST
|
||||
)
|
||||
endif (NOT Iconv_IS_BUILT_IN)
|
||||
|
||||
find_package(ICU REQUIRED uc dt in)
|
||||
include_directories(${ICU_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${ICU_LIBRARIES})
|
||||
|
||||
find_package(wxWidgets REQUIRED adv base core gl stc xml)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
target_link_libraries(Aegisub ${wxWidgets_LIBRARIES})
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${ZLIB_LIBRARIES})
|
||||
|
||||
find_package(ALSA)
|
||||
if (ALSA_FOUND)
|
||||
include_directories(${ALSA_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${ALSA_LIBRARIES})
|
||||
add_definitions("-DWITH_ALSA")
|
||||
target_sources(Aegisub PRIVATE src/audio_player_alsa.cpp)
|
||||
endif(ALSA_FOUND)
|
||||
|
||||
# target_compile_definitions(Aegisub PRIVATE "WITH_AVISYNTH")
|
||||
# target_sources(Aegisub PRIVATE src/audio_provider_avs.cpp src/avisynth_wrap.cpp src/video_provider_avs.cpp)
|
||||
|
||||
target_compile_definitions(Aegisub PRIVATE "WITH_CSRI")
|
||||
target_sources(Aegisub PRIVATE src/subtitles_provider_csri.cpp)
|
||||
set_property(SOURCE src/subtitles_provider_csri.cpp PROPERTY INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/vendor/csri/include")
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries (Aegisub dsound)
|
||||
add_definitions("-DWITH_DIRECTSOUND")
|
||||
target_sources(Aegisub PRIVATE src/audio_player_dsound.cpp src/audio_player_dsound2.cpp)
|
||||
endif(MSVC)
|
||||
|
||||
find_package(FFMS2)
|
||||
if (FFMS2_FOUND)
|
||||
include_directories(${FFMS2_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${FFMS2_LIBRARIES})
|
||||
add_definitions("-DWITH_FFMS2")
|
||||
target_sources(Aegisub PRIVATE src/audio_provider_ffmpegsource.cpp src/ffmpegsource_common.cpp src/video_provider_ffmpegsource.cpp)
|
||||
endif(FFMS2_FOUND)
|
||||
|
||||
find_package(FFTW)
|
||||
if (FFTW_FOUND)
|
||||
include_directories(${FFTW_INCLUDES})
|
||||
target_link_libraries (Aegisub ${FFTW_LIBRARIES})
|
||||
add_definitions("-DWITH_FFTW3")
|
||||
endif(FFTW_FOUND)
|
||||
|
||||
#ifdef WITH_LIBPULSE
|
||||
#add_definitions("-DWITH_LIBPULSE")
|
||||
#target_sources(Aegisub PRIVATE src/audio_player_pulse.cpp)
|
||||
|
||||
find_package(OpenAL)
|
||||
if (OPENAL_FOUND)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries (Aegisub ${OPENAL_LIBRARY})
|
||||
add_definitions("-DWITH_OPENAL")
|
||||
target_sources(Aegisub PRIVATE src/audio_player_openal.cpp)
|
||||
endif(OPENAL_FOUND)
|
||||
|
||||
#ifdef WITH_OSS
|
||||
#ifdef WITH_PORTAUDIO
|
||||
#ifdef WITH_STARTUPLOG
|
||||
|
||||
find_package(uchardet)
|
||||
if (uchardet_FOUND)
|
||||
include_directories(${uchardet_INCLUDE_DIRS})
|
||||
target_link_libraries (Aegisub ${uchardet_LIBRARIES})
|
||||
add_definitions("-DWITH_UCHARDET")
|
||||
endif(uchardet_FOUND)
|
||||
|
||||
#ifdef WITH_UPDATE_CHECKER
|
|
@ -20,13 +20,15 @@ The `cibuilds` branch makes some CI builds of snapshots of `feature` at relevant
|
|||
|
||||
### Branch/Feature list
|
||||
- [`folding`](https://github.com/arch1t3cht/Aegisub/tree/folding): Add the ability to visually group and collapse lines in the subtitle grid
|
||||
- [`lua_api`](https://github.com/arch1t3cht/Aegisub/tree/lua_api): Add new functions to the Lua automation API, like controlling the selection or cursor in the text edit box
|
||||
- [`vector_clip_actions`](https://github.com/arch1t3cht/Aegisub/tree/vector_clip_actions): Make the different modes of the vector clip tool (lines, bezier curves, adding points, etc) bindable to hotkeys
|
||||
- [`color_picker_fix2`](https://github.com/arch1t3cht/Aegisub/tree/color_picker_fix2): Add an option (under "Interface") to restrict the color picker to the window, which fixes the color picker on Linux in a lot of cases.
|
||||
- [`avisynth`](https://github.com/arch1t3cht/Aegisub/tree/avisynth): Reenable Avisynth support on Windows (Still occasionally crashes)
|
||||
- [`bugfixes`](https://github.com/arch1t3cht/Aegisub/tree/bugfixes): Various fixes, mostly relevant for compilation
|
||||
- [`misc_dc`](https://github.com/arch1t3cht/Aegisub/tree/misc_dc): Miscellaneous changes taken from AegisubDC
|
||||
- [`video_panning_feature`](https://github.com/arch1t3cht/Aegisub/tree/video_panning_feature): Merge [moex3's video zoom and panning](https://github.com/TypesettingTools/Aegisub/pull/150), with an OSX fix and an option to toggle the behavior of Ctrl+Zoom
|
||||
- [`video_panning_feature`](https://github.com/arch1t3cht/Aegisub/tree/video_panning_feature): Merge [moex3's video zoom and panning](https://github.com/TypesettingTools/Aegisub/pull/150), with an OSX fix and more options to control zoom behavior
|
||||
- [`spectrum-frequency-mapping`](https://github.com/arch1t3cht/Aegisub/tree/spectrum-frequency-mapping): Merge EleonoreMizo's [spectrum display improvements](https://github.com/TypesettingTools/Aegisub/pull/94), and also make Shift+Scroll vertically zoom the audio display
|
||||
- [`wangqr_time_video`](https://github.com/arch1t3cht/Aegisub/tree/wangqr_time_video): Merge wangqr's feature adding a tool for timing subtitles to changes in the video
|
||||
|
||||
### Troubleshooting
|
||||
#### Building fails with a "CMake sandbox violation"
|
||||
|
@ -43,6 +45,9 @@ The changes to `default_config.json` or similar files weren't detected by meson
|
|||
#### The video is desynced / Frames don't appear at the right time
|
||||
This is probably due to the ffms2 seeking bug ([#394](https://github.com/FFMS/ffms2/issues/394)). On Windows, this shouldn't happen anymore. On Linux, you need to install the latest git version of ffms2 - for example the [`ffms2-git`](https://aur.archlinux.org/packages/ffms2-git) AUR package on Arch linux, or just compile it yourself.
|
||||
|
||||
#### On Windows: Aegisub crashes whenever I open a video
|
||||
If you're compiling yourself, try adding `--force-fallback-for=zlib` to the meson options.
|
||||
|
||||
|
||||
# Aegisub
|
||||
|
||||
|
|
57
automation/v4-docs/gui.txt
Normal file
57
automation/v4-docs/gui.txt
Normal file
|
@ -0,0 +1,57 @@
|
|||
Automation 4 Gui Functions
|
||||
|
||||
This document describes the available Automation 4 functions for
|
||||
controlling the editor's graphical interface. These all reside in the
|
||||
table aegisub.gui .
|
||||
|
||||
---
|
||||
|
||||
Getting and setting the selection and cursor in the text edit box
|
||||
|
||||
This set of functions controls the selection in the text edit box.
|
||||
All indices are counted starting from 1, following Lua conventions.
|
||||
The setter functions are applied after all subtitle changes have been
|
||||
applied. Only the latest update is applied.
|
||||
The getter functions return the state after the latest update by
|
||||
the setter functions, or the original state if there were none.
|
||||
|
||||
|
||||
function aegisub.gui.get_cursor()
|
||||
|
||||
Returns: 1 number
|
||||
1. The position of the cursor in the text edit field.
|
||||
|
||||
---
|
||||
|
||||
function aegisub.get_selection()
|
||||
|
||||
Returns: 2 values, all numbers.
|
||||
1. Starting position of the selection.
|
||||
2. Ending position of the selection, always larger or equal
|
||||
than the stating position.
|
||||
|
||||
---
|
||||
|
||||
function aegisub.gui.set_cursor(position)
|
||||
|
||||
@position (number)
|
||||
The new position of the cursor.
|
||||
|
||||
Returns: 0 values
|
||||
|
||||
---
|
||||
|
||||
function aegisub.gui.set_selection(start, end)
|
||||
|
||||
@start (number)
|
||||
The new start of the selection.
|
||||
|
||||
@end (number)
|
||||
The new end of the selection, i.e. where the cursor will be.
|
||||
Can be smaller than the start, in which case the cursor will
|
||||
be on the left side of the selection.
|
||||
|
||||
Returns: 0 values
|
||||
|
||||
---
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
#include "selection_controller.h"
|
||||
#include "subs_controller.h"
|
||||
#include "video_controller.h"
|
||||
#include "text_selection_controller.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <libaegisub/dispatch.h>
|
||||
|
@ -285,6 +286,39 @@ namespace {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int lua_get_text_cursor(lua_State *L)
|
||||
{
|
||||
push_value(L, get_context(L)->textSelectionController->GetStagedInsertionPoint() + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_set_text_cursor(lua_State *L)
|
||||
{
|
||||
int point = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 1);
|
||||
get_context(L)->textSelectionController->StageSetInsertionPoint(point);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_get_text_selection(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
int start = c->textSelectionController->GetStagedSelectionStart() + 1;
|
||||
int end = c->textSelectionController->GetStagedSelectionEnd() + 1;
|
||||
push_value(L, start <= end ? start : end);
|
||||
push_value(L, start <= end ? end : start);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_set_text_selection(lua_State *L)
|
||||
{
|
||||
int start = lua_tointeger(L, -2) - 1;
|
||||
int end = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 2);
|
||||
get_context(L)->textSelectionController->StageSetSelection(start, end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int project_properties(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
|
@ -489,6 +523,12 @@ namespace {
|
|||
set_field<project_properties>(L, "project_properties");
|
||||
set_field<lua_get_audio_selection>(L, "get_audio_selection");
|
||||
set_field<lua_set_status_text>(L, "set_status_text");
|
||||
lua_createtable(L, 0, 4);
|
||||
set_field<lua_get_text_cursor>(L, "get_cursor");
|
||||
set_field<lua_set_text_cursor>(L, "set_cursor");
|
||||
set_field<lua_get_text_selection>(L, "get_selection");
|
||||
set_field<lua_set_text_selection>(L, "set_selection");
|
||||
lua_setfield(L, -2, "gui");
|
||||
|
||||
// store aegisub table to globals
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
@ -786,6 +826,7 @@ namespace {
|
|||
|
||||
void LuaCommand::operator()(agi::Context *c)
|
||||
{
|
||||
c->textSelectionController->DropStagedChanges();
|
||||
LuaStackcheck stackcheck(L);
|
||||
set_context(L, c);
|
||||
stackcheck.check_stack(0);
|
||||
|
@ -883,6 +924,7 @@ namespace {
|
|||
new_active = *new_sel.begin();
|
||||
c->selectionController->SetSelectionAndActive(std::move(new_sel), new_active);
|
||||
}
|
||||
c->textSelectionController->CommitStagedChanges();
|
||||
|
||||
stackcheck.check_stack(0);
|
||||
}
|
||||
|
|
|
@ -102,13 +102,19 @@ namespace {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
void get_userdata_field(lua_State *L, const char *name, const char *line_class, T *target)
|
||||
bool get_userdata_field(lua_State *L, const char *name, const char *line_class, T *target, bool required)
|
||||
{
|
||||
lua_getfield(L, -1, name);
|
||||
if (!lua_isuserdata(L, -1))
|
||||
if (!lua_isuserdata(L, -1)) {
|
||||
if (!required) {
|
||||
lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
throw bad_field("userdata", name, line_class);
|
||||
}
|
||||
*target = *static_cast<T *>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
using namespace Automation4;
|
||||
|
@ -316,7 +322,9 @@ namespace Automation4 {
|
|||
dia->Margin[2] = get_int_field(L, "margin_t", "dialogue");
|
||||
dia->Effect = get_string_field(L, "effect", "dialogue");
|
||||
dia->Text = get_string_field(L, "text", "dialogue");
|
||||
get_userdata_field(L, "_foldinfo", "dialogue", &dia->Fold);
|
||||
if (!get_userdata_field(L, "_foldinfo", "dialogue", &dia->Fold, false)) {
|
||||
dia->Fold = FoldInfo();
|
||||
}
|
||||
|
||||
std::vector<uint32_t> new_ids;
|
||||
|
||||
|
|
BIN
src/bitmaps/button/button_align_16.png
Normal file
BIN
src/bitmaps/button/button_align_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 353 B |
BIN
src/bitmaps/button/button_align_24.png
Normal file
BIN
src/bitmaps/button/button_align_24.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 571 B |
BIN
src/bitmaps/button/button_align_32.png
Normal file
BIN
src/bitmaps/button/button_align_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 690 B |
BIN
src/bitmaps/button/button_align_48.png
Normal file
BIN
src/bitmaps/button/button_align_48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
src/bitmaps/button/button_align_64.png
Normal file
BIN
src/bitmaps/button/button_align_64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 547 B |
|
@ -51,6 +51,11 @@ button/bugtracker_button_24.png
|
|||
button/bugtracker_button_32.png
|
||||
button/bugtracker_button_48.png
|
||||
button/bugtracker_button_64.png
|
||||
button/button_align_16.png
|
||||
button/button_align_24.png
|
||||
button/button_align_32.png
|
||||
button/button_align_48.png
|
||||
button/button_align_64.png
|
||||
button/button_audio_commit_16.png
|
||||
button/button_audio_commit_24.png
|
||||
button/button_audio_commit_32.png
|
||||
|
|
|
@ -43,6 +43,12 @@ public:
|
|||
|
||||
/// Get the currently selected color
|
||||
agi::Color GetColor() { return colour; }
|
||||
|
||||
void SetColor(agi::Color color)
|
||||
{
|
||||
colour = color;
|
||||
UpdateBitmap();
|
||||
}
|
||||
};
|
||||
|
||||
struct ColorValidator final : public wxValidator {
|
||||
|
|
|
@ -235,6 +235,18 @@ struct time_snap_scene final : public validate_video_loaded {
|
|||
}
|
||||
};
|
||||
|
||||
struct time_align_subtitle_to_point final : public validate_video_loaded {
|
||||
CMD_NAME("time/align")
|
||||
CMD_ICON(button_align)
|
||||
STR_MENU("Align subtitle to video")
|
||||
STR_DISP("Align subtitle to video")
|
||||
STR_HELP("Align subtitle to video by key points")
|
||||
void operator()(agi::Context* c) override {
|
||||
c->videoController->Stop();
|
||||
ShowAlignToVideoDialog(c);
|
||||
}
|
||||
};
|
||||
|
||||
struct time_add_lead_both final : public Command {
|
||||
CMD_NAME("time/lead/both")
|
||||
STR_MENU("Add lead in and out")
|
||||
|
@ -393,6 +405,7 @@ namespace cmd {
|
|||
reg(agi::make_unique<time_snap_end_video>());
|
||||
reg(agi::make_unique<time_snap_scene>());
|
||||
reg(agi::make_unique<time_snap_start_video>());
|
||||
reg(agi::make_unique<time_align_subtitle_to_point>());
|
||||
reg(agi::make_unique<time_start_decrease>());
|
||||
reg(agi::make_unique<time_start_increase>());
|
||||
}
|
||||
|
|
375
src/dialog_align.cpp
Normal file
375
src/dialog_align.cpp
Normal file
|
@ -0,0 +1,375 @@
|
|||
// Copyright (c) 2019, Charlie Jiang
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * 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.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// 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 OWNER 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.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_file.h"
|
||||
#include "compat.h"
|
||||
#include "dialog_manager.h"
|
||||
#include "format.h"
|
||||
#include "include/aegisub/context.h"
|
||||
#include "video_frame.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "options.h"
|
||||
#include "project.h"
|
||||
#include "selection_controller.h"
|
||||
#include "video_controller.h"
|
||||
#include "async_video_provider.h"
|
||||
#include "colour_button.h"
|
||||
#include "image_position_picker.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <libaegisub/ass/time.h>
|
||||
#include <libaegisub/vfr.h>
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
#if BOOST_VERSION >= 106900
|
||||
#include <boost/gil.hpp>
|
||||
#else
|
||||
#include <boost/gil/gil_all.hpp>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
class DialogAlignToVideo final : public wxDialog {
|
||||
agi::Context* context;
|
||||
AsyncVideoProvider* provider;
|
||||
|
||||
wxImage preview_image;
|
||||
VideoFrame current_frame;
|
||||
int current_n_frame;
|
||||
|
||||
ImagePositionPicker* preview_frame;
|
||||
ColourButton* selected_color;
|
||||
wxTextCtrl* selected_x;
|
||||
wxTextCtrl* selected_y;
|
||||
wxTextCtrl* selected_tolerance;
|
||||
|
||||
void update_from_textbox();
|
||||
void update_from_textbox(wxCommandEvent&);
|
||||
|
||||
bool check_exists(int pos, int x, int y, int* lrud, double* orig, unsigned char tolerance);
|
||||
void process(wxEvent&);
|
||||
public:
|
||||
DialogAlignToVideo(agi::Context* context);
|
||||
~DialogAlignToVideo();
|
||||
};
|
||||
|
||||
DialogAlignToVideo::DialogAlignToVideo(agi::Context* context)
|
||||
: wxDialog(context->parent, -1, _("Align subtitle to video by key point"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER)
|
||||
, context(context), provider(context->project->VideoProvider())
|
||||
{
|
||||
auto add_with_label = [&](wxSizer * sizer, wxString const& label, wxWindow * ctrl) {
|
||||
sizer->Add(new wxStaticText(this, -1, label), 0, wxLEFT | wxRIGHT | wxCENTER, 3);
|
||||
sizer->Add(ctrl, 1, wxLEFT);
|
||||
};
|
||||
|
||||
auto tolerance = OPT_GET("Tool/Align to Video/Tolerance")->GetInt();
|
||||
auto maximized = OPT_GET("Tool/Align to Video/Maximized")->GetBool();
|
||||
|
||||
current_n_frame = context->videoController->GetFrameN();
|
||||
current_frame = *context->project->VideoProvider()->GetFrame(current_n_frame, 0, true);
|
||||
preview_image = GetImage(current_frame);
|
||||
|
||||
preview_frame = new ImagePositionPicker(this, preview_image, [&](int x, int y, unsigned char r, unsigned char g, unsigned char b) -> void {
|
||||
selected_x->ChangeValue(wxString::Format(wxT("%i"), x));
|
||||
selected_y->ChangeValue(wxString::Format(wxT("%i"), y));
|
||||
|
||||
selected_color->SetColor(agi::Color(r, g, b));
|
||||
});
|
||||
selected_color = new ColourButton(this, wxSize(55, 16), true, agi::Color("FFFFFF"));
|
||||
selected_color->SetToolTip(_("The key color to be followed"));
|
||||
selected_x = new wxTextCtrl(this, -1, "0");
|
||||
selected_x->SetToolTip(_("The x coord of the key point"));
|
||||
selected_y = new wxTextCtrl(this, -1, "0");
|
||||
selected_y->SetToolTip(_("The y coord of the key point"));
|
||||
selected_tolerance = new wxTextCtrl(this, -1, wxString::Format(wxT("%i"), int(tolerance)));
|
||||
selected_tolerance->SetToolTip(_("Max tolerance of the color"));
|
||||
|
||||
selected_x->Bind(wxEVT_TEXT, &DialogAlignToVideo::update_from_textbox, this);
|
||||
selected_y->Bind(wxEVT_TEXT, &DialogAlignToVideo::update_from_textbox, this);
|
||||
update_from_textbox();
|
||||
|
||||
wxFlexGridSizer* right_sizer = new wxFlexGridSizer(4, 2, 5, 5);
|
||||
add_with_label(right_sizer, _("X"), selected_x);
|
||||
add_with_label(right_sizer, _("Y"), selected_y);
|
||||
add_with_label(right_sizer, _("Color"), selected_color);
|
||||
add_with_label(right_sizer, _("Tolerance"), selected_tolerance);
|
||||
right_sizer->AddGrowableCol(1, 1);
|
||||
|
||||
wxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
main_sizer->Add(preview_frame, 1, (wxALL & ~wxRIGHT) | wxEXPAND, 5);
|
||||
main_sizer->Add(right_sizer, 0, wxALIGN_LEFT, 5);
|
||||
|
||||
wxSizer* dialog_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
dialog_sizer->Add(main_sizer, wxSizerFlags(1).Border(wxALL & ~wxBOTTOM).Expand());
|
||||
dialog_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Right().Border());
|
||||
SetSizerAndFit(dialog_sizer);
|
||||
SetSize(1024, 700);
|
||||
CenterOnParent();
|
||||
|
||||
Bind(wxEVT_BUTTON, &DialogAlignToVideo::process, this, wxID_OK);
|
||||
Bind(wxEVT_LEFT_DCLICK, &DialogAlignToVideo::process, this, preview_frame->GetId());
|
||||
SetIcon(GETICON(button_align_16));
|
||||
if (maximized)
|
||||
wxDialog::Maximize(true);
|
||||
}
|
||||
|
||||
DialogAlignToVideo::~DialogAlignToVideo()
|
||||
{
|
||||
long lt;
|
||||
if (!selected_tolerance->GetValue().ToLong(<))
|
||||
return;
|
||||
if (lt < 0 || lt > 255)
|
||||
return;
|
||||
|
||||
OPT_SET("Tool/Align to Video/Tolerance")->SetInt(lt);
|
||||
}
|
||||
|
||||
void rgb2lab(unsigned char r, unsigned char g, unsigned char b, double* lab)
|
||||
{
|
||||
double X = (0.412453 * r + 0.357580 * g + 0.180423 * b) / 255.0;
|
||||
double Y = (0.212671 * r + 0.715160 * g + 0.072169 * b) / 255.0;
|
||||
double Z = (0.019334 * r + 0.119193 * g + 0.950227 * b) / 255.0;
|
||||
double xr = X / 0.950456, yr = Y / 1.000, zr = Z / 1.088854;
|
||||
|
||||
if (yr > 0.008856) {
|
||||
lab[0] = 116.0 * pow(yr, 1.0 / 3.0) - 16.0;
|
||||
}
|
||||
else {
|
||||
lab[0] = 903.3 * yr;
|
||||
}
|
||||
|
||||
double fxr, fyr, fzr;
|
||||
if (xr > 0.008856)
|
||||
fxr = pow(xr, 1.0 / 3.0);
|
||||
else
|
||||
fxr = 7.787 * xr + 16.0 / 116.0;
|
||||
|
||||
if (yr > 0.008856)
|
||||
fyr = pow(yr, 1.0 / 3.0);
|
||||
else
|
||||
fyr = 7.787 * yr + 16.0 / 116.0;
|
||||
|
||||
if (zr > 0.008856)
|
||||
fzr = pow(zr, 1.0 / 3.0);
|
||||
else
|
||||
fzr = 7.787 * zr + 16.0 / 116.0;
|
||||
|
||||
lab[1] = 500.0 * (fxr - fyr);
|
||||
lab[2] = 200.0 * (fyr - fzr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool check_point(boost::gil::pixel<unsigned char, T> & pixel, double orig[3], unsigned char tolerance)
|
||||
{
|
||||
double lab[3];
|
||||
// in pixel: B,G,R
|
||||
rgb2lab(pixel[2], pixel[1], pixel[0], lab);
|
||||
auto diff = sqrt(pow(lab[0] - orig[0], 2) + pow(lab[1] - orig[1], 2) + pow(lab[2] - orig[2], 2));
|
||||
return diff <= tolerance;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool calculate_point(boost::gil::image_view<T> view, int x, int y, double orig[3], unsigned char tolerance, int* ret)
|
||||
{
|
||||
auto origin = *view.at(x, y);
|
||||
if (!check_point(origin, orig, tolerance))
|
||||
return false;
|
||||
auto w = view.width();
|
||||
auto h = view.height();
|
||||
int l = x, r = x, u = y, d = y;
|
||||
for (int i = x + 1; i < w; i++)
|
||||
{
|
||||
auto p = *view.at(i, y);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = x - 1; i >= 0; i--)
|
||||
{
|
||||
auto p = *view.at(i, y);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
l = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = y + 1; i < h; i++)
|
||||
{
|
||||
auto p = *view.at(x, i);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
d = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = y - 1; i >= 0; i--)
|
||||
{
|
||||
auto p = *view.at(x, i);
|
||||
if (!check_point(p, orig, tolerance))
|
||||
{
|
||||
u = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret[0] = l;
|
||||
ret[1] = r;
|
||||
ret[2] = u;
|
||||
ret[3] = d;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::process(wxEvent &)
|
||||
{
|
||||
auto n_frames = provider->GetFrameCount();
|
||||
auto w = provider->GetWidth();
|
||||
auto h = provider->GetHeight();
|
||||
|
||||
long lx, ly, lt;
|
||||
if (!selected_x->GetValue().ToLong(&lx) || !selected_y->GetValue().ToLong(&ly) || !selected_tolerance->GetValue().ToLong(<))
|
||||
{
|
||||
wxMessageBox(_("Bad x or y position or tolerance value!"));
|
||||
return;
|
||||
}
|
||||
if (lx < 0 || ly < 0 || lx >= w || ly >= h)
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Bad x or y position! Require: 0 <= x < %i, 0 <= y < %i"), w, h));
|
||||
return;
|
||||
}
|
||||
if (lt < 0 || lt > 255)
|
||||
{
|
||||
wxMessageBox(_("Bad tolerance value! Require: 0 <= torlerance <= 255"));
|
||||
return;
|
||||
}
|
||||
int x = int(lx), y = int(ly);
|
||||
unsigned char tolerance = (unsigned char)(lt);
|
||||
|
||||
auto color = selected_color->GetColor();
|
||||
auto r = color.r;
|
||||
auto b = color.b;
|
||||
auto g = color.g;
|
||||
double lab[3];
|
||||
rgb2lab(r, g, b, lab);
|
||||
|
||||
int pos = current_n_frame;
|
||||
auto frame = provider->GetFrame(pos, -1, true);
|
||||
auto view = interleaved_view(frame->width, frame->height, reinterpret_cast<boost::gil::bgra8_pixel_t*>(frame->data.data()), frame->pitch);
|
||||
if (frame->flipped)
|
||||
y = frame->height - y;
|
||||
|
||||
// Ensure selected color and position match
|
||||
if(!check_point(*view.at(x,y), lab, tolerance))
|
||||
{
|
||||
wxMessageBox(_("Selected position and color are not within tolerance!"));
|
||||
return;
|
||||
}
|
||||
|
||||
int lrud[4];
|
||||
calculate_point(view, x, y, lab, tolerance, lrud);
|
||||
|
||||
// find forward
|
||||
#define CHECK_EXISTS_POS check_exists(pos, x, y, lrud, lab, tolerance)
|
||||
do {
|
||||
pos -= 2;
|
||||
} while (pos >= 0 && CHECK_EXISTS_POS);
|
||||
pos++;
|
||||
pos = std::max(0, pos);
|
||||
auto left = CHECK_EXISTS_POS ? pos : pos + 1;
|
||||
|
||||
pos = current_n_frame;
|
||||
do {
|
||||
pos += 2;
|
||||
} while (pos < n_frames && CHECK_EXISTS_POS);
|
||||
pos--;
|
||||
pos = std::min(pos, n_frames - 1);
|
||||
auto right = CHECK_EXISTS_POS ? pos : pos - 1;
|
||||
|
||||
auto timecode = context->project->Timecodes();
|
||||
auto line = context->selectionController->GetActiveLine();
|
||||
line->Start = timecode.TimeAtFrame(left, agi::vfr::Time::START);
|
||||
line->End = timecode.TimeAtFrame(right, agi::vfr::Time::END); // exclusive
|
||||
context->ass->Commit(_("Align to video by key point"), AssFile::COMMIT_DIAG_TIME);
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DialogAlignToVideo::check_exists(int pos, int x, int y, int* lrud, double* orig, unsigned char tolerance)
|
||||
{
|
||||
auto frame = provider->GetFrame(pos, -1, true);
|
||||
auto view = interleaved_view(frame->width, frame->height, reinterpret_cast<boost::gil::bgra8_pixel_t*>(frame->data.data()), frame->pitch);
|
||||
if (frame->flipped)
|
||||
y = frame->height - y;
|
||||
int actual[4];
|
||||
if (!calculate_point(view, x, y, orig, tolerance, actual)) return false;
|
||||
int dl = abs(actual[0] - lrud[0]);
|
||||
int dr = abs(actual[1] - lrud[1]);
|
||||
int du = abs(actual[2] - lrud[2]);
|
||||
int dd = abs(actual[3] - lrud[3]);
|
||||
|
||||
return dl <= 5 && dr <= 5 && du <= 5 && dd <= 5;
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::update_from_textbox()
|
||||
{
|
||||
long lx, ly;
|
||||
int w = preview_image.GetWidth(), h = preview_image.GetHeight();
|
||||
if (!selected_x->GetValue().ToLong(&lx) || !selected_y->GetValue().ToLong(&ly))
|
||||
return;
|
||||
|
||||
if (lx < 0 || ly < 0 || lx >= w || ly >= h)
|
||||
return;
|
||||
int x = int(lx);
|
||||
int y = int(ly);
|
||||
auto r = preview_image.GetRed(x, y);
|
||||
auto g = preview_image.GetGreen(x, y);
|
||||
auto b = preview_image.GetBlue(x, y);
|
||||
selected_color->SetColor(agi::Color(r, g, b));
|
||||
}
|
||||
|
||||
void DialogAlignToVideo::update_from_textbox(wxCommandEvent & evt)
|
||||
{
|
||||
update_from_textbox();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ShowAlignToVideoDialog(agi::Context * c)
|
||||
{
|
||||
c->dialog->Show<DialogAlignToVideo>(c);
|
||||
}
|
|
@ -74,3 +74,4 @@ void ShowSpellcheckerDialog(agi::Context *c);
|
|||
void ShowStyleManagerDialog(agi::Context *c);
|
||||
void ShowTimingProcessorDialog(agi::Context *c);
|
||||
void ShowVideoDetailsDialog(agi::Context *c);
|
||||
void ShowAlignToVideoDialog(agi::Context* c);
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
#include <wx/msgdlg.h>
|
||||
|
||||
namespace {
|
||||
const char* added_hotkeys_cj[][3] = {
|
||||
{"time/align", "Video", "KP_TAB"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
const char *added_hotkeys_7035[][3] = {
|
||||
{"audio/play/line", "Audio", "R"},
|
||||
{nullptr}
|
||||
|
@ -81,6 +86,11 @@ void init() {
|
|||
|
||||
auto migrations = OPT_GET("App/Hotkey Migrations")->GetListString();
|
||||
|
||||
if (boost::find(migrations, "cj") == end(migrations)) {
|
||||
migrate_hotkeys(added_hotkeys_cj);
|
||||
migrations.emplace_back("cj");
|
||||
}
|
||||
|
||||
if (boost::find(migrations, "7035") == end(migrations)) {
|
||||
migrate_hotkeys(added_hotkeys_7035);
|
||||
migrations.emplace_back("7035");
|
||||
|
|
132
src/image_position_picker.cpp
Normal file
132
src/image_position_picker.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
#include "image_position_picker.h"
|
||||
BEGIN_EVENT_TABLE(ImagePositionPicker, wxPanel)
|
||||
// some useful events
|
||||
/*
|
||||
EVT_MOTION(ImagePositionPicker::mouseMoved)
|
||||
EVT_LEFT_DOWN(ImagePositionPicker::mouseDown)
|
||||
EVT_LEFT_UP(ImagePositionPicker::mouseReleased)
|
||||
EVT_RIGHT_DOWN(ImagePositionPicker::rightClick)
|
||||
EVT_LEAVE_WINDOW(ImagePositionPicker::mouseLeftWindow)
|
||||
EVT_KEY_DOWN(ImagePositionPicker::keyPressed)
|
||||
EVT_KEY_UP(ImagePositionPicker::keyReleased)
|
||||
EVT_MOUSEWHEEL(ImagePositionPicker::mouseWheelMoved)
|
||||
*/
|
||||
|
||||
// catch paint events
|
||||
EVT_PAINT(ImagePositionPicker::paintEvent)
|
||||
//Size event
|
||||
EVT_SIZE(ImagePositionPicker::OnSize)
|
||||
EVT_MOUSE_EVENTS(ImagePositionPicker::OnMouseEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
// some useful events
|
||||
/*
|
||||
void ImagePositionPicker::mouseMoved(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseDown(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseWheelMoved(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseReleased(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::rightClick(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::mouseLeftWindow(wxMouseEvent& event) {}
|
||||
void ImagePositionPicker::keyPressed(wxKeyEvent& event) {}
|
||||
void ImagePositionPicker::keyReleased(wxKeyEvent& event) {}
|
||||
*/
|
||||
|
||||
ImagePositionPicker::ImagePositionPicker(wxWindow* parent, wxImage i, updator upd) : wxPanel(parent)
|
||||
{
|
||||
image = i;
|
||||
prevW = -1;
|
||||
prevH = -1;
|
||||
w = image.GetWidth();
|
||||
h = image.GetHeight();
|
||||
update = upd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the system of by wxWidgets when the panel needs
|
||||
* to be redrawn. You can also trigger this call by
|
||||
* calling Refresh()/Update().
|
||||
*/
|
||||
|
||||
void ImagePositionPicker::paintEvent(wxPaintEvent& evt)
|
||||
{
|
||||
// depending on your system you may need to look at double-buffered dcs
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alternatively, you can use a clientDC to paint on the panel
|
||||
* at any time. Using this generally does not free you from
|
||||
* catching paint events, since it is possible that e.g. the window
|
||||
* manager throws away your drawing when the window comes to the
|
||||
* background, and expects you will redraw it when the window comes
|
||||
* back (by sending a paint event).
|
||||
*/
|
||||
void ImagePositionPicker::paintNow()
|
||||
{
|
||||
// depending on your system you may need to look at double-buffered dcs
|
||||
wxClientDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we do the actual rendering. I put it in a separate
|
||||
* method so that it can work no matter what type of DC
|
||||
* (e.g. wxPaintDC or wxClientDC) is used.
|
||||
*/
|
||||
void ImagePositionPicker::render(wxDC& dc)
|
||||
{
|
||||
int neww, newh;
|
||||
dc.GetSize(&neww, &newh);
|
||||
|
||||
if (neww != prevW || newh != prevH)
|
||||
{
|
||||
// keep the image proportionate
|
||||
int ww, hh;
|
||||
if (double(neww) / w >= double(newh) / h) // too long
|
||||
{
|
||||
ww = newh * w / h;
|
||||
hh = newh;
|
||||
}
|
||||
else
|
||||
{
|
||||
ww = neww;
|
||||
hh = neww * h / w;
|
||||
}
|
||||
resized = wxBitmap(image.Scale(ww, hh /*, wxIMAGE_QUALITY_HIGH*/));
|
||||
prevW = ww;
|
||||
prevH = hh;
|
||||
dc.DrawBitmap(resized, 0, 0, false);
|
||||
}
|
||||
else {
|
||||
dc.DrawBitmap(resized, 0, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we call refresh to tell the panel to draw itself again.
|
||||
* So when the user resizes the image panel the image should be resized too.
|
||||
*/
|
||||
void ImagePositionPicker::OnSize(wxSizeEvent& event) {
|
||||
Refresh();
|
||||
//skip the event.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void ImagePositionPicker::OnMouseEvent(wxMouseEvent& evt)
|
||||
{
|
||||
wxPoint pos = evt.GetPosition();
|
||||
if (evt.Dragging() || evt.LeftDown() || evt.LeftUp())
|
||||
{
|
||||
int x = pos.x * w / prevW;
|
||||
int y = pos.y * h / prevH;
|
||||
if (x >= 0 && x < w && y >= 0 && y < h)
|
||||
update(x, y, image.GetRed(x, y), image.GetGreen(x, y), image.GetBlue(x, y));
|
||||
}
|
||||
else if (evt.LeftDClick()) {
|
||||
// Propagate the double click event to submit
|
||||
evt.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
evt.Skip();
|
||||
}
|
||||
}
|
37
src/image_position_picker.h
Normal file
37
src/image_position_picker.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <wx/wx.h>
|
||||
#include <wx/sizer.h>
|
||||
#include "gl_wrap.h"
|
||||
|
||||
typedef std::function<void(double, double, unsigned char, unsigned char, unsigned char)> updator;
|
||||
|
||||
class ImagePositionPicker : public wxPanel
|
||||
{
|
||||
wxImage image;
|
||||
wxBitmap resized;
|
||||
int prevW, prevH, w, h;
|
||||
|
||||
updator update;
|
||||
|
||||
public:
|
||||
ImagePositionPicker(wxWindow* parent, wxImage i, updator upd);
|
||||
|
||||
void paintEvent(wxPaintEvent & evt);
|
||||
void paintNow();
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent& evt);
|
||||
void render(wxDC& dc);
|
||||
|
||||
// some useful events
|
||||
/*
|
||||
void mouseMoved(wxMouseEvent& event);
|
||||
void mouseDown(wxMouseEvent& event);
|
||||
void mouseWheelMoved(wxMouseEvent& event);
|
||||
void mouseReleased(wxMouseEvent& event);
|
||||
void rightClick(wxMouseEvent& event);
|
||||
void mouseLeftWindow(wxMouseEvent& event);
|
||||
void keyPressed(wxKeyEvent& event);
|
||||
void keyReleased(wxKeyEvent& event);
|
||||
*/
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
|
@ -581,6 +581,10 @@
|
|||
},
|
||||
"Visual" : {
|
||||
"Autohide": false
|
||||
},
|
||||
"Align to Video" : {
|
||||
"Tolerance" : 20,
|
||||
"Maximized" : true
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -590,6 +594,8 @@
|
|||
},
|
||||
|
||||
"Video" : {
|
||||
"Disable Scroll Zoom" : false,
|
||||
"Reverse Zoom" : false,
|
||||
"Default Zoom" : 7,
|
||||
"Detached" : {
|
||||
"Enabled" : false,
|
||||
|
@ -619,6 +625,6 @@
|
|||
},
|
||||
"Subtitle Sync" : true,
|
||||
"Video Pan": false,
|
||||
"Default to UI Zoom": false
|
||||
"Default to Video Zoom": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@
|
|||
"subtitle/select/all" : [
|
||||
"Ctrl-A"
|
||||
],
|
||||
"grid/toggle" : [
|
||||
"grid/fold/toggle" : [
|
||||
"Enter"
|
||||
],
|
||||
"video/frame/next" : [
|
||||
|
@ -289,6 +289,9 @@
|
|||
],
|
||||
"video/frame/prev/large" : [
|
||||
"Alt-Left"
|
||||
],
|
||||
"time/align" : [
|
||||
"KP_TAB"
|
||||
]
|
||||
},
|
||||
"Translation Assistant" : {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"subtitle/select/visible",
|
||||
"time/snap/scene",
|
||||
"time/frame/current",
|
||||
"time/align",
|
||||
"",
|
||||
"tool/style/manager",
|
||||
"subtitle/properties",
|
||||
|
|
|
@ -580,6 +580,10 @@
|
|||
},
|
||||
"Visual" : {
|
||||
"Autohide": false
|
||||
},
|
||||
"Align to Video" : {
|
||||
"Tolerance" : 20,
|
||||
"Maximized" : true
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -589,6 +593,8 @@
|
|||
},
|
||||
|
||||
"Video" : {
|
||||
"Disable Scroll Zoom" : false,
|
||||
"Reverse Zoom" : false,
|
||||
"Default Zoom" : 7,
|
||||
"Detached" : {
|
||||
"Enabled" : false,
|
||||
|
@ -618,6 +624,6 @@
|
|||
},
|
||||
"Subtitle Sync" : true,
|
||||
"Video Pan": false,
|
||||
"Default to UI Zoom": false
|
||||
"Default to Video Zoom": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,7 +273,7 @@
|
|||
"subtitle/select/all" : [
|
||||
"Ctrl-A"
|
||||
],
|
||||
"grid/toggle" : [
|
||||
"grid/fold/toggle" : [
|
||||
"Enter"
|
||||
],
|
||||
"video/frame/next" : [
|
||||
|
|
|
@ -56,6 +56,7 @@ aegisub_src = files(
|
|||
'context.cpp',
|
||||
'crash_writer.cpp',
|
||||
'dialog_about.cpp',
|
||||
'dialog_align.cpp',
|
||||
'dialog_attachments.cpp',
|
||||
'dialog_automation.cpp',
|
||||
'dialog_autosave.cpp',
|
||||
|
@ -98,6 +99,7 @@ aegisub_src = files(
|
|||
'help_button.cpp',
|
||||
'hotkey.cpp',
|
||||
'hotkey_data_view_model.cpp',
|
||||
'image_position_picker.cpp',
|
||||
'initial_line_state.cpp',
|
||||
'main.cpp',
|
||||
'menu.cpp',
|
||||
|
|
|
@ -174,6 +174,9 @@ void Video(wxTreebook *book, Preferences *parent) {
|
|||
p->CellSkip(general);
|
||||
p->OptionAdd(general, _("Automatically open audio when opening video"), "Video/Open Audio");
|
||||
p->CellSkip(general);
|
||||
p->OptionAdd(general, _("Disable zooming with scroll bar"), "Video/Disable Scroll Zoom")
|
||||
->SetToolTip("Makes the scroll bar not zoom the video. Useful when using a track pad that often scrolls accidentally.");
|
||||
p->OptionAdd(general, _("Reverse zoom direction"), "Video/Reverse Zoom");
|
||||
|
||||
const wxString czoom_arr[24] = { "12.5%", "25%", "37.5%", "50%", "62.5%", "75%", "87.5%", "100%", "112.5%", "125%", "137.5%", "150%", "162.5%", "175%", "187.5%", "200%", "212.5%", "225%", "237.5%", "250%", "262.5%", "275%", "287.5%", "300%" };
|
||||
wxArrayString choice_zoom(24, czoom_arr);
|
||||
|
@ -446,7 +449,8 @@ void Advanced_Video(wxTreebook *book, Preferences *parent) {
|
|||
p->OptionChoice(expert, _("Subtitles provider"), sp_choice, "Subtitle/Provider");
|
||||
|
||||
p->OptionAdd(expert, _("Video Panning"), "Video/Video Pan");
|
||||
p->OptionAdd(expert, _("Default to UI Zoom"), "Video/Default to UI Zoom");
|
||||
p->OptionAdd(expert, _("Default to Video Zoom"), "Video/Default to Video Zoom")
|
||||
->SetToolTip("Reverses the behavior of Ctrl while scrolling the video display. If not set, scrolling will default to UI zoom and Ctrl+scrolling will zoom the video. If set, this will be reversed.");
|
||||
|
||||
|
||||
#ifdef WITH_AVISYNTH
|
||||
|
|
|
@ -73,3 +73,18 @@ void TextSelectionController::SetSelection(int start, int end) {
|
|||
changing = false;
|
||||
AnnounceSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void TextSelectionController::CommitStagedChanges() {
|
||||
if (has_staged_selection) {
|
||||
if (staged_selection_start <= staged_selection_end) {
|
||||
SetSelection(staged_selection_start, staged_selection_end);
|
||||
} else {
|
||||
// commit some crimes to get this to work in all cases
|
||||
SetInsertionPoint(staged_selection_end == 0 ? staged_selection_start : 0);
|
||||
SetSelection(staged_selection_start, staged_selection_start);
|
||||
SetInsertionPoint(staged_selection_end);
|
||||
}
|
||||
has_staged_selection = false;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,10 @@ class TextSelectionController {
|
|||
int insertion_point = 0;
|
||||
bool changing = false;
|
||||
|
||||
int staged_selection_start = 0;
|
||||
int staged_selection_end = 0;
|
||||
bool has_staged_selection = false;
|
||||
|
||||
wxStyledTextCtrl *ctrl = nullptr;
|
||||
|
||||
void UpdateUI(wxStyledTextEvent &evt);
|
||||
|
@ -35,10 +39,23 @@ public:
|
|||
void SetSelection(int start, int end);
|
||||
void SetInsertionPoint(int point);
|
||||
|
||||
// This set of functions allows staging changes to the selection or insertion points, which can then be applied later.
|
||||
// This is useful when one is still waiting on other changes to be applied, but already listening for changes to the
|
||||
// selection in the eventually visible text.
|
||||
// They also provide a wrapper for setting a selection whose insertion point is on the left side.
|
||||
void StageSetSelection(int start, int end) { staged_selection_start = start; staged_selection_end = end; has_staged_selection = true; };
|
||||
void StageSetInsertionPoint(int point) { StageSetSelection(point, point); };
|
||||
void CommitStagedChanges();
|
||||
void DropStagedChanges() { has_staged_selection = false; };
|
||||
|
||||
int GetSelectionStart() const { return selection_start; }
|
||||
int GetSelectionEnd() const { return selection_end; }
|
||||
int GetInsertionPoint() const { return insertion_point; }
|
||||
|
||||
int GetStagedSelectionStart() const { return has_staged_selection ? staged_selection_start : selection_start; }
|
||||
int GetStagedSelectionEnd() const { return has_staged_selection ? staged_selection_end : selection_end; }
|
||||
int GetStagedInsertionPoint() const { return has_staged_selection ? staged_selection_end : insertion_point; }
|
||||
|
||||
void SetControl(wxStyledTextCtrl *ctrl);
|
||||
~TextSelectionController();
|
||||
|
||||
|
|
|
@ -409,8 +409,11 @@ void VideoDisplay::OnMouseLeave(wxMouseEvent& event) {
|
|||
void VideoDisplay::OnMouseWheel(wxMouseEvent& event) {
|
||||
bool videoPan = OPT_GET("Video/Video Pan")->GetBool();
|
||||
if (int wheel = event.GetWheelRotation()) {
|
||||
if (ForwardMouseWheelEvent(this, event)) {
|
||||
if (!videoPan || (event.ControlDown() != OPT_GET("Video/Default to UI Zoom")->GetBool())) {
|
||||
if (ForwardMouseWheelEvent(this, event) && !OPT_GET("Video/Disable Scroll Zoom")->GetBool()) {
|
||||
if (OPT_GET("Video/Reverse Zoom")->GetBool()) {
|
||||
wheel = -wheel;
|
||||
}
|
||||
if (!videoPan || (event.ControlDown() == OPT_GET("Video/Default to Video Zoom")->GetBool())) {
|
||||
SetWindowZoom(windowZoomValue + .125 * (wheel / event.GetWheelDelta()));
|
||||
} else {
|
||||
SetVideoZoom(wheel / event.GetWheelDelta());
|
||||
|
|
Loading…
Reference in a new issue