Merge branch 'beta-fix-2809' (fix #2809)

This commit is contained in:
David Capello 2022-10-12 15:00:36 -03:00
commit 160a3f9a6c
52 changed files with 833 additions and 361 deletions

View File

@ -6,6 +6,15 @@
title = Warning - Important
description = You are going to enter in "Advanced Mode".
[ani_controls]
shortcut = Shortcut:
right_click = Right-click: Show playback options
[anidir_combo]
forward = Forward
reverse = Reverse
ping_pong = Ping-pong
[ask_for_color_profile]
title = Color Profile
sprite_with_profile = The sprite contains a color profile.
@ -14,6 +23,23 @@ sprite_without_profile = The sprite doesn't contain a color profile.
[statusbar_tips]
all_layers_are_locked = All selected layers are locked
layer_locked = Layer '{0}' is locked
disable_snap_grid = Disable Snap to Grid
frame = Frame:
current_frame = Current Frame
zoom_level = Zoom Level
new_frame = New Frame
locked_layers = There are locked layers
no_active_layers = There is no active layer
layer_x_is_hidden = Layer '{}' is hidden
unmodifiable_reference_layer = Layer '{}' is reference, cannot be modified
filter_no_unlocked_layer = No unlocked layers to apply filter
cannot_move_bg_layer = The background layer cannot be moved
nothing_to_move = Nothing to move
recovery_task_using_sprite = Sprite is used by a backup/data recovery task
non_transformable_reference_layer = Layer '{}' is reference, cannot be transformed
sprite_locked_somewhere = The sprite is locked in other editor
not_enough_transform_memory = Not enough memory to transform the selection
not_enough_rotsprite_memory = Not enough memory for RotSprite
[alerts]
applying_filter = FX<<Applying effect...||&Cancel
@ -185,6 +211,11 @@ Information
||&OK
END
[brightness_contrast]
title = Brightness/Contrast
brightness_label = Brightness:
contrast_label = Contrast:
[brush_slot_params]
brush = Brush:
brush_type = Type
@ -200,6 +231,11 @@ ink_opacity = Opacity
extras = Extras:
shade = Shade
pixel_perfect = Pixel-Perfect
save_brush = Save Brush Here
locked = Locked
delete = Delete
delete_all = Delete All
saved_parameters = Saved Parameters
[cel_movement_popup_menu]
move = &Move
@ -240,6 +276,35 @@ remap_tiles_tooltip = Matches old tiles with new tiles
clear_tiles = Clear Tiles
resize_tiles = Resize Tiles
drag_and_drop_tiles = Drag And Drop Tiles
reverse_colors = Reverse Colors
sort_colors = Sort Colors
gradient = Gradient
gradient_by_hue = Gradient by Hue
sort_by_hue = Sort by Hue
sort_by_saturation = Sort by Saturation
sort_by_brightness = Sort by Brightness
sort_by_luminance = Sort by Luminance
sort_by_red = Sort by Red
sort_by_green = Sort by Green
sort_by_blue = Sort by Blue
sort_by_alpha = Sort by Alpha
ascending = Ascending
descending = Descending
[color_popup]
transparent_color_sel = Transparent Color Selected
index = Index
[color_wheel]
discrete = Discrete
no_harmonies = Without Harmonies
complementary = Complementary
monochromatic = Monochromatic
analogous = Analogous
split_complementary = Split-Complementary
triadic = Triadic
tetradic = Tetradic
square = Square
[commands]
About = About
@ -529,12 +594,19 @@ toggle_breakpoint = Toggle Breakpoint
stacktrace = Stacktrace
console = Console
locals = Locals
cancel = Cancel
[document_tab_popup_menu]
duplicate_view = Duplicate &View
open_with_os = &Open with OS
open_in_folder = Open in &Folder
[dithering_selector]
no_dithering = No Dithering
old_dithering = Old Dithering+
ordered_dithering = Ordered Dithering+
floyd_steinberg = Floyd-Steinberg Error Diffusion Dithering
[canvas_size]
title = Canvas Size
size = Size:
@ -585,6 +657,63 @@ title = Color Mode
amount = Amount:
flatten = Merge layers
[context_bar]
center = Center
fit_screen = Fit Screen
back = Back
pattern_aligned_to_src = Pattern aligned to source
pattern_aligned_to_dest = Pattern aligned to destination
paint_brush = Paint brush
contiguous = Contiguous
stop_at_grid = Stop at Grid
refer_active_layer = Refer only active layer
refer_visible_layer = Refer visible layer
pixel_connectivity = Pixel Connectivity:
select_palette_color = Select colors in the palette
reverse_shade = Reverse Shade
save_shade = Save Shade
transparent_color = Transparent Color
transparent_color_options = Transparent Color Options
opaque = Opaque
transparent = Transparent
auto_adjust_layer = Adjust automatically depending on layer type
default_display_pivot = Display pivot by default
fast_rotation = Fast Rotation
rotsprite = RotSprite
pixel_perfect = Pixel-perfect
linear_gradient = Linear Gradient
radial_gradient = Radial Gradiant
drop_pixel = Drop pixels here (Enter)
cancel_drag = Cancel drag and drop (Esc)
auto_select_layer = Auto Select Layer
all = All
none = None
select_slices = Select All Slices
deselect_slices = Deselect Slices
slice_props = Slice Properties
delete_slice = Delete Slice
discard_brush = Discard Brush (Esc)
brush_type = Brush Type
brush_size = Brush Size (in pixels)
brush_angle = Brush Angle (in degrees)
ink = Ink
opacity = Opacity (paint intensity)
shades = Shades
spray_width = Spray Width
spray_speed = Spray Speed
rotation_pivot = Rotation Pivot
rotation_algorithm = Rotation Algorithm
dynamics = Dynamics
freehand_trace_algorithm = Freehand trace algorithm
contiguous_fill = Fill contiguous areas color
paint_bucket_option = Extra paint bucket options
best_fit_index = Best fit Index
all_layers = All Layers
current_layer = Current Layer
first_ref_layer = First Reference Layer
pick = Pick:
sample = Sample:
[convolution_matrix]
reload_stock = &Reload Stock
@ -647,6 +776,8 @@ cancel = &Cancel
[export_sprite_sheet]
title = Export Sprite Sheet
save_title = Save Sprite Sheet
save_json_title = Save JSON Data
sprite = Sprite
sprite_tooltip = Source of sprite samples to export in the sprite sheet
borders = Borders
@ -734,6 +865,7 @@ open_sprite_sheet = Open Sprite Sheet
export = &Export
cancel = &Cancel
generating = Generating...
generated = Sprite Sheet Generated
[file_selector]
go_back_button_tooltip = Go back one folder
@ -748,15 +880,28 @@ file_name = File name:
file_type = File type:
pinned_folders = Pinned Folders
recent_folders = Recent Folders
all_formats = All formats
all_files = All files
[filters]
selected_cels = Selected
selected_cels_tooltip = Apply to the active selection in the timeline
all_cels = All
all_cels_tooltip = Apply to all cels in the sprite
ok = &OK
cancel = &Cancel
preview = &Preview
tiled = &Tiled
[font_popup]
title = Fonts
load = Load
empty_fonts = No system fonts were found
[frame_combo]
all_frames = All frames
selected_frames = Selected frames
tag = Tag:
[frame_properties]
title = Frame Properties
@ -777,6 +922,7 @@ the given option as the default option.
END
reset = Reset
advanced_options = Advanced Options
unknown = Unknown
[gif_options]
title = GIF Options
@ -823,6 +969,10 @@ new_version_available = New {0} v{1} available!
[import_sprite_sheet]
title = Import Sprite Sheet
type = Type:
type_horz = Horizontal Strip
type_vert = Vertical Strip
type_rows = By Rows
type_cols = By Columns
tiles = Tiles:
x = X:
y = Y:
@ -832,6 +982,8 @@ padding = Padding
horizontal_padding = Horizontal:
vertical_padding = Vertical:
partial_tiles = Include partial tiles at bottom/right edges
context_bar_help = Select bounds to identify sprite frames
layer_name = Sprite Sheet
import = &Import
cancel = &Cancel
@ -854,6 +1006,8 @@ title = Keyboard Shortcuts
import = &Import
export = &Export
reset = &Reset
import_keyboard_sc = Import Keyboard Shortcuts
export_keyboard_sc = Export Keyboard Shortcuts
section_menus = Menus
section_commands = Commands
section_tools = Tools
@ -868,15 +1022,105 @@ drag_angle = Angle:
drag_angle_tooltip = Direction of the mouse to indicate an increment of the value
drag_distance = Distance:
drag_distance_tooltip = Number of pixels for mouse movement to increment/decrement one unit
header_action = Action
header_key = Key
header_context = Context
zoom = Zoom
add = Add
default_action = (Default Action)
scroll_vertically = Scroll Vertically
scroll_horizontally = Scroll Horizontally
fg_color = Color: Foreground Palette Entry
bg_color = Color: Background Palette Entry
fg_tile = Tile: Foreground Tile Entry
bg_tile = Tile: Background Tile Entry
change_frame = Change Frame
change_brush_size = Change Brush Size
change_brush_angle = Change Brush Angle
change_tool = Change Tool
change_tool_same_group = Change Tool (same group)
change_layer = Change Layer
change_ink_type = Change Ink Type
change_ink_opacity = Change Ink Opacity
change_layer_opacity = Change Layer Opacity
change_cel_opacity = Change Cel Opacity
color_alpha = Color: Alpha
color_hsl_hue = Color: HSL Hue
color_hsl_saturation = Color: HSL Saturation
color_hsl_lightness = Color: HSL Lightness
color_hsv_hue = Color: HSV Hue
color_hsv_saturation = Color: HSV Saturation
color_hsv_value = Color: HSV Value
key_context_normal = Normal
key_context_selection = Selection
key_context_translating_selection = Translating Selection
key_context_scaling_selection = Scaling Selection
key_context_rotating_selection = Rotating Selection
key_context_move_tool = Move Tool
key_context_freehand_tool = Freehand Tool
key_context_shape_tool = Shape Tool
copy_selection = Copy Selection
snap_to_grid = Snap To Grid
lock_axis = Lock Axis
fine_translating = Fine Translating
maintain_aspect_ratio = Maintain Aspect Ratio
scale_from_center = Scale From Center
fine_scaling = Fine Scaling
angle_snap = Angle Snap
add_selection = Add Selection
subtract_selection = Subtract Selection
intersect_selection = Intersect Selection
auto_select_layer = Auto Select Layer
line_from_last_point = Straight Line from Last Point
angle_from_last_point = Angle Snap from Last Point
move_origin = Move Origin
square_aspect = Square Aspect
draw_from_center = Draw From Center
rotate_shape = Rotate Shape
trigger_left_mouse_button = Trigger Left Mouse Button
trigger_right_mouse_button = Trigger Right Mouse Button
ok = &OK
cancel = &Cancel
[layer_combo]
group = Group:
layer = Layer:
selected_layers = Selected layers
visible_layers = Visible layers
[layer_properties]
title = Layer Properties
name = Name:
mode = Mode:
opacity = Opacity:
tileset_tooltip = Tileset
normal = Normal
darken = Darken
multiply = Multiply
color_burn = Color Burn
lighten = Lighten
screen = Screen
color_dodge = Color Dodge
addition = Addition
overlay = Overlay
soft_light = Soft Light
hard_light = Hard Light
difference = Difference
exclusion = Exclusion
subtract = Subtract
divide = Divide
hue = Hue
saturation = Saturation
color = Color
luminosity = Luminosity
no_layer = No Layer
flattened = Flattened
[load_palette]
title = Load Palette
[load_selection]
title = Load Selection (.msk file)
[main_menu]
file = &File
@ -1060,11 +1304,23 @@ help_twitter = Twitter
help_enter_license = Enter &License
help_about = &About
[mask_by_color]
title = Select Color
label_color = Color:
tolerance = Tolerance:
preview = &Preview
ok = &OK
cancel = &Cancel
[modify_selection]
title = Modify Selection
circle = Circle Brush
square = Square Brush
[new_brush]
shortcut = Shortcut:
context_bar_help = Select brush bounds | Right-click to cut
[new_folder]
title = New Folder
folder_name = Folder Name:
@ -1076,6 +1332,10 @@ name = Name:
tileset = Tileset:
default_new_layer_name = New Layer
[news_listbox]
more = More...
problem_loading = Problems loading news. Please retry.
[enter_license]
title = Enter License
default_message = If you need a license key, go to
@ -1138,6 +1398,10 @@ default = Default (Octree)
rgb5a3 = Table RGB 5 bits + Alpha 3 bits
octree = Octree
[open_file]
title = Open
loading = Loading file
[open_sequence]
title = Notice
description = Do you want to load the following files as an animation?
@ -1250,6 +1514,13 @@ the Shift key is pressed.
END
discard_brush = Discard custom brush when eyedropper is used
right_click = Right-click:
right_click_paint_bgcolor = Paint with background color
right_click_pick_fgcolor = Pick foreground color
right_click_erase = Erase
right_click_scroll = Scroll
right_click_rectangular_marquee = Rectangular Marquee
right_click_lasso = Lasso
right_click_select_layer_and_move = Select Layer and Move
editor_selection = Selection
auto_opaque = Adjust opaque/transparent mode automatically
auto_opaque_tooltip = <<<END
@ -1330,8 +1601,13 @@ cursor_neg_bw = Negative Black and White
cursor_specific_color = Specific Color
bg_checkered = Checkered Background
bg_size = Size:
bg_custom_size = Custom
bg_apply_zoom = Apply Zoom
bg_colors = Colors:
bg_for_new_docs = Background for New Documents
bg_for_active_doc = Background for the Active Document
grid_for_active_doc = Grid for the Active Document
grid_for_new_docs = Grid for New Documents
grid_visible = Visible Grid
grid_x = X:
grid_y = Y:
@ -1391,6 +1667,7 @@ convert_cs = Convert to working RGB space
assign_cs = Assign working RGB space
ask_cs = Ask
available_themes = Available Themes
extension_themes = Extension Themes
select_theme = &Select
download_themes = Download Themes
open_theme_folder = Open &Folder
@ -1492,6 +1769,13 @@ color = Color:
antialias = Anti-aliasing filter
antialias_tooltip = Smooth font edges
[preview]
title = Preview
speed_x = Speed x{}
play_once = Play Once
play_all_no_tags = Play All Frames (Ignore Tags)
rewind_on_stop = Rewind on Stop
[recover_files]
title = Recover Files
recover_sprite = Recover Sprite
@ -1506,10 +1790,32 @@ old_sessions = Previous Sessions
incompatible = [MIGHT BE INCOMPATIBLE v{1}] {0}
[replace_color]
title = Replace Color
from = From:
to = To:
tolerance = Tolerance:
[remove_slice]
x_removed = Slice '{}' removed
n_slices_removed = {} slice(s) removed
[remove_layer]
x_removed = Layer '{}' removed
layers_removed = Layers removed
[save_file]
title = Save File
save_as = Save As
export = Export
saving = Saving file
saved = File <{}> saved.
[save_palette]
title = Save Palette
[save_selection]
title = Save Selection (.msk file)
[script_access]
title = Security
script_label = The following script:
@ -1590,6 +1896,13 @@ double_high = Double-high Pixels (1:2)
color_profile = Color Profile:
assign_color_profile = Assign
convert_color_profile = Convert
rgb = RGB
grayscale = Grayscale
indexed_color = Indexed ({0} colors)
indexed_image_only = (only for indexed images)
assign_color_profile = Assign Color Profile
convert_color_profile = Convert Color Profile
change_sprite_props = Change Sprite Properties
[sprite_size]
title = Sprite Size
@ -1610,6 +1923,9 @@ lock_ratio = Lock Ratio
percentage = Percentage:
interpolation = Interpolation:
method = Method:
method_nearest_neighbor = Nearest-neighbor
method_bilinear = Bilinear
method_rotsprite = RotSprite
[svg_options]
title = SVG Options

View File

@ -20,6 +20,7 @@
#include "app/cmd/set_layer_name.h"
#include "app/cmd/unlink_cel.h"
#include "app/doc.h"
#include "app/i18n/strings.h"
#include "app/restore_visible_layers.h"
#include "doc/algorithm/shrink_bounds.h"
#include "doc/cel.h"
@ -81,7 +82,7 @@ void FlattenLayers::onExecute()
// Create a new transparent layer to flatten everything onto it.
flatLayer = new LayerImage(sprite);
ASSERT(flatLayer->isVisible());
flatLayer->setName("Flattened");
flatLayer->setName(Strings::layer_properties_flattened());
newFlatLayer = true;
bgcolor = sprite->transparentColor();
}

View File

@ -171,17 +171,13 @@ class ConversionItem : public ListItem {
public:
ConversionItem(const doc::PixelFormat pixelFormat)
: m_pixelFormat(pixelFormat) {
std::string toMode;
switch (pixelFormat) {
case IMAGE_RGB:
setText("-> RGB");
break;
case IMAGE_GRAYSCALE:
setText("-> Grayscale");
break;
case IMAGE_INDEXED:
setText("-> Indexed");
break;
case IMAGE_RGB: toMode = Strings::commands_ChangePixelFormat_RGB(); break;
case IMAGE_GRAYSCALE: toMode = Strings::commands_ChangePixelFormat_Grayscale(); break;
case IMAGE_INDEXED: toMode = Strings::commands_ChangePixelFormat_Indexed(); break;
}
setText(fmt::format("-> {}", toMode));
}
doc::PixelFormat pixelFormat() const { return m_pixelFormat; }
private:
@ -204,11 +200,13 @@ public:
const doc::PixelFormat from = m_editor->sprite()->pixelFormat();
// Add the color mode in the window title
std::string fromMode;
switch (from) {
case IMAGE_RGB: setText(text() + ": RGB"); break;
case IMAGE_GRAYSCALE: setText(text() + ": Grayscale"); break;
case IMAGE_INDEXED: setText(text() + ": Indexed"); break;
case IMAGE_RGB: fromMode = Strings::commands_ChangePixelFormat_RGB(); break;
case IMAGE_GRAYSCALE: fromMode = Strings::commands_ChangePixelFormat_Grayscale(); break;
case IMAGE_INDEXED: fromMode = Strings::commands_ChangePixelFormat_Indexed(); break;
}
setText(fmt::format("{}: {}", text(), fromMode));
// Add conversion items
if (from != IMAGE_RGB)
@ -646,7 +644,7 @@ void ChangePixelFormatCommand::onExecute(Context* context)
{
const ContextReader reader(context);
SpriteJob job(reader, "Color Mode Change");
SpriteJob job(reader, Strings::color_mode_title().c_str());
Sprite* sprite(job.sprite());
// TODO this was moved in the main UI thread because

View File

@ -13,6 +13,7 @@
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/doc_api.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/status_bar.h"
@ -80,7 +81,7 @@ void ClearCelCommand::onExecute(Context* context)
if (nonEditableLayers)
StatusBar::instance()->showTip(1000,
"There are locked layers");
Strings::statusbar_tips_locked_layers());
update_screen_for_document(document);
}

View File

@ -854,7 +854,7 @@ private:
void onImageFilename() {
base::paths newFilename;
if (!app::show_file_selector(
"Save Sprite Sheet", m_filename,
Strings::export_sprite_sheet_save_title(), m_filename,
get_writable_extensions(),
FileSelectorType::Save, newFilename))
return;
@ -879,8 +879,11 @@ private:
base::paths exts = { "json" };
base::paths newFilename;
if (!app::show_file_selector(
"Save JSON Data", m_dataFilename, exts,
FileSelectorType::Save, newFilename))
Strings::export_sprite_sheet_save_json_title(),
m_dataFilename,
exts,
FileSelectorType::Save,
newFilename))
return;
ASSERT(!newFilename.empty());
@ -1335,7 +1338,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
StatusBar* statusbar = StatusBar::instance();
if (statusbar)
statusbar->showTip(1000, "Sprite Sheet Generated");
statusbar->showTip(1000, Strings::export_sprite_sheet_generated());
// Save the exported sprite sheet as a recent file
if (newDocument->isAssociatedToFile())

View File

@ -70,10 +70,10 @@ public:
(int)app::SpriteSheetType::Columns == 4,
"SpriteSheetType enum changed");
sheetType()->addItem("Horizontal Strip");
sheetType()->addItem("Vertical Strip");
sheetType()->addItem("By Rows");
sheetType()->addItem("By Columns");
sheetType()->addItem(Strings::import_sprite_sheet_type_horz());
sheetType()->addItem(Strings::import_sprite_sheet_type_vert());
sheetType()->addItem(Strings::import_sprite_sheet_type_rows());
sheetType()->addItem(Strings::import_sprite_sheet_type_cols());
sheetType()->setSelectedItemIndex((int)app::SpriteSheetType::Rows-1);
sheetType()->Change.connect([this]{ onSheetTypeChange(); });
@ -251,7 +251,7 @@ protected:
}
std::string onGetContextBarHelp() override {
return "Select bounds to identify sprite frames";
return Strings::import_sprite_sheet_context_bar_help();
}
private:
@ -513,11 +513,13 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
// The following steps modify the sprite, so we wrap all
// operations in a undo-transaction.
ContextWriter writer(context);
Tx tx(writer.context(), "Import Sprite Sheet", ModifyDocument);
Tx tx(
writer.context(), Strings::import_sprite_sheet_title(), ModifyDocument);
DocApi api = document->getApi(tx);
// Add the layer in the sprite.
LayerImage* resultLayer = api.newLayer(sprite->root(), "Sprite Sheet");
LayerImage* resultLayer =
api.newLayer(sprite->root(), Strings::import_sprite_sheet_layer_name());
// Add all frames+cels to the new layer
for (size_t i=0; i<animation.size(); ++i) {

View File

@ -80,9 +80,9 @@ public:
class HeaderItem : public ListItem {
public:
HeaderItem()
: m_actionLabel("Action")
, m_keyLabel("Key")
, m_contextLabel("Context") {
: m_actionLabel(Strings::keyboard_shortcuts_header_action())
, m_keyLabel(Strings::keyboard_shortcuts_header_key())
, m_contextLabel(Strings::keyboard_shortcuts_header_context()) {
setBorder(gfx::Border(0));
auto theme = SkinTheme::get(this);
@ -447,7 +447,7 @@ private:
m_addButton->setBgColor(gfx::ColorNone);
m_addButton->setBounds(itemBounds);
m_addButton->setText("Add");
m_addButton->setText(Strings::keyboard_shortcuts_add());
invalidate();
}
@ -481,7 +481,7 @@ private:
std::string getAccelText(const Accelerator& accel) const {
if (m_key && m_key->type() == KeyType::WheelAction &&
accel.isEmpty()) {
return "(Default Action)";
return Strings::keyboard_shortcuts_default_action();
}
else {
return accel.toString();
@ -840,7 +840,7 @@ private:
base::paths exts = { KEYBOARD_FILENAME_EXTENSION };
base::paths filename;
if (!app::show_file_selector(
"Import Keyboard Shortcuts", "", exts,
Strings::keyboard_shortcuts_import_keyboard_sc(), "", exts,
FileSelectorType::Open, filename))
return;
@ -856,7 +856,7 @@ private:
base::paths filename;
if (!app::show_file_selector(
"Export Keyboard Shortcuts", "", exts,
Strings::keyboard_shortcuts_export_keyboard_sc(), "", exts,
FileSelectorType::Save, filename))
return;

View File

@ -21,6 +21,7 @@
#include "app/context_access.h"
#include "app/doc.h"
#include "app/doc_event.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/main_window.h"
@ -79,30 +80,49 @@ public:
name()->setMinSize(gfx::Size(128, 0));
name()->setExpansive(true);
mode()->addItem(new BlendModeItem("Normal", doc::BlendMode::NORMAL));
mode()->addItem(new BlendModeItem(Strings::layer_properties_normal(),
doc::BlendMode::NORMAL));
mode()->addItem(new SeparatorInView);
mode()->addItem(new BlendModeItem("Darken", doc::BlendMode::DARKEN));
mode()->addItem(new BlendModeItem("Multiply", doc::BlendMode::MULTIPLY));
mode()->addItem(new BlendModeItem("Color Burn", doc::BlendMode::COLOR_BURN));
mode()->addItem(new BlendModeItem(Strings::layer_properties_darken(),
doc::BlendMode::DARKEN));
mode()->addItem(new BlendModeItem(Strings::layer_properties_multiply(),
doc::BlendMode::MULTIPLY));
mode()->addItem(new BlendModeItem(Strings::layer_properties_color_burn(),
doc::BlendMode::COLOR_BURN));
mode()->addItem(new SeparatorInView);
mode()->addItem(new BlendModeItem("Lighten", doc::BlendMode::LIGHTEN));
mode()->addItem(new BlendModeItem("Screen", doc::BlendMode::SCREEN));
mode()->addItem(new BlendModeItem("Color Dodge", doc::BlendMode::COLOR_DODGE));
mode()->addItem(new BlendModeItem("Addition", doc::BlendMode::ADDITION));
mode()->addItem(new BlendModeItem(Strings::layer_properties_lighten(),
doc::BlendMode::LIGHTEN));
mode()->addItem(new BlendModeItem(Strings::layer_properties_screen(),
doc::BlendMode::SCREEN));
mode()->addItem(new BlendModeItem(Strings::layer_properties_color_dodge(),
doc::BlendMode::COLOR_DODGE));
mode()->addItem(new BlendModeItem(Strings::layer_properties_addition(),
doc::BlendMode::ADDITION));
mode()->addItem(new SeparatorInView);
mode()->addItem(new BlendModeItem("Overlay", doc::BlendMode::OVERLAY));
mode()->addItem(new BlendModeItem("Soft Light", doc::BlendMode::SOFT_LIGHT));
mode()->addItem(new BlendModeItem("Hard Light", doc::BlendMode::HARD_LIGHT));
mode()->addItem(new BlendModeItem(Strings::layer_properties_overlay(),
doc::BlendMode::OVERLAY));
mode()->addItem(new BlendModeItem(Strings::layer_properties_soft_light(),
doc::BlendMode::SOFT_LIGHT));
mode()->addItem(new BlendModeItem(Strings::layer_properties_hard_light(),
doc::BlendMode::HARD_LIGHT));
mode()->addItem(new SeparatorInView);
mode()->addItem(new BlendModeItem("Difference", doc::BlendMode::DIFFERENCE));
mode()->addItem(new BlendModeItem("Exclusion", doc::BlendMode::EXCLUSION));
mode()->addItem(new BlendModeItem("Subtract", doc::BlendMode::SUBTRACT));
mode()->addItem(new BlendModeItem("Divide", doc::BlendMode::DIVIDE));
mode()->addItem(new BlendModeItem(Strings::layer_properties_difference(),
doc::BlendMode::DIFFERENCE));
mode()->addItem(new BlendModeItem(Strings::layer_properties_exclusion(),
doc::BlendMode::EXCLUSION));
mode()->addItem(new BlendModeItem(Strings::layer_properties_subtract(),
doc::BlendMode::SUBTRACT));
mode()->addItem(new BlendModeItem(Strings::layer_properties_divide(),
doc::BlendMode::DIVIDE));
mode()->addItem(new SeparatorInView);
mode()->addItem(new BlendModeItem("Hue", doc::BlendMode::HSL_HUE));
mode()->addItem(new BlendModeItem("Saturation", doc::BlendMode::HSL_SATURATION));
mode()->addItem(new BlendModeItem("Color", doc::BlendMode::HSL_COLOR));
mode()->addItem(new BlendModeItem("Luminosity", doc::BlendMode::HSL_LUMINOSITY));
mode()->addItem(new BlendModeItem(Strings::layer_properties_hue(),
doc::BlendMode::HSL_HUE));
mode()->addItem(new BlendModeItem(Strings::layer_properties_saturation(),
doc::BlendMode::HSL_SATURATION));
mode()->addItem(new BlendModeItem(Strings::layer_properties_color(),
doc::BlendMode::HSL_COLOR));
mode()->addItem(new BlendModeItem(Strings::layer_properties_luminosity(),
doc::BlendMode::HSL_LUMINOSITY));
name()->Change.connect([this]{ onStartTimer(); });
mode()->Change.connect([this]{ onStartTimer(); });
@ -407,7 +427,7 @@ private:
m_userDataView.entry()->setText(m_layer->userData().text());
}
else {
name()->setText("No Layer");
name()->setText(Strings::layer_properties_no_layer());
name()->setEnabled(false);
mode()->setEnabled(false);
opacity()->setEnabled(false);

View File

@ -12,6 +12,7 @@
#include "app/cmd/copy_cel.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/status_bar.h"
@ -91,7 +92,7 @@ void LinkCelsCommand::onExecute(Context* context)
if (nonEditableLayers)
StatusBar::instance()->showTip(1000,
"There are locked layers");
Strings::statusbar_tips_locked_layers());
update_screen_for_document(document);
}

View File

@ -61,7 +61,7 @@ void LoadMaskCommand::onExecute(Context* context)
base::paths exts = { "msk" };
base::paths selectedFilename;
if (!app::show_file_selector(
"Load .msk File", m_filename, exts,
Strings::load_selection_title(), m_filename, exts,
FileSelectorType::Open, selectedFilename))
return;
@ -77,7 +77,9 @@ void LoadMaskCommand::onExecute(Context* context)
{
ContextWriter writer(reader);
Doc* document = writer.document();
Tx tx(writer.context(), "Mask Load", DoesntModifyDocument);
Tx tx(writer.context(),
Strings::load_selection_title(),
DoesntModifyDocument);
tx(new cmd::SetMask(document, mask.get()));
tx.commit();

View File

@ -66,7 +66,7 @@ void LoadPaletteCommand::onExecute(Context* context)
base::paths exts = get_readable_palette_extensions();
base::paths filenames;
if (app::show_file_selector(
"Load Palette", "", exts,
Strings::load_palette_title(), "", exts,
FileSelectorType::Open, filenames)) {
filename = filenames.front();
}

View File

@ -18,6 +18,7 @@
#include "app/context_access.h"
#include "app/doc.h"
#include "app/ini_file.h"
#include "app/i18n/strings.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/tx.h"
@ -106,7 +107,8 @@ void MaskByColorCommand::onExecute(Context* context)
if (!image)
return;
std::unique_ptr<Window> win(new Window(Window::WithTitleBar, "Mask by Color"));
std::unique_ptr<Window> win(
new Window(Window::WithTitleBar, Strings::mask_by_color_title()));
base::ScopedValue<Window*> setWindow(m_window, win.get(), nullptr);
TooltipManager* tooltipManager = new TooltipManager();
m_window->addChild(tooltipManager);
@ -114,20 +116,20 @@ void MaskByColorCommand::onExecute(Context* context)
auto box2 = new Box(HORIZONTAL);
auto box3 = new Box(HORIZONTAL);
auto box4 = new Box(HORIZONTAL | HOMOGENEOUS);
auto label_color = new Label("Color:");
auto label_color = new Label(Strings::mask_by_color_label_color());
m_buttonColor = new ColorButton(
ColorBar::instance()->getFgColor(),
sprite->pixelFormat(),
ColorButtonOptions());
auto label_tolerance = new Label("Tolerance:");
auto label_tolerance = new Label(Strings::mask_by_color_tolerance());
m_sliderTolerance = new Slider(0, 255, get_config_int(ConfigSection, "Tolerance", 0));
m_selMode = new SelModeField;
m_selMode->setupTooltips(tooltipManager);
m_checkPreview = new CheckBox("&Preview");
auto button_ok = new Button("&OK");
auto button_cancel = new Button("&Cancel");
m_checkPreview = new CheckBox(Strings::mask_by_color_preview());
auto button_ok = new Button(Strings::mask_by_color_ok());
auto button_cancel = new Button(Strings::mask_by_color_cancel());
m_checkPreview->processMnemonicFromText();
button_ok->processMnemonicFromText();

View File

@ -15,6 +15,7 @@
#include "app/commands/commands.h"
#include "app/console.h"
#include "app/context_access.h"
#include "app/i18n/strings.h"
#include "app/modules/editors.h"
#include "app/tools/active_tool.h"
#include "app/tools/ink.h"
@ -46,7 +47,7 @@ protected:
void onQuickboxCancel(Editor* editor) override;
std::string onGetContextBarHelp() override {
return "Select brush bounds | Right-click to cut";
return Strings::new_brush_context_bar_help();
}
private:
@ -173,7 +174,7 @@ void NewBrushCommand::createBrush(const Site& site, const Mask* mask)
CommandId::ChangeBrush(), params);
if (key && !key->accels().empty()) {
std::string tooltip;
tooltip += "Shortcut: ";
tooltip += Strings::new_brush_shortcut() + " ";
tooltip += key->accels().front().toString();
StatusBar::instance()->showTip(2000, tooltip);
}

View File

@ -18,6 +18,7 @@
#include "app/doc.h"
#include "app/file/file.h"
#include "app/file_selector.h"
#include "app/i18n/strings.h"
#include "app/job.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
@ -37,7 +38,7 @@ namespace app {
class OpenFileJob : public Job, public IFileOpProgress {
public:
OpenFileJob(FileOp* fop)
: Job("Loading file")
: Job(Strings::open_file_loading().c_str())
, m_fop(fop)
{
}
@ -122,7 +123,7 @@ void OpenFileCommand::onExecute(Context* context)
if (!m_folder.empty() && !base::is_path_separator(m_folder[m_folder.size()-1]))
m_folder.push_back(base::path_separator);
if (!app::show_file_selector("Open", m_folder, exts,
if (!app::show_file_selector(Strings::open_file_title(), m_folder, exts,
FileSelectorType::OpenMultiple,
filenames)) {
// The user cancelled the operation through UI

View File

@ -472,14 +472,14 @@ public:
discardBrush()->setSelected(true);
// Scope
bgScope()->addItem("Background for New Documents");
gridScope()->addItem("Grid for New Documents");
bgScope()->addItem(Strings::options_bg_for_new_docs());
gridScope()->addItem(Strings::options_grid_for_new_docs());
if (context->activeDocument()) {
bgScope()->addItem("Background for the Active Document");
bgScope()->addItem(Strings::options_bg_for_active_doc());
bgScope()->setSelectedItemIndex(1);
bgScope()->Change.connect([this]{ onChangeBgScope(); });
gridScope()->addItem("Grid for the Active Document");
gridScope()->addItem(Strings::options_grid_for_active_doc());
gridScope()->setSelectedItemIndex(1);
gridScope()->Change.connect([this]{ onChangeGridScope(); });
}
@ -526,13 +526,13 @@ public:
static_assert(int(app::gen::RightClickMode::LASSO) == 5, "");
static_assert(int(app::gen::RightClickMode::SELECT_LAYER_AND_MOVE) == 6, "");
rightClickBehavior()->addItem("Paint with background color");
rightClickBehavior()->addItem("Pick foreground color");
rightClickBehavior()->addItem("Erase");
rightClickBehavior()->addItem("Scroll");
rightClickBehavior()->addItem("Rectangular Marquee");
rightClickBehavior()->addItem("Lasso");
rightClickBehavior()->addItem("Select Layer & Move");
rightClickBehavior()->addItem(Strings::options_right_click_paint_bgcolor());
rightClickBehavior()->addItem(Strings::options_right_click_pick_fgcolor());
rightClickBehavior()->addItem(Strings::options_right_click_erase());
rightClickBehavior()->addItem(Strings::options_right_click_scroll());
rightClickBehavior()->addItem(Strings::options_right_click_rectangular_marquee());
rightClickBehavior()->addItem(Strings::options_right_click_lasso());
rightClickBehavior()->addItem(Strings::options_right_click_select_layer_and_move());
rightClickBehavior()->setSelectedItemIndex((int)m_pref.editor.rightClickMode());
#ifndef __APPLE__ // Zoom sliding two fingers option only on macOS
@ -548,7 +548,7 @@ public:
checkeredBgSize()->addItem("4x4");
checkeredBgSize()->addItem("2x2");
checkeredBgSize()->addItem("1x1");
checkeredBgSize()->addItem("Custom");
checkeredBgSize()->addItem(Strings::options_bg_custom_size());
checkeredBgSize()->Change.connect([this]{ onCheckeredBgSizeChange(); });
// Reset buttons
@ -1339,7 +1339,7 @@ private:
if (first) {
first = false;
themeList()->addChild(
new SeparatorInView("Extension Themes", HORIZONTAL));
new SeparatorInView(Strings::options_extension_themes(), HORIZONTAL));
}
for (auto it : ext->themes()) {

View File

@ -97,9 +97,11 @@ void RemoveLayerCommand::onExecute(Context* context)
StatusBar::instance()->invalidate();
if (!layerName.empty())
StatusBar::instance()->showTip(1000, fmt::format("Layer '{}' removed", layerName));
StatusBar::instance()->showTip(
1000, fmt::format(Strings::remove_layer_x_removed(), layerName));
else
StatusBar::instance()->showTip(1000, "Layers removed");
StatusBar::instance()->showTip(1000,
Strings::remove_layer_layers_removed());
}
#endif
}

View File

@ -14,6 +14,7 @@
#include "app/cmd/set_slice_key.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/status_bar.h"
@ -122,10 +123,12 @@ void RemoveSliceCommand::onExecute(Context* context)
StatusBar::instance()->invalidate();
if (!sliceName.empty())
StatusBar::instance()->showTip(
1000, fmt::format("Slice '{}' removed", sliceName));
1000, fmt::format(Strings::remove_slice_x_removed(), sliceName));
else
StatusBar::instance()->showTip(
1000, fmt::format("{} slice(s) removed", slicesToDelete.size()));
1000,
fmt::format(Strings::remove_slice_n_slices_removed(),
slicesToDelete.size()));
}
Command* CommandFactory::createRemoveSliceCommand()

View File

@ -46,8 +46,10 @@ class RotateJob : public SpriteJob {
public:
RotateJob(const ContextReader& reader, int angle, const CelList& cels, bool rotateSprite)
: SpriteJob(reader, "Rotate Canvas")
RotateJob(const ContextReader& reader,
const std::string& jobName,
int angle, const CelList& cels, bool rotateSprite)
: SpriteJob(reader, jobName.c_str())
, m_cels(cels)
, m_rotateSprite(rotateSprite) {
m_angle = angle;
@ -237,7 +239,7 @@ void RotateCommand::onExecute(Context* context)
ContextReader reader(context);
{
RotateJob job(reader, m_angle, cels, rotateSprite);
RotateJob job(reader, friendlyName(), m_angle, cels, rotateSprite);
job.startJob();
job.waitJob();
}

View File

@ -49,7 +49,7 @@ namespace app {
class SaveFileJob : public Job, public IFileOpProgress {
public:
SaveFileJob(FileOp* fop)
: Job("Saving file")
: Job(Strings::save_file_saving().c_str())
, m_fop(fop)
{
}
@ -254,7 +254,7 @@ void SaveFileBaseCommand::saveDocumentInBackground(
#ifdef ENABLE_UI
if (context->isUIAvailable() && params().ui()) {
StatusBar::instance()->setStatusText(
2000, fmt::format("File <{}> saved.",
2000, fmt::format(Strings::save_file_saved(),
base::get_file_name(filename)));
}
#endif
@ -298,7 +298,7 @@ void SaveFileCommand::onExecute(Context* context)
// save-as dialog to the user to select for first time the file-name
// for this document.
else {
saveAsDialog(context, "Save File",
saveAsDialog(context, Strings::save_file_title(),
(params().filename.isSet() ? params().filename():
document->filename()),
MarkAsSaved::On);
@ -321,7 +321,7 @@ SaveFileAsCommand::SaveFileAsCommand()
void SaveFileAsCommand::onExecute(Context* context)
{
Doc* document = context->activeDocument();
saveAsDialog(context, "Save As",
saveAsDialog(context, Strings::save_file_save_as(),
(params().filename.isSet() ? params().filename():
document->filename()),
MarkAsSaved::On);
@ -366,7 +366,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
[this, &win, &askOverwrite, context, doc]() -> std::string {
std::string result =
saveAsDialog(
context, "Export",
context, Strings::save_file_export(),
win.outputFilenameValue(),
MarkAsSaved::Off,
SaveInBackground::Off,

View File

@ -48,7 +48,7 @@ void SaveMaskCommand::onExecute(Context* context)
base::paths exts = { "msk" };
base::paths selFilename;
if (!app::show_file_selector(
"Save .msk File", "default.msk", exts,
Strings::save_selection_title(), "default.msk", exts,
FileSelectorType::Save, selFilename))
return;

View File

@ -64,9 +64,10 @@ void SavePaletteCommand::onExecute(Context* ctx)
base::paths exts = get_writable_palette_extensions();
base::paths selFilename;
std::string initialPath = (m_saveAsPreset ? get_preset_palettes_dir(): "");
if (!app::show_file_selector(
"Save Palette", initialPath, exts,
FileSelectorType::Save, selFilename))
if (!app::show_file_selector(Strings::save_palette_title(),
initialPath,
exts,
FileSelectorType::Save, selFilename))
return;
filename = selFilename.front();

View File

@ -122,18 +122,18 @@ void SpritePropertiesCommand::onExecute(Context* context)
// Update widgets values
switch (sprite->pixelFormat()) {
case IMAGE_RGB:
imgtype_text = "RGB";
imgtype_text = Strings::sprite_properties_rgb();
break;
case IMAGE_GRAYSCALE:
imgtype_text = "Grayscale";
imgtype_text = Strings::sprite_properties_grayscale();
break;
case IMAGE_INDEXED:
imgtype_text = fmt::format("Indexed ({0} colors)",
imgtype_text = fmt::format(Strings::sprite_properties_indexed_color(),
sprite->palette(0)->size());
break;
default:
ASSERT(false);
imgtype_text = "Unknown";
imgtype_text = Strings::general_unknown();
break;
}
@ -169,7 +169,8 @@ void SpritePropertiesCommand::onExecute(Context* context)
LEFT);
}
else {
window.transparentColorPlaceholder()->addChild(new Label("(only for indexed images)"));
window.transparentColorPlaceholder()->addChild(
new Label(Strings::sprite_properties_indexed_image_only()));
}
// Pixel ratio
@ -205,7 +206,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
ContextWriter writer(context);
Sprite* sprite(writer.sprite());
Tx tx(writer.context(), "Assign Color Profile");
Tx tx(writer.context(), Strings::sprite_properties_assign_color_profile());
tx(new cmd::AssignColorProfile(
sprite, colorSpaces[selectedColorProfile]->gfxColorSpace()));
tx.commit();
@ -218,7 +219,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
ContextWriter writer(context);
Sprite* sprite(writer.sprite());
Tx tx(writer.context(), "Convert Color Profile");
Tx tx(writer.context(), Strings::sprite_properties_convert_color_profile());
tx(new cmd::ConvertColorProfile(
sprite, colorSpaces[selectedColorProfile]->gfxColorSpace()));
tx.commit();
@ -248,7 +249,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
if (index != sprite->transparentColor() ||
pixelRatio != sprite->pixelRatio() ||
newUserData != sprite->userData()) {
Tx tx(writer.context(), "Change Sprite Properties");
Tx tx(writer.context(), Strings::sprite_properties_change_sprite_props());
DocApi api = writer.document()->getApi(tx);
if (index != sprite->transparentColor())

View File

@ -17,6 +17,7 @@
#include "app/commands/params.h"
#include "app/doc_api.h"
#include "app/ini_file.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/sprite_job.h"
@ -80,7 +81,7 @@ class SpriteSizeJob : public SpriteJob {
public:
SpriteSizeJob(const ContextReader& reader, int new_width, int new_height, ResizeMethod resize_method)
: SpriteJob(reader, "Sprite Size") {
: SpriteJob(reader, Strings::sprite_size_title().c_str()) {
m_new_width = new_width;
m_new_height = new_height;
m_resize_method = resize_method;
@ -263,9 +264,9 @@ public:
doc::algorithm::RESIZE_METHOD_BILINEAR == 1 &&
doc::algorithm::RESIZE_METHOD_ROTSPRITE == 2,
"ResizeMethod enum has changed");
method()->addItem("Nearest-neighbor");
method()->addItem("Bilinear");
method()->addItem("RotSprite");
method()->addItem(Strings::sprite_size_method_nearest_neighbor());
method()->addItem(Strings::sprite_size_method_bilinear());
method()->addItem(Strings::sprite_size_method_rotsprite());
int resize_method;
if (params.method.isSet())
resize_method = (int)params.method();

View File

@ -12,6 +12,7 @@
#include "app/cmd/unlink_cel.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/status_bar.h"
@ -84,7 +85,7 @@ void UnlinkCelCommand::onExecute(Context* context)
if (nonEditableLayers)
StatusBar::instance()->showTip(1000,
"There are locked layers");
Strings::statusbar_tips_locked_layers());
update_screen_for_document(document);
}

View File

@ -20,12 +20,7 @@ Command::Command(const char* id, CommandFlags flags)
: m_id(id)
, m_flags(flags)
{
std::string strId = "commands.";
strId += this->id();
if (auto s = Strings::instance())
m_friendlyName = s->translate(strId.c_str());
else
m_friendlyName = strId;
generateFriendlyName();
}
Command::~Command()
@ -69,6 +64,15 @@ bool Command::isChecked(Context* context)
}
}
void Command::generateFriendlyName()
{
std::string strId = "commands." + this->id();
if (auto s = Strings::instance())
m_friendlyName = s->translate(strId.c_str());
else
m_friendlyName = strId;
}
void Command::execute(Context* context)
{
onExecute(context);

View File

@ -35,6 +35,7 @@ namespace app {
void loadParams(const Params& params);
bool isEnabled(Context* context);
bool isChecked(Context* context);
void generateFriendlyName();
protected:
virtual bool onNeedsParams() const;

View File

@ -17,6 +17,7 @@
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/ini_file.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/ui/color_button.h"
#include "app/ui/color_sliders.h"
@ -47,16 +48,20 @@ class BrightnessContrastWindow : public FilterWindow {
public:
BrightnessContrastWindow(BrightnessContrastFilter& filter,
FilterManagerImpl& filterMgr)
: FilterWindow("Brightness/Contrast", ConfigSection, &filterMgr,
: FilterWindow(Strings::brightness_contrast_title().c_str(),
ConfigSection,
&filterMgr,
WithChannelsSelector,
WithoutTiledCheckBox)
, m_brightness(-100, 100, int(100.0 * filter.brightness()))
, m_contrast(-100, 100, int(100.0 * filter.contrast()))
, m_filter(filter)
{
getContainer()->addChild(new ui::Label("Brightness:"));
getContainer()->addChild(
new ui::Label(Strings::brightness_contrast_brightness_label()));
getContainer()->addChild(&m_brightness);
getContainer()->addChild(new ui::Label("Contrast:"));
getContainer()->addChild(
new ui::Label(Strings::brightness_contrast_contrast_label()));
getContainer()->addChild(&m_contrast);
m_brightness.Change.connect([this]{ onChange(); });
m_contrast.Change.connect([this]{ onChange(); });

View File

@ -22,6 +22,7 @@
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/find_widget.h"
#include "app/i18n/strings.h"
#include "app/ini_file.h"
#include "app/load_widget.h"
#include "app/pref/preferences.h"
@ -78,7 +79,9 @@ static const char* ConfigSection = "ReplaceColor";
class ReplaceColorWindow : public FilterWindow {
public:
ReplaceColorWindow(ReplaceColorFilterWrapper& filter, FilterManagerImpl& filterMgr)
: FilterWindow("Replace Color", ConfigSection, &filterMgr,
: FilterWindow(Strings::replace_color_title().c_str(),
ConfigSection,
&filterMgr,
WithChannelsSelector,
WithoutTiledCheckBox)
, m_filter(filter)

View File

@ -13,6 +13,7 @@
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_worker.h"
#include "app/i18n/strings.h"
#include "app/ini_file.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
@ -35,12 +36,14 @@ FilterWindow::FilterWindow(const char* title, const char* cfgSection,
, m_hbox(HORIZONTAL)
, m_vbox(VERTICAL)
, m_container(VERTICAL)
, m_okButton("&OK")
, m_cancelButton("&Cancel")
, m_okButton(Strings::filters_ok())
, m_cancelButton(Strings::filters_cancel())
, m_preview(filterMgr)
, m_targetButton(filterMgr->pixelFormat(), (withChannels == WithChannelsSelector))
, m_showPreview("&Preview")
, m_tiledCheck(withTiled == WithTiledCheckBox ? new CheckBox("&Tiled") : NULL)
, m_showPreview(Strings::filters_preview())
, m_tiledCheck(withTiled == WithTiledCheckBox ?
new CheckBox(Strings::filters_tiled()) :
nullptr)
{
m_okButton.processMnemonicFromText();
m_cancelButton.processMnemonicFromText();

View File

@ -170,8 +170,8 @@ void FilterWorker::run()
console.printf("A problem has occurred.\n\nDetails:\n%s", m_error.c_str());
}
else if (m_cancelled && !m_filterMgr->isTransaction()) {
StatusBar::instance()
->showTip(2500, "No unlocked layers to apply filter");
StatusBar::instance()->showTip(2500,
Strings::statusbar_tips_filter_no_unlocked_layer());
}
#endif // ENABLE_UI
}

View File

@ -13,6 +13,7 @@
#include "app/app.h"
#include "app/context.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/ui/main_window.h"
#include "app/ui/status_bar.h"
@ -35,9 +36,9 @@ Console::ConsoleWindow* Console::m_console = nullptr;
class Console::ConsoleWindow final : public Window {
public:
ConsoleWindow() : Window(Window::WithTitleBar, "Console"),
ConsoleWindow() : Window(Window::WithTitleBar, Strings::debugger_console()),
m_textbox("", WORDWRAP),
m_button("Cancel") {
m_button(Strings::debugger_cancel()) {
TRACE_CON("CON: ConsoleWindow this=", this);
m_button.Click.connect([this]{ closeWindow(&m_button); });

View File

@ -10,6 +10,7 @@
#endif
#include "app/tools/ink_type.h"
#include "app/i18n/strings.h"
namespace app {
namespace tools {
@ -17,13 +18,13 @@ namespace tools {
std::string ink_type_to_string(InkType inkType)
{
switch (inkType) {
case tools::InkType::SIMPLE: return "Simple Ink";
case tools::InkType::ALPHA_COMPOSITING: return "Alpha Compositing";
case tools::InkType::COPY_COLOR: return "Copy Color+Alpha";
case tools::InkType::LOCK_ALPHA: return "Lock Alpha";
case tools::InkType::SHADING: return "Shading";
case tools::InkType::SIMPLE: return Strings::inks_simple_ink();
case tools::InkType::ALPHA_COMPOSITING: return Strings::inks_alpha_compositing();
case tools::InkType::COPY_COLOR: return Strings::inks_copy_color();
case tools::InkType::LOCK_ALPHA: return Strings::inks_lock_alpha();
case tools::InkType::SHADING: return Strings::inks_shading();
}
return "Unknown";
return Strings::general_unknown();
}
std::string ink_type_to_string_id(InkType inkType)

View File

@ -15,6 +15,7 @@
#include "app/brush_slot.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/pref/preferences.h"
@ -160,10 +161,10 @@ private:
void onClick() override {
Menu menu;
AppMenuItem save("Save Brush Here");
AppMenuItem lockItem("Locked");
AppMenuItem deleteItem("Delete");
AppMenuItem deleteAllItem("Delete All");
AppMenuItem save(Strings::brush_slot_params_save_brush());
AppMenuItem lockItem(Strings::brush_slot_params_locked());
AppMenuItem deleteItem(Strings::brush_slot_params_delete());
AppMenuItem deleteAllItem(Strings::brush_slot_params_delete_all());
lockItem.setSelected(m_brushes.isBrushSlotLocked(m_slot));
@ -179,7 +180,8 @@ private:
menu.addChild(new MenuSeparator);
menu.addChild(&deleteAllItem);
menu.addChild(new Label(""));
menu.addChild(new Separator("Saved Parameters", HORIZONTAL));
menu.addChild(
new Separator(Strings::brush_slot_params_saved_parameters(), HORIZONTAL));
app::gen::BrushSlotParams params;
menu.addChild(&params);
@ -263,7 +265,7 @@ private:
class NewCustomBrushItem : public ButtonSet::Item {
public:
NewCustomBrushItem() {
setText("Save Brush");
setText(Strings::brush_slot_params_save_brush());
}
private:

View File

@ -1456,7 +1456,7 @@ void ColorBar::onReverseColors()
}
Palette newPalette(*get_current_palette(), remap);
setPalette(&newPalette, "Reverse Colors");
setPalette(&newPalette, Strings::color_bar_reverse_colors());
}
void ColorBar::onSortBy(SortPaletteBy channel)
@ -1500,7 +1500,7 @@ void ColorBar::onSortBy(SortPaletteBy channel)
// Create a new palette and apply the remap. This is the final new
// palette for the sprite.
Palette newPalette(palette, remapOrig);
setPalette(&newPalette, "Sort Colors");
setPalette(&newPalette, Strings::color_bar_sort_colors());
}
void ColorBar::onGradient(GradientType gradientType)
@ -1512,11 +1512,11 @@ void ColorBar::onGradient(GradientType gradientType)
Palette newPalette(*get_current_palette());
if (gradientType == GradientType::LINEAR) {
newPalette.makeGradient(index1, index2);
setPalette(&newPalette, "Gradient");
setPalette(&newPalette, Strings::color_bar_gradient());
}
else {
newPalette.makeHueGradient(index1, index2);
setPalette(&newPalette, "Gradient by Hue");
setPalette(&newPalette, Strings::color_bar_gradient_by_hue());
}
}
@ -1919,19 +1919,19 @@ void ColorBar::showPaletteSortOptions()
Menu menu;
MenuItem
rev("Reverse Colors"),
grd("Gradient"),
grh("Gradient by Hue"),
hue("Sort by Hue"),
sat("Sort by Saturation"),
bri("Sort by Brightness"),
lum("Sort by Luminance"),
red("Sort by Red"),
grn("Sort by Green"),
blu("Sort by Blue"),
alp("Sort by Alpha"),
asc("Ascending"),
des("Descending");
rev(Strings::color_bar_reverse_colors()),
grd(Strings::color_bar_gradient()),
grh(Strings::color_bar_gradient_by_hue()),
hue(Strings::color_bar_sort_by_hue()),
sat(Strings::color_bar_sort_by_saturation()),
bri(Strings::color_bar_sort_by_brightness()),
lum(Strings::color_bar_sort_by_luminance()),
red(Strings::color_bar_sort_by_red()),
grn(Strings::color_bar_sort_by_green()),
blu(Strings::color_bar_sort_by_blue()),
alp(Strings::color_bar_sort_by_alpha()),
asc(Strings::color_bar_ascending()),
des(Strings::color_bar_descending());
menu.addChild(&rev);
menu.addChild(&grd);
menu.addChild(&grh);

View File

@ -19,6 +19,7 @@
#include "app/context_access.h"
#include "app/doc.h"
#include "app/file/palette_file.h"
#include "app/i18n/strings.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
@ -179,7 +180,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options)
nullptr)
, m_simpleColors(nullptr)
, m_oldAndNew(Shade(2), ColorShades::ClickEntries)
, m_maskLabel("Transparent Color Selected")
, m_maskLabel(Strings::color_popup_transparent_color_sel())
, m_canPin(options.canPinSelector)
, m_insideChange(false)
, m_disableHexUpdate(false)
@ -196,7 +197,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options)
m_simpleColors = new SimpleColors(this, &m_tooltips);
}
ButtonSet::Item* item = m_colorType.addItem("Index");
ButtonSet::Item* item = m_colorType.addItem(Strings::color_popup_index());
item->setFocusStop(false);
if (!options.showIndexTab)
item->setVisible(false);

View File

@ -12,6 +12,7 @@
#include "app/ui/color_wheel.h"
#include "app/color_utils.h"
#include "app/i18n/strings.h"
#include "app/pref/preferences.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
@ -474,15 +475,15 @@ void ColorWheel::onResize(ui::ResizeEvent& ev)
void ColorWheel::onOptions()
{
Menu menu;
MenuItem discrete("Discrete");
MenuItem none("Without Harmonies");
MenuItem complementary("Complementary");
MenuItem monochromatic("Monochromatic");
MenuItem analogous("Analogous");
MenuItem split("Split-Complementary");
MenuItem triadic("Triadic");
MenuItem tetradic("Tetradic");
MenuItem square("Square");
MenuItem discrete(Strings::color_wheel_discrete());
MenuItem none(Strings::color_wheel_no_harmonies());
MenuItem complementary(Strings::color_wheel_complementary());
MenuItem monochromatic(Strings::color_wheel_monochromatic());
MenuItem analogous(Strings::color_wheel_analogous());
MenuItem split(Strings::color_wheel_split_complementary());
MenuItem triadic(Strings::color_wheel_triadic());
MenuItem tetradic(Strings::color_wheel_tetradic());
MenuItem square(Strings::color_wheel_square());
menu.addChild(&discrete);
if (m_colorModel != ColorModel::NORMAL_MAP) {
menu.addChild(new MenuSeparator);

View File

@ -97,8 +97,8 @@ public:
ZoomButtons()
: ButtonSet(3) {
addItem("100%");
addItem("Center");
addItem("Fit Screen");
addItem(Strings::context_bar_center());
addItem(Strings::context_bar_fit_screen());
}
private:
@ -142,7 +142,7 @@ class ContextBar::BrushBackField : public ButtonSet {
public:
BrushBackField()
: ButtonSet(1) {
addItem("Back");
addItem(Strings::context_bar_back());
}
protected:
@ -294,9 +294,9 @@ public:
// brush when we call ComboBox::addItem() (because the first
// addItem() generates an onChange() event).
m_lock = true;
addItem("Pattern aligned to source");
addItem("Pattern aligned to destination");
addItem("Paint brush");
addItem(Strings::context_bar_pattern_aligned_to_src());
addItem(Strings::context_bar_pattern_aligned_to_dest());
addItem(Strings::context_bar_paint_brush());
m_lock = false;
setSelectedItemIndex((int)Preferences::instance().brush.pattern());
@ -356,7 +356,8 @@ protected:
class ContextBar::ContiguousField : public CheckBox {
public:
ContiguousField() : CheckBox("Contiguous") {
ContiguousField()
: CheckBox(Strings::context_bar_contiguous()) {
initTheme();
}
@ -393,16 +394,16 @@ protected:
Menu menu;
MenuItem
stopAtGrid("Stop at Grid"),
activeLayer("Refer only active layer"),
allLayers("Refer visible layers");
stopAtGrid(Strings::context_bar_stop_at_grid()),
activeLayer(Strings::context_bar_refer_active_layer()),
allLayers(Strings::context_bar_refer_visible_layer());
menu.addChild(&stopAtGrid);
menu.addChild(new MenuSeparator());
menu.addChild(&activeLayer);
menu.addChild(&allLayers);
menu.addChild(new MenuSeparator);
menu.addChild(new Label("Pixel Connectivity:"));
menu.addChild(new Label(Strings::context_bar_pixel_connectivity()));
HBox box;
ButtonSet buttonset(2);
@ -525,7 +526,7 @@ public:
addChild(&m_button);
addChild(&m_shade);
m_shade.setText("Select colors in the palette");
m_shade.setText(Strings::context_bar_select_palette_color());
m_shade.setMinColors(2);
m_conn = colorBar->ChangeSelection.connect(
[this]{ onChangeColorBarSelection(); });
@ -582,8 +583,8 @@ private:
Menu menu;
MenuItem
reverse("Reverse Shade"),
save("Save Shade");
reverse(Strings::context_bar_reverse_shade()),
save(Strings::context_bar_save_shade());
menu.addChild(&reverse);
menu.addChild(&save);
@ -786,8 +787,10 @@ public:
onOpaqueChange();
tooltipManager->addTooltipFor(m_icon.at(0), "Transparent Color Options", BOTTOM);
tooltipManager->addTooltipFor(&m_maskColor, "Transparent Color", BOTTOM);
tooltipManager->addTooltipFor(
m_icon.at(0), Strings::context_bar_transparent_color_options(), BOTTOM);
tooltipManager->addTooltipFor(
&m_maskColor, Strings::context_bar_transparent_color(), BOTTOM);
}
private:
@ -797,9 +800,9 @@ private:
Menu menu;
MenuItem
opaque("Opaque"),
masked("Transparent"),
automatic("Adjust automatically depending on layer type");
opaque(Strings::context_bar_opaque()),
masked(Strings::context_bar_transparent()),
automatic(Strings::context_bar_auto_adjust_layer());
menu.addChild(&opaque);
menu.addChild(&masked);
menu.addChild(new MenuSeparator);
@ -878,7 +881,7 @@ private:
gfx::Rect bounds = this->bounds();
Menu menu;
CheckBox visible("Display pivot by default");
CheckBox visible(Strings::context_bar_default_display_pivot());
HBox box;
ButtonSet buttonset(3);
buttonset.addItem(theme->parts.pivotNorthwest());
@ -945,8 +948,10 @@ public:
// algorithm when we call ComboBox::addItem() (because the first
// addItem() generates an onChange() event).
m_lockChange = true;
addItem(new Item("Fast Rotation", tools::RotationAlgorithm::FAST));
addItem(new Item("RotSprite", tools::RotationAlgorithm::ROTSPRITE));
addItem(
new Item(Strings::context_bar_fast_rotation(), tools::RotationAlgorithm::FAST));
addItem(
new Item(Strings::context_bar_rotsprite(), tools::RotationAlgorithm::ROTSPRITE));
m_lockChange = false;
setSelectedItemIndex((int)Preferences::instance().selection.rotationAlgorithm());
@ -1219,7 +1224,9 @@ private:
class ContextBar::FreehandAlgorithmField : public CheckBox {
public:
FreehandAlgorithmField() : CheckBox("Pixel-perfect") {
FreehandAlgorithmField()
: CheckBox(Strings::context_bar_pixel_perfect())
{
initTheme();
}
@ -1277,8 +1284,10 @@ public:
}
void setupTooltips(TooltipManager* tooltipManager) {
tooltipManager->addTooltipFor(at(0), "Linear Gradient", BOTTOM);
tooltipManager->addTooltipFor(at(1), "Radial Gradient", BOTTOM);
tooltipManager->addTooltipFor(
at(0), Strings::context_bar_linear_gradient(), BOTTOM);
tooltipManager->addTooltipFor(
at(1), Strings::context_bar_radial_gradient(), BOTTOM);
}
render::GradientType gradientType() const {
@ -1298,8 +1307,8 @@ public:
void setupTooltips(TooltipManager* tooltipManager) {
// TODO Enter and Esc should be configurable keys
tooltipManager->addTooltipFor(at(0), "Drop pixels here (Enter)", BOTTOM);
tooltipManager->addTooltipFor(at(1), "Cancel drag and drop (Esc)", BOTTOM);
tooltipManager->addTooltipFor(at(0), Strings::context_bar_drop_pixel(), BOTTOM);
tooltipManager->addTooltipFor(at(1), Strings::context_bar_cancel_drag(), BOTTOM);
}
obs::signal<void(ContextBarObserver::DropAction)> DropPixels;
@ -1329,15 +1338,15 @@ public:
m_channel.addItem("HSL");
m_channel.addItem("Gray+Alpha");
m_channel.addItem("Gray");
m_channel.addItem("Best fit Index");
m_channel.addItem(Strings::context_bar_best_fit_index());
m_sample.addItem("All Layers");
m_sample.addItem("Current Layer");
m_sample.addItem("First Reference Layer");
m_sample.addItem(Strings::context_bar_all_layers());
m_sample.addItem(Strings::context_bar_current_layer());
m_sample.addItem(Strings::context_bar_first_ref_layer());
addChild(new Label("Pick:"));
addChild(new Label(Strings::context_bar_pick()));
addChild(&m_channel);
addChild(new Label("Sample:"));
addChild(new Label(Strings::context_bar_sample()));
addChild(&m_sample);
m_channel.Change.connect([this]{ onChannelChange(); });
@ -1366,7 +1375,9 @@ private:
class ContextBar::AutoSelectLayerField : public CheckBox {
public:
AutoSelectLayerField() : CheckBox("Auto Select Layer") {
AutoSelectLayerField()
: CheckBox(Strings::context_bar_auto_select_layer())
{
initTheme();
}
@ -1521,8 +1532,8 @@ public:
{
auto theme = SkinTheme::get(this);
m_sel.addItem("All");
m_sel.addItem("None");
m_sel.addItem(Strings::context_bar_all());
m_sel.addItem(Strings::context_bar_none());
m_sel.ItemChange.connect(
[this](ButtonSet::Item* item){
onSelAction(m_sel.selectedItem());
@ -1548,10 +1559,14 @@ public:
}
void setupTooltips(TooltipManager* tooltipManager) {
tooltipManager->addTooltipFor(m_sel.at(0), "Select All Slices", BOTTOM);
tooltipManager->addTooltipFor(m_sel.at(1), "Deselect Slices", BOTTOM);
tooltipManager->addTooltipFor(m_action.at(0), "Slice Properties", BOTTOM);
tooltipManager->addTooltipFor(m_action.at(1), "Delete Slice", BOTTOM);
tooltipManager->addTooltipFor(
m_sel.at(0), Strings::context_bar_select_slices(), BOTTOM);
tooltipManager->addTooltipFor(
m_sel.at(1), Strings::context_bar_deselect_slices(), BOTTOM);
tooltipManager->addTooltipFor(
m_action.at(0), Strings::context_bar_slice_props(), BOTTOM);
tooltipManager->addTooltipFor(
m_action.at(1), Strings::context_bar_delete_slice(), BOTTOM);
}
void setDoc(Doc* doc) {
@ -2448,26 +2463,38 @@ const tools::DynamicsOptions& ContextBar::getDynamics() const
void ContextBar::setupTooltips(TooltipManager* tooltipManager)
{
tooltipManager->addTooltipFor(m_brushBack->at(0), "Discard Brush (Esc)", BOTTOM);
tooltipManager->addTooltipFor(m_brushType->at(0), "Brush Type", BOTTOM);
tooltipManager->addTooltipFor(m_brushSize, "Brush Size (in pixels)", BOTTOM);
tooltipManager->addTooltipFor(m_brushAngle, "Brush Angle (in degrees)", BOTTOM);
tooltipManager->addTooltipFor(m_inkType->at(0), "Ink", BOTTOM);
tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (paint intensity)", BOTTOM);
tooltipManager->addTooltipFor(m_inkShades->at(0), "Shades", BOTTOM);
tooltipManager->addTooltipFor(m_sprayWidth, "Spray Width", BOTTOM);
tooltipManager->addTooltipFor(m_spraySpeed, "Spray Speed", BOTTOM);
tooltipManager->addTooltipFor(m_pivot->at(0), "Rotation Pivot", BOTTOM);
tooltipManager->addTooltipFor(m_rotAlgo, "Rotation Algorithm", BOTTOM);
tooltipManager->addTooltipFor(m_dynamics->at(0), "Dynamics", BOTTOM);
tooltipManager->addTooltipFor(
m_brushBack->at(0), Strings::context_bar_discard_brush(), BOTTOM);
tooltipManager->addTooltipFor(
m_brushType->at(0), Strings::context_bar_brush_type(), BOTTOM);
tooltipManager->addTooltipFor(
m_brushSize, Strings::context_bar_brush_size(), BOTTOM);
tooltipManager->addTooltipFor(
m_brushAngle, Strings::context_bar_brush_angle(), BOTTOM);
tooltipManager->addTooltipFor(
m_inkType->at(0), Strings::context_bar_ink(), BOTTOM);
tooltipManager->addTooltipFor(
m_inkOpacity, Strings::context_bar_opacity(), BOTTOM);
tooltipManager->addTooltipFor(
m_inkShades->at(0), Strings::context_bar_shades(), BOTTOM);
tooltipManager->addTooltipFor(
m_sprayWidth, Strings::context_bar_spray_width(), BOTTOM);
tooltipManager->addTooltipFor(
m_spraySpeed, Strings::context_bar_spray_speed(), BOTTOM);
tooltipManager->addTooltipFor(
m_pivot->at(0), Strings::context_bar_rotation_pivot(), BOTTOM);
tooltipManager->addTooltipFor(
m_rotAlgo, Strings::context_bar_rotation_algorithm(), BOTTOM);
tooltipManager->addTooltipFor(
m_dynamics->at(0), Strings::context_bar_dynamics(), BOTTOM);
tooltipManager->addTooltipFor(m_freehandAlgo,
key_tooltip("Freehand trace algorithm",
CommandId::PixelPerfectMode()), BOTTOM);
tooltipManager->addTooltipFor(m_contiguous,
key_tooltip("Fill contiguous areas color",
CommandId::ContiguousFill()), BOTTOM);
tooltipManager->addTooltipFor(m_paintBucketSettings->at(0),
"Extra paint bucket options", BOTTOM);
tooltipManager->addTooltipFor(
m_paintBucketSettings->at(0), Strings::context_bar_paint_bucket_option(), BOTTOM);
m_selectionMode->setupTooltips(tooltipManager);
m_gradientType->setupTooltips(tooltipManager);

View File

@ -13,6 +13,7 @@
#include "app/app.h"
#include "app/extensions.h"
#include "app/i18n/strings.h"
#include "app/modules/palettes.h"
#include "app/ui/skin/skin_theme.h"
#include "app/util/conversion_to_surface.h"
@ -206,29 +207,30 @@ void DitheringSelector::regenerate()
switch (m_type) {
case SelectBoth:
addItem(new DitherItem(render::DitheringAlgorithm::None,
render::DitheringMatrix(), "No Dithering"));
render::DitheringMatrix(),
Strings::dithering_selector_no_dithering()));
for (const auto& it : ditheringMatrices) {
addItem(
new DitherItem(
render::DitheringAlgorithm::Ordered,
it.matrix(),
"Ordered Dithering+" + it.name()));
addItem(new DitherItem(
render::DitheringAlgorithm::Ordered,
it.matrix(),
Strings::dithering_selector_ordered_dithering() + it.name()));
}
for (const auto& it : ditheringMatrices) {
addItem(
new DitherItem(
render::DitheringAlgorithm::Old,
it.matrix(),
"Old Dithering+" + it.name()));
Strings::dithering_selector_old_dithering() + it.name()));
}
addItem(
new DitherItem(
render::DitheringAlgorithm::ErrorDiffusion,
render::DitheringMatrix(),
"Floyd-Steinberg Error Diffusion Dithering"));
Strings::dithering_selector_floyd_steinberg()));
break;
case SelectMatrix:
addItem(new DitherItem(render::DitheringMatrix(), "No Dithering"));
addItem(new DitherItem(render::DitheringMatrix(),
Strings::dithering_selector_no_dithering()));
for (auto& it : ditheringMatrices)
addItem(new DitherItem(it.matrix(), it.name()));
break;

View File

@ -2798,7 +2798,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
Menu menu;
for (double option : options) {
MenuItem* item = new MenuItem(fmt::format("Speed x{}", option));
MenuItem* item = new MenuItem(fmt::format(Strings::preview_speed_x(), option));
item->Click.connect([this, option]{ setAnimationSpeedMultiplier(option); });
item->setSelected(m_aniSpeed == option);
menu.addChild(item);
@ -2808,7 +2808,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
// Play once option
{
MenuItem* item = new MenuItem("Play Once");
MenuItem* item = new MenuItem(Strings::preview_play_once());
item->Click.connect(
[&playOnce]() {
playOnce(!playOnce());
@ -2819,7 +2819,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
// Play all option
{
MenuItem* item = new MenuItem("Play All Frames (Ignore Tags)");
MenuItem* item = new MenuItem(Strings::preview_play_all_no_tags());
item->Click.connect(
[&playAll]() {
playAll(!playAll());
@ -2829,7 +2829,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
}
if (withStopBehaviorOptions) {
MenuItem* item = new MenuItem("Rewind on Stop");
MenuItem* item = new MenuItem(Strings::preview_rewind_on_stop());
item->Click.connect(
[]() {
// Switch the "rewind_on_stop" option

View File

@ -19,6 +19,7 @@
#include "app/console.h"
#include "app/doc.h"
#include "app/doc_api.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/pref/preferences.h"
#include "app/site.h"
@ -1170,8 +1171,9 @@ retry:; // In case that we don't have enough memory for RotSprite
int(corners.leftBottom().y-leftTop.y));
}
catch (const std::bad_alloc&) {
StatusBar::instance()->showTip(1000,
"Not enough memory for RotSprite");
StatusBar::instance()->showTip(
1000,
Strings::statusbar_tips_not_enough_rotsprite_memory());
rotAlgo = tools::RotationAlgorithm::FAST;
goto retry;

View File

@ -180,12 +180,14 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
if (layer) {
// TODO we should be able to move the `Background' with tiled mode
if (layer->isBackground()) {
StatusBar::instance()->showTip(1000,
"The background layer cannot be moved");
StatusBar::instance()->showTip(
1000, Strings::statusbar_tips_cannot_move_bg_layer());
}
else if (!layer->isVisibleHierarchy()) {
StatusBar::instance()->showTip(
1000, fmt::format("Layer '{}' is hidden", layer->name()));
1000,
fmt::format(Strings::statusbar_tips_layer_x_is_hidden(),
layer->name()));
}
else if (!layer->isMovable() || !layer->isEditableHierarchy()) {
StatusBar::instance()->showTip(
@ -195,7 +197,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
MovingCelCollect collect(editor, layer);
if (collect.empty()) {
StatusBar::instance()->showTip(
1000, "Nothing to move");
1000, Strings::statusbar_tips_nothing_to_move());
}
else {
try {
@ -211,7 +213,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
catch (const LockedDocException&) {
// TODO break the background task that is locking this sprite
StatusBar::instance()->showTip(
1000, "Sprite is used by a backup/data recovery task");
1000, Strings::statusbar_tips_recovery_task_using_sprite());
}
}
}
@ -748,7 +750,8 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT
Layer* layer = editor->layer();
if (layer && layer->isReference()) {
StatusBar::instance()->showTip(
1000, fmt::format("Layer '{}' is reference, cannot be transformed",
1000,
fmt::format(Strings::statusbar_tips_non_transformable_reference_layer(),
layer->name()));
return;
}
@ -803,11 +806,13 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT
// Other editor is locking the document.
// TODO steal the PixelsMovement of the other editor and use it for this one.
StatusBar::instance()->showTip(1000, "The sprite is locked in other editor");
StatusBar::instance()->showTip(
1000, Strings::statusbar_tips_sprite_locked_somewhere());
editor->showMouseCursor(kForbiddenCursor);
}
catch (const std::bad_alloc&) {
StatusBar::instance()->showTip(1000, "Not enough memory to transform the selection");
StatusBar::instance()->showTip(
1000, Strings::statusbar_tips_not_enough_transform_memory());
editor->showMouseCursor(kForbiddenCursor);
}
}

View File

@ -818,12 +818,14 @@ tools::ToolLoop* create_tool_loop(
Layer* layer = site.layer();
if (!layer) {
StatusBar::instance()->showTip(
1000, "There is no active layer");
1000, Strings::statusbar_tips_no_active_layers());
return nullptr;
}
else if (!layer->isVisibleHierarchy()) {
StatusBar::instance()->showTip(
1000, fmt::format("Layer '{}' is hidden", layer->name()));
1000,
fmt::format(Strings::statusbar_tips_layer_x_is_hidden(),
layer->name()));
return nullptr;
}
// If the active layer is read-only.
@ -833,7 +835,9 @@ tools::ToolLoop* create_tool_loop(
// If the active layer is reference.
else if (layer->isReference()) {
StatusBar::instance()->showTip(
1000, fmt::format("Layer '{}' is reference, cannot be modified", layer->name()));
1000,
fmt::format(Strings::statusbar_tips_unmodifiable_reference_layer(),
layer->name()));
return nullptr;
}
}

View File

@ -485,7 +485,8 @@ bool FileSelector::show(
// File type for all formats
fileType()->addItem(
new CustomFileExtensionItem("All formats", allExtensions));
new CustomFileExtensionItem(Strings::file_selector_all_formats(),
allExtensions));
// One file type for each supported image format
for (const auto& e : allExtensions) {
@ -499,7 +500,7 @@ bool FileSelector::show(
}
// All files
fileType()->addItem(
new CustomFileExtensionItem("All files",
new CustomFileExtensionItem(Strings::file_selector_all_files(),
base::paths())); // Empty extensions means "*.*"
// file name entry field

View File

@ -15,6 +15,7 @@
#include "app/commands/commands.h"
#include "app/console.h"
#include "app/font_path.h"
#include "app/i18n/strings.h"
#include "app/match_words.h"
#include "app/ui/search_entry.h"
#include "app/ui/skin/skin_theme.h"
@ -133,7 +134,7 @@ private:
};
FontPopup::FontPopup()
: PopupWindow("Fonts",
: PopupWindow(Strings::font_popup_title(),
ClickBehavior::CloseOnClickInOtherWindow,
EnterBehavior::DoNothingOnEnter)
, m_popup(new gen::FontPopup())
@ -181,7 +182,7 @@ FontPopup::FontPopup()
}
if (m_listBox.children().empty())
m_listBox.addChild(new ListItem("No system fonts were found"));
m_listBox.addChild(new ListItem(Strings::font_popup_empty_fonts()));
}
void FontPopup::showPopup(Display* display,

View File

@ -15,9 +15,9 @@
#include "app/app_menus.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/doc.h"
#include "app/i18n/strings.h"
#include "app/tools/active_tool.h"
#include "app/tools/ink.h"
#include "app/tools/tool.h"
@ -36,41 +36,51 @@
#define XML_KEYBOARD_FILE_VERSION "1"
#define I18N_KEY(a) app::Strings::keyboard_shortcuts_##a()
namespace {
static struct {
struct KeyShortcutAction {
const char* name;
const char* userfriendly;
std::string userfriendly;
app::KeyAction action;
app::KeyContext context;
} actions[] = {
{ "CopySelection" , "Copy Selection" , app::KeyAction::CopySelection, app::KeyContext::TranslatingSelection },
{ "SnapToGrid" , "Snap To Grid" , app::KeyAction::SnapToGrid, app::KeyContext::TranslatingSelection },
{ "LockAxis" , "Lock Axis" , app::KeyAction::LockAxis, app::KeyContext::TranslatingSelection },
{ "FineControl" , "Fine Translating" , app::KeyAction::FineControl , app::KeyContext::TranslatingSelection },
{ "MaintainAspectRatio" , "Maintain Aspect Ratio", app::KeyAction::MaintainAspectRatio, app::KeyContext::ScalingSelection },
{ "ScaleFromCenter" , "Scale From Center" , app::KeyAction::ScaleFromCenter, app::KeyContext::ScalingSelection },
{ "FineControl" , "Fine Scaling" , app::KeyAction::FineControl , app::KeyContext::ScalingSelection },
{ "AngleSnap" , "Angle Snap" , app::KeyAction::AngleSnap, app::KeyContext::RotatingSelection },
{ "AddSelection" , "Add Selection" , app::KeyAction::AddSelection, app::KeyContext::SelectionTool },
{ "SubtractSelection" , "Subtract Selection" , app::KeyAction::SubtractSelection, app::KeyContext::SelectionTool },
{ "IntersectSelection" , "Intersect Selection" , app::KeyAction::IntersectSelection, app::KeyContext::SelectionTool },
{ "AutoSelectLayer" , "Auto Select Layer" , app::KeyAction::AutoSelectLayer, app::KeyContext::MoveTool },
{ "StraightLineFromLastPoint", "Straight Line from Last Point", app::KeyAction::StraightLineFromLastPoint, app::KeyContext::FreehandTool },
{ "AngleSnapFromLastPoint", "Angle Snap from Last Point", app::KeyAction::AngleSnapFromLastPoint, app::KeyContext::FreehandTool },
{ "MoveOrigin" , "Move Origin" , app::KeyAction::MoveOrigin, app::KeyContext::ShapeTool },
{ "SquareAspect" , "Square Aspect" , app::KeyAction::SquareAspect, app::KeyContext::ShapeTool },
{ "DrawFromCenter" , "Draw From Center" , app::KeyAction::DrawFromCenter, app::KeyContext::ShapeTool },
{ "RotateShape" , "Rotate Shape" , app::KeyAction::RotateShape, app::KeyContext::ShapeTool },
{ "LeftMouseButton" , "Trigger Left Mouse Button" , app::KeyAction::LeftMouseButton, app::KeyContext::Any },
{ "RightMouseButton" , "Trigger Right Mouse Button" , app::KeyAction::RightMouseButton, app::KeyContext::Any },
{ NULL , NULL , app::KeyAction::None, app::KeyContext::Any }
};
static std::vector<KeyShortcutAction> g_actions;
static const std::vector<KeyShortcutAction>& actions() {
if (g_actions.empty()) {
g_actions = std::vector<KeyShortcutAction> {
{ "CopySelection" , I18N_KEY(copy_selection) , app::KeyAction::CopySelection, app::KeyContext::TranslatingSelection },
{ "SnapToGrid" , I18N_KEY(snap_to_grid) , app::KeyAction::SnapToGrid, app::KeyContext::TranslatingSelection },
{ "LockAxis" , I18N_KEY(lock_axis) , app::KeyAction::LockAxis, app::KeyContext::TranslatingSelection },
{ "FineControl" , I18N_KEY(fine_translating) , app::KeyAction::FineControl , app::KeyContext::TranslatingSelection },
{ "MaintainAspectRatio" , I18N_KEY(maintain_aspect_ratio) , app::KeyAction::MaintainAspectRatio, app::KeyContext::ScalingSelection },
{ "ScaleFromCenter" , I18N_KEY(scale_from_center) , app::KeyAction::ScaleFromCenter, app::KeyContext::ScalingSelection },
{ "FineControl" , I18N_KEY(fine_scaling) , app::KeyAction::FineControl , app::KeyContext::ScalingSelection },
{ "AngleSnap" , I18N_KEY(angle_snap) , app::KeyAction::AngleSnap, app::KeyContext::RotatingSelection },
{ "AddSelection" , I18N_KEY(add_selection) , app::KeyAction::AddSelection, app::KeyContext::SelectionTool },
{ "SubtractSelection" , I18N_KEY(subtract_selection) , app::KeyAction::SubtractSelection, app::KeyContext::SelectionTool },
{ "IntersectSelection" , I18N_KEY(intersect_selection) , app::KeyAction::IntersectSelection, app::KeyContext::SelectionTool },
{ "AutoSelectLayer" , I18N_KEY(auto_select_layer) , app::KeyAction::AutoSelectLayer, app::KeyContext::MoveTool },
{ "StraightLineFromLastPoint", I18N_KEY(line_from_last_point) , app::KeyAction::StraightLineFromLastPoint, app::KeyContext::FreehandTool },
{ "AngleSnapFromLastPoint", I18N_KEY(angle_from_last_point) , app::KeyAction::AngleSnapFromLastPoint, app::KeyContext::FreehandTool },
{ "MoveOrigin" , I18N_KEY(move_origin) , app::KeyAction::MoveOrigin, app::KeyContext::ShapeTool },
{ "SquareAspect" , I18N_KEY(square_aspect) , app::KeyAction::SquareAspect, app::KeyContext::ShapeTool },
{ "DrawFromCenter" , I18N_KEY(draw_from_center) , app::KeyAction::DrawFromCenter, app::KeyContext::ShapeTool },
{ "RotateShape" , I18N_KEY(rotate_shape) , app::KeyAction::RotateShape, app::KeyContext::ShapeTool },
{ "LeftMouseButton" , I18N_KEY(trigger_left_mouse_button) , app::KeyAction::LeftMouseButton, app::KeyContext::Any },
{ "RightMouseButton" , I18N_KEY(trigger_right_mouse_button) , app::KeyAction::RightMouseButton, app::KeyContext::Any }
};
}
return g_actions;
}
static struct {
const char* name;
app::KeyContext context;
} contexts[] = {
} g_contexts[] = {
{ "" , app::KeyContext::Any },
{ "Normal" , app::KeyContext::Normal },
{ "Selection" , app::KeyContext::SelectionTool },
@ -85,38 +95,47 @@ namespace {
using Vec = app::DragVector;
static struct {
struct KeyShortcutWheelAction {
const char* name;
const char* userfriendly;
const std::string userfriendly;
Vec vector;
} wheel_actions[] = {
{ "" , "" , Vec(0.0, 0.0) },
{ "Zoom" , "Zoom" , Vec(8.0, 0.0) },
{ "VScroll" , "Scroll: Vertically" , Vec(4.0, 0.0) },
{ "HScroll" , "Scroll: Horizontally" , Vec(4.0, 0.0) },
{ "FgColor" , "Color: Foreground Palette Entry" , Vec(8.0, 0.0) },
{ "BgColor" , "Color: Background Palette Entry" , Vec(8.0, 0.0) },
{ "FgTile" , "Tile: Foreground Tile Entry" , Vec(8.0, 0.0) },
{ "BgTile" , "Tile: Background Tile Entry" , Vec(8.0, 0.0) },
{ "Frame" , "Change Frame" , Vec(16.0, 0.0) },
{ "BrushSize" , "Change Brush Size" , Vec(4.0, 0.0) },
{ "BrushAngle" , "Change Brush Angle" , Vec(-4.0, 0.0) },
{ "ToolSameGroup" , "Change Tool (same group)" , Vec(8.0, 0.0) },
{ "ToolOtherGroup" , "Change Tool" , Vec(0.0, -8.0) },
{ "Layer" , "Change Layer" , Vec(0.0, 8.0) },
{ "InkType" , "Change Ink Type" , Vec(0.0, -16.0) },
{ "InkOpacity" , "Change Ink Opacity" , Vec(0.0, 1.0) },
{ "LayerOpacity" , "Change Layer Opacity" , Vec(0.0, 1.0) },
{ "CelOpacity" , "Change Cel Opacity" , Vec(0.0, 1.0) },
{ "Alpha" , "Color: Alpha" , Vec(4.0, 0.0) },
{ "HslHue" , "Color: HSL Hue" , Vec(1.0, 0.0) },
{ "HslSaturation", "Color: HSL Saturation" , Vec(4.0, 0.0) },
{ "HslLightness" , "Color: HSL Lightness" , Vec(0.0, 4.0) },
{ "HsvHue" , "Color: HSV Hue" , Vec(1.0, 0.0) },
{ "HsvSaturation", "Color: HSV Saturation" , Vec(4.0, 0.0) },
{ "HsvValue" , "Color: HSV Value" , Vec(0.0, 4.0) },
};
static std::vector<KeyShortcutWheelAction> g_wheel_actions;
static const std::vector<KeyShortcutWheelAction>& wheel_actions() {
if (g_wheel_actions.empty()) {
g_wheel_actions = std::vector<KeyShortcutWheelAction> {
{ "" , "" , Vec(0.0, 0.0) },
{ "Zoom" , I18N_KEY(zoom) , Vec(8.0, 0.0) },
{ "VScroll" , I18N_KEY(scroll_vertically) , Vec(4.0, 0.0) },
{ "HScroll" , I18N_KEY(scroll_horizontally) , Vec(4.0, 0.0) },
{ "FgColor" , I18N_KEY(fg_color) , Vec(8.0, 0.0) },
{ "BgColor" , I18N_KEY(bg_color) , Vec(8.0, 0.0) },
{ "FgTile" , I18N_KEY(fg_tile) , Vec(8.0, 0.0) },
{ "BgTile" , I18N_KEY(bg_tile) , Vec(8.0, 0.0) },
{ "Frame" , I18N_KEY(change_frame) , Vec(16.0, 0.0) },
{ "BrushSize" , I18N_KEY(change_brush_size) , Vec(4.0, 0.0) },
{ "BrushAngle" , I18N_KEY(change_brush_angle) , Vec(-4.0, 0.0) },
{ "ToolSameGroup" , I18N_KEY(change_tool_same_group) , Vec(8.0, 0.0) },
{ "ToolOtherGroup", I18N_KEY(change_tool) , Vec(0.0, -8.0) },
{ "Layer" , I18N_KEY(change_layer) , Vec(0.0, 8.0) },
{ "InkType" , I18N_KEY(change_ink_type) , Vec(0.0, -16.0) },
{ "InkOpacity" , I18N_KEY(change_ink_opacity) , Vec(0.0, 1.0) },
{ "LayerOpacity" , I18N_KEY(change_layer_opacity) , Vec(0.0, 1.0) },
{ "CelOpacity" , I18N_KEY(change_cel_opacity) , Vec(0.0, 1.0) },
{ "Alpha" , I18N_KEY(color_alpha) , Vec(4.0, 0.0) },
{ "HslHue" , I18N_KEY(color_hsl_hue) , Vec(1.0, 0.0) },
{ "HslSaturation" , I18N_KEY(color_hsl_saturation) , Vec(4.0, 0.0) },
{ "HslLightness" , I18N_KEY(color_hsl_lightness) , Vec(0.0, 4.0) },
{ "HsvHue" , I18N_KEY(color_hsv_hue) , Vec(1.0, 0.0) },
{ "HsvSaturation" , I18N_KEY(color_hsv_saturation) , Vec(4.0, 0.0) },
{ "HsvValue" , I18N_KEY(color_hsv_value) , Vec(0.0, 4.0) }
};
}
return g_wheel_actions;
}
const char* get_shortcut(TiXmlElement* elem) {
const char* shortcut = NULL;
@ -136,10 +155,9 @@ namespace {
std::string get_user_friendly_string_for_keyaction(app::KeyAction action,
app::KeyContext context) {
for (int c=0; actions[c].name; ++c) {
if (action == actions[c].action &&
context == actions[c].context)
return actions[c].userfriendly;
for (const auto& a : actions()) {
if (action == a.action && context == a.context)
return a.userfriendly;
}
return std::string();
}
@ -148,7 +166,7 @@ namespace {
int c = int(wheelAction);
if (c >= int(app::WheelAction::First) &&
c <= int(app::WheelAction::Last)) {
return wheel_actions[c].userfriendly;
return wheel_actions()[c].userfriendly;
}
else
return std::string();
@ -185,26 +203,25 @@ namespace {
namespace base {
template<> app::KeyAction convert_to(const std::string& from) {
app::KeyAction action = app::KeyAction::None;
for (int c=0; actions[c].name; ++c) {
if (from == actions[c].name)
return actions[c].action;
for (const auto& a : actions()) {
if (from == a.name)
return a.action;
}
return action;
return app::KeyAction::None;
}
template<> std::string convert_to(const app::KeyAction& from) {
for (int c=0; actions[c].name; ++c) {
if (from == actions[c].action)
return actions[c].name;
for (const auto& a : actions()) {
if (from == a.action)
return a.name;
}
return "";
return std::string();
}
template<> app::WheelAction convert_to(const std::string& from) {
for (int c=int(app::WheelAction::First);
c<=int(app::WheelAction::Last); ++c) {
if (from == wheel_actions[c].name)
if (from == wheel_actions()[c].name)
return (app::WheelAction)c;
}
return app::WheelAction::None;
@ -214,24 +231,24 @@ namespace base {
int c = int(from);
if (c >= int(app::WheelAction::First) &&
c <= int(app::WheelAction::Last)) {
return wheel_actions[c].name;
return wheel_actions()[c].name;
}
else
return std::string();
}
template<> app::KeyContext convert_to(const std::string& from) {
for (int c=0; contexts[c].name; ++c) {
if (from == contexts[c].name)
return contexts[c].context;
for (int c=0; g_contexts[c].name; ++c) {
if (from == g_contexts[c].name)
return g_contexts[c].context;
}
return app::KeyContext::Any;
}
template<> std::string convert_to(const app::KeyContext& from) {
for (int c=0; contexts[c].name; ++c) {
if (from == contexts[c].context)
return contexts[c].name;
for (int c=0; g_contexts[c].name; ++c) {
if (from == g_contexts[c].context)
return g_contexts[c].name;
}
return std::string();
}
@ -358,7 +375,7 @@ KeyPtr Key::MakeDragAction(WheelAction dragAction)
KeyPtr k(new Key(dragAction));
k->m_type = KeyType::DragAction;
k->m_keycontext = KeyContext::Any;
k->m_dragVector = wheel_actions[(int)dragAction].vector;
k->m_dragVector = wheel_actions()[(int)dragAction].vector;
return k;
}
@ -554,6 +571,12 @@ void KeyboardShortcuts::destroyInstance()
KeyboardShortcuts::KeyboardShortcuts()
{
ASSERT(Strings::instance());
Strings::instance()->LanguageChange.connect([]{
// Clear collections so they are re-constructed with the new language
g_actions.clear();
g_wheel_actions.clear();
});
}
KeyboardShortcuts::~KeyboardShortcuts()
@ -1300,21 +1323,21 @@ std::string convertKeyContextToUserFriendlyString(KeyContext keyContext)
case KeyContext::Any:
return std::string();
case KeyContext::Normal:
return "Normal";
return I18N_KEY(key_context_normal);
case KeyContext::SelectionTool:
return "Selection";
return I18N_KEY(key_context_selection);
case KeyContext::TranslatingSelection:
return "Translating Selection";
return I18N_KEY(key_context_translating_selection);
case KeyContext::ScalingSelection:
return "Scaling Selection";
return I18N_KEY(key_context_scaling_selection);
case KeyContext::RotatingSelection:
return "Rotating Selection";
return I18N_KEY(key_context_rotating_selection);
case KeyContext::MoveTool:
return "Move Tool";
return I18N_KEY(key_context_move_tool);
case KeyContext::FreehandTool:
return "Freehand Tool";
return I18N_KEY(key_context_freehand_tool);
case KeyContext::ShapeTool:
return "Shape Tool";
return I18N_KEY(key_context_shape_tool);
}
return std::string();
}

View File

@ -11,6 +11,7 @@
#include "app/ui/layer_frame_comboboxes.h"
#include "app/i18n/strings.h"
#include "app/restore_visible_layers.h"
#include "app/site.h"
#include "doc/anidir.h"
@ -56,12 +57,15 @@ std::string LayerListItem::buildName(const doc::Layer* layer)
name.insert(0, layer->name());
layer = layer->parent();
}
name.insert(0, isGroup ? "Group: ": "Layer: ");
const std::string namePrefix =
(isGroup ? Strings::layer_combo_group() :
Strings::layer_combo_layer()) + " ";
name.insert(0, namePrefix);
return name;
}
FrameListItem::FrameListItem(doc::Tag* tag)
: ListItem("Tag: " + tag->name())
: ListItem(Strings::frame_combo_tag() + " " + tag->name())
, m_tag(tag)
{
setValue(m_tag->name());
@ -89,10 +93,10 @@ void fill_area_combobox(const doc::Sprite* sprite, ui::ComboBox* area, const std
void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const std::string& defLayer, const int defLayerIndex)
{
int i = layers->addItem("Visible layers");
int i = layers->addItem(Strings::layer_combo_visible_layers());
dynamic_cast<ui::ListItem*>(layers->getItem(i))->setValue(kAllLayers);
i = layers->addItem("Selected layers");
i = layers->addItem(Strings::layer_combo_selected_layers());
dynamic_cast<ui::ListItem*>(layers->getItem(i))->setValue(kSelectedLayers);
if (defLayer == kSelectedLayers)
layers->setSelectedItemIndex(i);
@ -113,10 +117,10 @@ void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const
void fill_frames_combobox(const doc::Sprite* sprite, ui::ComboBox* frames, const std::string& defFrame)
{
int i = frames->addItem("All frames");
int i = frames->addItem(Strings::frame_combo_all_frames());
dynamic_cast<ui::ListItem*>(frames->getItem(i))->setValue(kAllFrames);
i = frames->addItem("Selected frames");
i = frames->addItem(Strings::frame_combo_selected_frames());
dynamic_cast<ui::ListItem*>(frames->getItem(i))->setValue(kSelectedFrames);
if (defFrame == kSelectedFrames)
frames->setSelectedItemIndex(i);
@ -139,9 +143,9 @@ void fill_anidir_combobox(ui::ComboBox* anidir, doc::AniDir defAnidir)
int(doc::AniDir::REVERSE) == 1 &&
int(doc::AniDir::PING_PONG) == 2, "doc::AniDir has changed");
anidir->addItem("Forward");
anidir->addItem("Reverse");
anidir->addItem("Ping-pong");
anidir->addItem(Strings::anidir_combo_forward());
anidir->addItem(Strings::anidir_combo_reverse());
anidir->addItem(Strings::anidir_combo_ping_pong());
anidir->setSelectedItemIndex(int(defAnidir));
}

View File

@ -13,6 +13,7 @@
#include "app/app.h"
#include "app/app_menus.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/crash/data_recovery.h"
#include "app/i18n/strings.h"
@ -159,12 +160,7 @@ MainWindow::MainWindow()
// When the language is change, we reload the menu bar strings and
// relayout the whole main window.
Strings::instance()->LanguageChange.connect(
[this]{
m_menuBar->reload();
layout();
invalidate();
});
Strings::instance()->LanguageChange.connect([this] { onLanguageChange(); });
}
MainWindow::~MainWindow()
@ -203,6 +199,22 @@ MainWindow::~MainWindow()
m_menuBar->setMenu(NULL);
}
void MainWindow::onLanguageChange()
{
auto commands = Commands::instance();
std::vector<std::string> commandIDs;
commands->getAllIds(commandIDs);
for (const auto& commandID : commandIDs) {
Command* command = commands->byId(commandID.c_str());
command->generateFriendlyName();
}
m_menuBar->reload();
layout();
invalidate();
}
DocView* MainWindow::getDocView()
{
return dynamic_cast<DocView*>(m_workspace->activeView());

View File

@ -116,6 +116,7 @@ namespace app {
void onSaveLayout(ui::SaveLayoutEvent& ev) override;
void onResize(ui::ResizeEvent& ev) override;
void onActiveViewChange();
void onLanguageChange();
private:
DocView* getDocView();

View File

@ -12,6 +12,7 @@
#include "app/ui/news_listbox.h"
#include "app/app.h"
#include "app/i18n/strings.h"
#include "app/pref/preferences.h"
#include "app/res/http_loader.h"
#include "app/ui/skin/skin_theme.h"
@ -168,7 +169,8 @@ private:
class ProblemsItem : public NewsItem {
public:
ProblemsItem() : NewsItem("", "Problems loading news. Retry.", "") {
ProblemsItem()
: NewsItem("", Strings::news_listbox_problem_loading(), "") {
}
protected:
@ -306,7 +308,8 @@ void NewsListBox::parseFile(const std::string& filename)
.FirstChild("channel")
.FirstChild("link").ToElement();
if (linkXml && linkXml->GetText())
addChild(new NewsItem(linkXml->GetText(), "More...", ""));
addChild(
new NewsItem(linkXml->GetText(), Strings::news_listbox_more(), ""));
if (view)
view->updateView();

View File

@ -16,6 +16,7 @@
#include "app/doc_event.h"
#include "app/ini_file.h"
#include "app/loop_tag.h"
#include "app/i18n/strings.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/pref/preferences.h"
@ -176,7 +177,7 @@ private:
};
PreviewEditorWindow::PreviewEditorWindow()
: Window(WithTitleBar, "Preview")
: Window(WithTitleBar, Strings::preview_title())
, m_docView(NULL)
, m_centerButton(new MiniCenterButton())
, m_playButton(new MiniPlayButton())

View File

@ -16,6 +16,7 @@
#include "app/doc_access.h"
#include "app/doc_event.h"
#include "app/doc_range.h"
#include "app/i18n/strings.h"
#include "app/modules/editors.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
@ -587,7 +588,7 @@ class StatusBar::SnapToGridWindow : public ui::PopupWindow {
public:
SnapToGridWindow()
: ui::PopupWindow("", ClickBehavior::DoNothingOnClick)
, m_button("Disable Snap to Grid") {
, m_button(Strings::statusbar_tips_disable_snap_grid()) {
InitTheme.connect(
[this]{
setBorder(gfx::Border(2 * guiscale()));
@ -692,7 +693,7 @@ StatusBar::StatusBar(TooltipManager* tooltipManager)
Box* box1 = new Box(HORIZONTAL);
Box* box4 = new Box(HORIZONTAL);
m_frameLabel = new Label("Frame:");
m_frameLabel = new Label(Strings::statusbar_tips_frame());
m_currentFrame = new GotoFrameEntry();
m_newFrame = new Button("+");
m_newFrame->Click.connect([this]{ newFrame(); });
@ -713,9 +714,12 @@ StatusBar::StatusBar(TooltipManager* tooltipManager)
}
// Tooltips
tooltipManager->addTooltipFor(m_currentFrame, "Current Frame", BOTTOM);
tooltipManager->addTooltipFor(m_zoomEntry, "Zoom Level", BOTTOM);
tooltipManager->addTooltipFor(m_newFrame, "New Frame", BOTTOM);
tooltipManager->addTooltipFor(
m_currentFrame, Strings::statusbar_tips_current_frame(), BOTTOM);
tooltipManager->addTooltipFor(
m_zoomEntry, Strings::statusbar_tips_zoom_level(), BOTTOM);
tooltipManager->addTooltipFor(
m_newFrame, Strings::statusbar_tips_new_frame(), BOTTOM);
App::instance()->activeToolManager()->add_observer(this);

View File

@ -13,6 +13,7 @@
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/i18n/strings.h"
#include "app/modules/editors.h"
#include "app/ui/editor/editor.h"
#include "app/ui/keyboard_shortcuts.h"
@ -124,12 +125,12 @@ std::string AniControls::getTooltipFor(int index) const
Params(),
KeyContext::Normal);
if (key && !key->accels().empty()) {
tooltip += "\n\nShortcut: ";
tooltip += "\n\n" + Strings::ani_controls_shortcut() + " ";
tooltip += key->accels().front().toString();
}
if (index == ACTION_PLAY) {
tooltip += "\n\nRight-click: Show playback options";
tooltip += "\n\n" + Strings::ani_controls_right_click();
}
}