mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-29 19:20:09 +00:00
Merge branch 'master' into feature/continuous-cels
This commit is contained in:
commit
1321de9d58
@ -56,6 +56,7 @@
|
||||
<key command="SpriteProperties" shortcut="Ctrl+P" mac="Cmd+P" />
|
||||
<!-- Layer -->
|
||||
<key command="LayerProperties" shortcut="Shift+P" />
|
||||
<key command="LayerVisibility" shortcut="Shift+X" />
|
||||
<key command="NewLayer" shortcut="Shift+N" />
|
||||
<key command="GotoPreviousLayer" shortcut="Down" context="Normal" />
|
||||
<key command="GotoNextLayer" shortcut="Up" context="Normal" />
|
||||
@ -497,6 +498,7 @@
|
||||
</menu>
|
||||
<menu text="&Layer">
|
||||
<item command="LayerProperties" text="&Properties..." />
|
||||
<item command="LayerVisibility" text="&Visible" />
|
||||
<separator />
|
||||
<item command="NewLayer" text="&New Layer" />
|
||||
<item command="RemoveLayer" text="&Remove Layer" />
|
||||
@ -576,7 +578,7 @@
|
||||
<menu text="&Help">
|
||||
<item command="Launch" text="Readme">
|
||||
<param name="type" value="url" />
|
||||
<param name="path" value="https://github.com/dacap/aseprite#readme" />
|
||||
<param name="path" value="https://github.com/aseprite/aseprite#readme" />
|
||||
</item>
|
||||
<separator />
|
||||
<item command="Launch" text="Quick &Reference">
|
||||
|
@ -13,8 +13,9 @@
|
||||
<radio id="no_quantize" text="&Don't modify color palette" group="1" />
|
||||
</vbox>
|
||||
|
||||
<separator text="Optimize for Web:" left="true" horizontal="true" />
|
||||
<separator text="General Options:" left="true" horizontal="true" />
|
||||
<check text="Interlaced" id="interlaced" />
|
||||
<check text="Animation Loop" id="loop" />
|
||||
|
||||
<separator horizontal="true" />
|
||||
|
||||
|
@ -131,9 +131,6 @@ void osx_mouse_handler(int ax, int ay, int x, int y, int z, int buttons)
|
||||
_mouse_y = ay;
|
||||
_mouse_z += z;
|
||||
|
||||
_mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx);
|
||||
_mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy);
|
||||
|
||||
_handle_mouse_input();
|
||||
}
|
||||
|
||||
@ -219,26 +216,24 @@ static void osx_mouse_exit(void)
|
||||
*/
|
||||
static void osx_mouse_position(int x, int y)
|
||||
{
|
||||
CGPoint point;
|
||||
NSRect frame;
|
||||
int screen_height;
|
||||
int scale, view_scale;
|
||||
NSPoint pt;
|
||||
CGPoint pos;
|
||||
CGEventRef event;
|
||||
NSView* view = [osx_window contentView];
|
||||
|
||||
_unix_lock_mutex(osx_event_mutex);
|
||||
|
||||
_mouse_x = point.x = x;
|
||||
_mouse_y = point.y = y;
|
||||
pt = NSMakePoint(x, y);
|
||||
pt = [view convertPoint:pt toView:view];
|
||||
pt = [view convertPoint:pt toView:nil];
|
||||
pt = [osx_window convertBaseToScreen:pt];
|
||||
pt.y = [[osx_window screen] frame].size.height - pt.y;
|
||||
|
||||
if (osx_window) {
|
||||
CFNumberGetValue(CFDictionaryGetValue(CGDisplayCurrentMode(kCGDirectMainDisplay), kCGDisplayHeight), kCFNumberSInt32Type, &screen_height);
|
||||
frame = [osx_window frame];
|
||||
point.x += frame.origin.x;
|
||||
point.y += (screen_height - (frame.origin.y + gfx_driver->h));
|
||||
}
|
||||
|
||||
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, point);
|
||||
|
||||
mymickey_x = mymickey_y = 0;
|
||||
osx_mouse_warped = TRUE;
|
||||
pos = CGPointMake(pt.x, pt.y);
|
||||
event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, pos, 0);
|
||||
CGEventPost(kCGHIDEventTap, event);
|
||||
CFRelease(event);
|
||||
|
||||
_unix_unlock_mutex(osx_event_mutex);
|
||||
}
|
||||
@ -350,6 +345,9 @@ int osx_mouse_set_sprite(BITMAP *sprite, int x, int y)
|
||||
*/
|
||||
int osx_mouse_show(BITMAP *bmp, int x, int y)
|
||||
{
|
||||
if (!_mouse_on)
|
||||
return -1;
|
||||
|
||||
/* Only draw on screen */
|
||||
if (!is_same_bitmap(bmp, screen))
|
||||
return -1;
|
||||
@ -368,6 +366,9 @@ int osx_mouse_show(BITMAP *bmp, int x, int y)
|
||||
*/
|
||||
void osx_mouse_hide(void)
|
||||
{
|
||||
if (!_mouse_on)
|
||||
return;
|
||||
|
||||
osx_change_cursor(osx_blank_cursor);
|
||||
|
||||
osx_using_native_cursor = FALSE;
|
||||
|
@ -121,28 +121,33 @@ static void prepare_window_for_animation(int refresh_view)
|
||||
int pitch, y, x;
|
||||
|
||||
_unix_lock_mutex(osx_window_mutex);
|
||||
while (![qd_view lockFocusIfCanDraw]);
|
||||
while (!QDDone([qd_view qdPort]));
|
||||
LockPortBits([qd_view qdPort]);
|
||||
pitch = GetPixRowBytes(GetPortPixMap([qd_view qdPort])) / 4;
|
||||
addr = (unsigned int *)GetPixBaseAddr(GetPortPixMap([qd_view qdPort])) +
|
||||
((int)([osx_window frame].size.height) - gfx_quartz_window.h) * pitch;
|
||||
if (refresh_view && colorconv_blitter) {
|
||||
src_gfx_rect.width = gfx_quartz_window.w;
|
||||
src_gfx_rect.height = gfx_quartz_window.h;
|
||||
src_gfx_rect.pitch = pseudo_screen_pitch;
|
||||
src_gfx_rect.data = pseudo_screen_addr;
|
||||
dest_gfx_rect.pitch = pitch * 4;
|
||||
dest_gfx_rect.data = addr;
|
||||
colorconv_blitter(&src_gfx_rect, &dest_gfx_rect);
|
||||
|
||||
if ([qd_view lockFocusIfCanDraw] == YES) {
|
||||
while (!QDDone([qd_view qdPort]));
|
||||
LockPortBits([qd_view qdPort]);
|
||||
|
||||
pitch = GetPixRowBytes(GetPortPixMap([qd_view qdPort])) / 4;
|
||||
addr = (unsigned int *)GetPixBaseAddr(GetPortPixMap([qd_view qdPort])) +
|
||||
((int)([osx_window frame].size.height) - gfx_quartz_window.h) * pitch;
|
||||
if (refresh_view && colorconv_blitter) {
|
||||
src_gfx_rect.width = gfx_quartz_window.w;
|
||||
src_gfx_rect.height = gfx_quartz_window.h;
|
||||
src_gfx_rect.pitch = pseudo_screen_pitch;
|
||||
src_gfx_rect.data = pseudo_screen_addr;
|
||||
dest_gfx_rect.pitch = pitch * 4;
|
||||
dest_gfx_rect.data = addr;
|
||||
colorconv_blitter(&src_gfx_rect, &dest_gfx_rect);
|
||||
}
|
||||
for (y = gfx_quartz_window.h; y; y--) {
|
||||
for (x = 0; x < gfx_quartz_window.w; x++)
|
||||
*(addr + x) |= 0xff000000;
|
||||
addr += pitch;
|
||||
}
|
||||
QDFlushPortBuffer([qd_view qdPort], update_region);
|
||||
UnlockPortBits([qd_view qdPort]);
|
||||
[qd_view unlockFocus];
|
||||
}
|
||||
for (y = gfx_quartz_window.h; y; y--) {
|
||||
for (x = 0; x < gfx_quartz_window.w; x++)
|
||||
*(addr + x) |= 0xff000000;
|
||||
addr += pitch;
|
||||
}
|
||||
UnlockPortBits([qd_view qdPort]);
|
||||
[qd_view unlockFocus];
|
||||
|
||||
_unix_unlock_mutex(osx_window_mutex);
|
||||
}
|
||||
|
||||
|
@ -153,25 +153,14 @@ static RETSIGTYPE osx_signal_handler(int num)
|
||||
|
||||
|
||||
|
||||
static BOOL handle_mouse_enter(
|
||||
NSRect frame, NSRect view, NSPoint point,
|
||||
int* mx, int* my, int* buttons)
|
||||
static void handle_mouse_enter()
|
||||
{
|
||||
if (_mouse_installed && !_mouse_on &&
|
||||
(osx_window) && (NSPointInRect(point, view))) {
|
||||
*mx = point.x;
|
||||
*my = frame.size.height - point.y;
|
||||
*buttons = 0;
|
||||
|
||||
if (_mouse_installed && !_mouse_on && osx_window) {
|
||||
_mouse_on = TRUE;
|
||||
osx_hide_native_mouse();
|
||||
if (osx_mouse_enter_callback)
|
||||
osx_mouse_enter_callback();
|
||||
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@ -200,9 +189,8 @@ void osx_event_handler()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSEvent *event;
|
||||
NSDate *distant_past = [NSDate distantPast];
|
||||
NSPoint point;
|
||||
NSRect frame, view;
|
||||
NSView* view;
|
||||
int dx = 0, dy = 0, dz = 0;
|
||||
int mx = _mouse_x;
|
||||
int my = _mouse_y;
|
||||
@ -211,10 +199,12 @@ void osx_event_handler()
|
||||
BOOL gotmouseevent = NO;
|
||||
|
||||
while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: distant_past
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES]) != nil)
|
||||
untilDate: [NSDate distantPast]
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES]))
|
||||
{
|
||||
BOOL send_event = YES;
|
||||
|
||||
_unix_lock_mutex(osx_skip_events_processing_mutex);
|
||||
int skip_events_processing = osx_skip_events_processing;
|
||||
_unix_unlock_mutex(osx_skip_events_processing_mutex);
|
||||
@ -224,16 +214,15 @@ void osx_event_handler()
|
||||
continue;
|
||||
}
|
||||
|
||||
view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h);
|
||||
view = [osx_window contentView];
|
||||
point = [event locationInWindow];
|
||||
if (osx_window)
|
||||
{
|
||||
frame = [[osx_window contentView] frame];
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = [[NSScreen mainScreen] frame];
|
||||
if (osx_window) {
|
||||
if ([event window] == nil)
|
||||
point = [osx_window convertScreenToBase:point];
|
||||
|
||||
point = [view convertPoint:point fromView:nil];
|
||||
}
|
||||
|
||||
event_type = [event type];
|
||||
switch (event_type) {
|
||||
|
||||
@ -241,10 +230,11 @@ void osx_event_handler()
|
||||
if (_keyboard_installed)
|
||||
osx_keyboard_handler(TRUE, event);
|
||||
|
||||
#if 0 // Avoid beeps TODO uncomment this when the OS X menus are ready
|
||||
if ([event modifierFlags] & NSCommandKeyMask && )
|
||||
#if 0 // Avoid beeps TODO comment this when the OS X menus are ready
|
||||
if ([event modifierFlags] & NSCommandKeyMask)
|
||||
[NSApp sendEvent: event];
|
||||
#endif
|
||||
send_event = NO;
|
||||
break;
|
||||
|
||||
case NSKeyUp:
|
||||
@ -255,6 +245,7 @@ void osx_event_handler()
|
||||
if ([event modifierFlags] & NSCommandKeyMask)
|
||||
[NSApp sendEvent: event];
|
||||
#endif
|
||||
send_event = NO;
|
||||
break;
|
||||
|
||||
case NSFlagsChanged:
|
||||
@ -267,87 +258,110 @@ void osx_event_handler()
|
||||
case NSRightMouseDown:
|
||||
/* App is regaining focus */
|
||||
if (![NSApp isActive]) {
|
||||
handle_mouse_enter(frame, view, point, &mx, &my, &buttons);
|
||||
if ([view mouse:point inRect:[view frame]])
|
||||
handle_mouse_enter();
|
||||
|
||||
if (osx_window)
|
||||
[osx_window invalidateCursorRectsForView: [osx_window contentView]];
|
||||
[osx_window invalidateCursorRectsForView:view];
|
||||
|
||||
if (_keyboard_installed)
|
||||
osx_keyboard_focused(TRUE, 0);
|
||||
|
||||
_switch_in();
|
||||
gotmouseevent = YES;
|
||||
[NSApp sendEvent: event];
|
||||
break;
|
||||
}
|
||||
|
||||
buttons |= ((event_type == NSLeftMouseDown) ? 0x1 : 0);
|
||||
buttons |= ((event_type == NSRightMouseDown) ? 0x2 : 0);
|
||||
buttons |= ((event_type == NSOtherMouseDown) ? 0x4 : 0);
|
||||
if (_mouse_on) {
|
||||
buttons |= ((event_type == NSLeftMouseDown) ? 0x1 : 0);
|
||||
buttons |= ((event_type == NSRightMouseDown) ? 0x2 : 0);
|
||||
buttons |= ((event_type == NSOtherMouseDown) ? 0x4 : 0);
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
|
||||
[NSApp sendEvent: event];
|
||||
gotmouseevent = YES;
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSLeftMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
case NSRightMouseUp:
|
||||
if ([NSApp isActive])
|
||||
handle_mouse_enter(frame, view, point, &mx, &my, &buttons);
|
||||
if ([NSApp isActive] && [view mouse:point inRect:[view frame]])
|
||||
handle_mouse_enter();
|
||||
|
||||
buttons &= ~((event_type == NSLeftMouseUp) ? 0x1 : 0);
|
||||
buttons &= ~((event_type == NSRightMouseUp) ? 0x2 : 0);
|
||||
buttons &= ~((event_type == NSOtherMouseUp) ? 0x4 : 0);
|
||||
if (_mouse_on) {
|
||||
buttons &= ~((event_type == NSLeftMouseUp) ? 0x1 : 0);
|
||||
buttons &= ~((event_type == NSRightMouseUp) ? 0x2 : 0);
|
||||
buttons &= ~((event_type == NSOtherMouseUp) ? 0x4 : 0);
|
||||
|
||||
[NSApp sendEvent: event];
|
||||
gotmouseevent = YES;
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
case NSMouseMoved:
|
||||
if ([NSApp isActive])
|
||||
handle_mouse_enter(frame, view, point, &mx, &my, &buttons);
|
||||
if ([NSApp isActive] && [view mouse:point inRect:[view frame]])
|
||||
handle_mouse_enter();
|
||||
|
||||
dx += [event deltaX];
|
||||
dy += [event deltaY];
|
||||
if (_mouse_on) {
|
||||
dx += [event deltaX];
|
||||
dy += [event deltaY];
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
|
||||
mx = point.x;
|
||||
my = frame.size.height - point.y;
|
||||
|
||||
[NSApp sendEvent: event];
|
||||
gotmouseevent = YES;
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
break;
|
||||
|
||||
case NSScrollWheel:
|
||||
dz += [event deltaY];
|
||||
if (_mouse_on)
|
||||
dz += [event deltaY];
|
||||
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
|
||||
gotmouseevent = YES;
|
||||
break;
|
||||
|
||||
case NSMouseEntered:
|
||||
if (([event trackingNumber] == osx_mouse_tracking_rect) && ([NSApp isActive])) {
|
||||
if (handle_mouse_enter(frame, view, point, &mx, &my, &buttons))
|
||||
if ([event window] == osx_window &&
|
||||
[view mouse:point inRect:[view frame]]) {
|
||||
handle_mouse_enter();
|
||||
|
||||
if (_mouse_on) {
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
}
|
||||
[NSApp sendEvent: event];
|
||||
break;
|
||||
|
||||
case NSMouseExited:
|
||||
if ([event trackingNumber] == osx_mouse_tracking_rect) {
|
||||
if (handle_mouse_leave())
|
||||
gotmouseevent = YES;
|
||||
if (handle_mouse_leave()) {
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
[NSApp sendEvent: event];
|
||||
break;
|
||||
|
||||
case NSAppKitDefined:
|
||||
switch ([event subtype]) {
|
||||
case NSApplicationActivatedEventType:
|
||||
if (osx_window) {
|
||||
[osx_window invalidateCursorRectsForView: [osx_window contentView]];
|
||||
[osx_window invalidateCursorRectsForView:view];
|
||||
if (_keyboard_installed)
|
||||
osx_keyboard_focused(TRUE, 0);
|
||||
|
||||
handle_mouse_enter(frame, view, point, &mx, &my, &buttons);
|
||||
handle_mouse_enter();
|
||||
|
||||
if (_mouse_on) {
|
||||
mx = point.x;
|
||||
my = point.y;
|
||||
gotmouseevent = YES;
|
||||
}
|
||||
}
|
||||
_switch_in();
|
||||
break;
|
||||
@ -355,6 +369,7 @@ void osx_event_handler()
|
||||
case NSApplicationDeactivatedEventType:
|
||||
if (osx_window && _keyboard_installed)
|
||||
osx_keyboard_focused(FALSE, 0);
|
||||
|
||||
handle_mouse_leave();
|
||||
_switch_out();
|
||||
break;
|
||||
@ -370,20 +385,20 @@ void osx_event_handler()
|
||||
osx_window_first_expose = FALSE;
|
||||
[osx_window setHasShadow: NO];
|
||||
[osx_window setHasShadow: YES];
|
||||
[osx_window invalidateCursorRectsForView: [osx_window contentView]];
|
||||
[osx_window invalidateCursorRectsForView:view];
|
||||
}
|
||||
break;
|
||||
}
|
||||
[NSApp sendEvent: event];
|
||||
break;
|
||||
|
||||
default:
|
||||
[NSApp sendEvent: event];
|
||||
break;
|
||||
}
|
||||
|
||||
if (send_event == YES)
|
||||
[NSApp sendEvent: event];
|
||||
|
||||
if (gotmouseevent == YES)
|
||||
osx_mouse_handler(mx, my, dx, dy, dz, buttons);
|
||||
}
|
||||
if (gotmouseevent == YES)
|
||||
osx_mouse_handler(mx, my, dx, dy, dz, buttons);
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
|
@ -146,6 +146,7 @@ add_library(app-lib
|
||||
commands/cmd_launch.cpp
|
||||
commands/cmd_layer_from_background.cpp
|
||||
commands/cmd_layer_properties.cpp
|
||||
commands/cmd_layer_visibility.cpp
|
||||
commands/cmd_load_mask.cpp
|
||||
commands/cmd_load_palette.cpp
|
||||
commands/cmd_mask_all.cpp
|
||||
@ -230,6 +231,7 @@ add_library(app-lib
|
||||
file/tga_format.cpp
|
||||
file_selector.cpp
|
||||
file_system.cpp
|
||||
filename_formatter.cpp
|
||||
flatten.cpp
|
||||
gui_xml.cpp
|
||||
handle_anidir.cpp
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "app/file/file_formats_manager.h"
|
||||
#include "app/file/palette_file.h"
|
||||
#include "app/file_system.h"
|
||||
#include "app/filename_formatter.h"
|
||||
#include "app/find_widget.h"
|
||||
#include "app/gui_xml.h"
|
||||
#include "app/ini_file.h"
|
||||
@ -226,6 +227,7 @@ void App::initialize(const AppOptions& options)
|
||||
bool splitLayersSaveAs = false;
|
||||
std::string importLayer;
|
||||
std::string importLayerSaveAs;
|
||||
std::string filenameFormat;
|
||||
|
||||
for (const auto& value : options.values()) {
|
||||
const AppOptions::Option* opt = value.option();
|
||||
@ -271,6 +273,10 @@ void App::initialize(const AppOptions& options)
|
||||
else if (opt == &options.ignoreEmpty()) {
|
||||
ignoreEmpty = true;
|
||||
}
|
||||
// --filename-format
|
||||
else if (opt == &options.filenameFormat()) {
|
||||
filenameFormat = value.value();
|
||||
}
|
||||
// --save-as <filename>
|
||||
else if (opt == &options.saveAs()) {
|
||||
Document* doc = NULL;
|
||||
@ -283,30 +289,35 @@ void App::initialize(const AppOptions& options)
|
||||
else {
|
||||
ctx->setActiveDocument(doc);
|
||||
|
||||
std::string format = filenameFormat;
|
||||
|
||||
Command* command = CommandsModule::instance()->getCommandByName(CommandId::SaveFileCopyAs);
|
||||
if (splitLayersSaveAs) {
|
||||
std::vector<Layer*> layers;
|
||||
doc->sprite()->getLayersList(layers);
|
||||
|
||||
std::string fn, fmt;
|
||||
if (format.empty()) {
|
||||
if (doc->sprite()->totalFrames() > frame_t(1))
|
||||
format = "{path}/{title} ({layer}) {frame}.{extension}";
|
||||
else
|
||||
format = "{path}/{title} ({layer}).{extension}";
|
||||
}
|
||||
|
||||
// For each layer, hide other ones and save the sprite.
|
||||
for (Layer* show : layers) {
|
||||
for (Layer* hide : layers)
|
||||
hide->setVisible(hide == show);
|
||||
|
||||
std::string frameStr;
|
||||
if (doc->sprite()->totalFrames() > frame_t(1))
|
||||
frameStr += " 1";
|
||||
fn = filename_formatter(format,
|
||||
value.value(), show->name());
|
||||
fmt = filename_formatter(format,
|
||||
value.value(), show->name(), -1, false);
|
||||
|
||||
std::string fn = value.value();
|
||||
fn =
|
||||
base::join_path(
|
||||
base::get_file_path(fn),
|
||||
base::get_file_title(fn))
|
||||
+ " (" + show->name() + ")" + frameStr + "." +
|
||||
base::get_file_extension(fn);
|
||||
|
||||
static_cast<SaveFileBaseCommand*>(command)->setFilename(fn);
|
||||
ctx->executeCommand(command);
|
||||
Params params;
|
||||
params.set("filename", fn.c_str());
|
||||
params.set("filename-format", fmt.c_str());
|
||||
ctx->executeCommand(command, ¶ms);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -319,8 +330,10 @@ void App::initialize(const AppOptions& options)
|
||||
layer->setVisible(layer->name() == importLayerSaveAs);
|
||||
}
|
||||
|
||||
static_cast<SaveFileBaseCommand*>(command)->setFilename(value.value());
|
||||
ctx->executeCommand(command);
|
||||
Params params;
|
||||
params.set("filename", value.value().c_str());
|
||||
params.set("filename-format", format.c_str());
|
||||
ctx->executeCommand(command, ¶ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -387,6 +400,9 @@ void App::initialize(const AppOptions& options)
|
||||
splitLayers = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_exporter && !filenameFormat.empty())
|
||||
m_exporter->setFilenameFormat(filenameFormat);
|
||||
}
|
||||
|
||||
// Export
|
||||
|
@ -49,6 +49,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
, m_splitLayers(m_po.add("split-layers").description("Import each layer of the next given sprite as\na separated image in the sheet"))
|
||||
, m_importLayer(m_po.add("import-layer").requiresValue("<name>").description("Import just one layer of the next given sprite"))
|
||||
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
|
||||
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
|
||||
, m_verbose(m_po.add("verbose").description("Explain what is being done"))
|
||||
, m_help(m_po.add("help").mnemonic('?').description("Display this help and exits"))
|
||||
, m_version(m_po.add("version").description("Output version information and exit"))
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
const Option& splitLayers() const { return m_splitLayers; }
|
||||
const Option& importLayer() const { return m_importLayer; }
|
||||
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
|
||||
const Option& filenameFormat() const { return m_filenameFormat; }
|
||||
|
||||
bool hasExporterParams() const;
|
||||
|
||||
@ -84,6 +85,7 @@ private:
|
||||
Option& m_splitLayers;
|
||||
Option& m_importLayer;
|
||||
Option& m_ignoreEmpty;
|
||||
Option& m_filenameFormat;
|
||||
|
||||
Option& m_verbose;
|
||||
Option& m_help;
|
||||
|
@ -131,14 +131,16 @@ void FlipCommand::onExecute(Context* context)
|
||||
|
||||
// Flip the portion of image specified by "bounds" variable.
|
||||
if (!alreadyFlipped) {
|
||||
api.setCelPosition
|
||||
(sprite, cel,
|
||||
(m_flipType == doc::algorithm::FlipHorizontal ?
|
||||
sprite->width() - image->width() - cel->x():
|
||||
cel->x()),
|
||||
(m_flipType == doc::algorithm::FlipVertical ?
|
||||
sprite->height() - image->height() - cel->y():
|
||||
cel->y()));
|
||||
if (!document->isMaskVisible()) {
|
||||
api.setCelPosition
|
||||
(sprite, cel,
|
||||
(m_flipType == doc::algorithm::FlipHorizontal ?
|
||||
sprite->width() - image->width() - cel->x():
|
||||
cel->x()),
|
||||
(m_flipType == doc::algorithm::FlipVertical ?
|
||||
sprite->height() - image->height() - cel->y():
|
||||
cel->y()));
|
||||
}
|
||||
|
||||
api.flipImage(image, bounds, m_flipType);
|
||||
}
|
||||
|
85
src/app/commands/cmd_layer_visibility.cpp
Normal file
85
src/app/commands/cmd_layer_visibility.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2015 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
|
||||
#include "generated_layer_properties.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
class LayerVisibilityCommand : public Command {
|
||||
public:
|
||||
LayerVisibilityCommand();
|
||||
Command* clone() const override { return new LayerVisibilityCommand(*this); }
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
bool onChecked(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LayerVisibilityCommand::LayerVisibilityCommand()
|
||||
: Command("LayerVisibility",
|
||||
"Layer Visibility",
|
||||
CmdRecordableFlag)
|
||||
{
|
||||
}
|
||||
|
||||
bool LayerVisibilityCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::HasActiveLayer);
|
||||
}
|
||||
|
||||
bool LayerVisibilityCommand::onChecked(Context* context)
|
||||
{
|
||||
const ContextReader reader(context);
|
||||
const Layer* layer = reader.layer();
|
||||
return (layer && layer->isVisible());
|
||||
}
|
||||
|
||||
void LayerVisibilityCommand::onExecute(Context* context)
|
||||
{
|
||||
ContextWriter writer(context);
|
||||
Layer* layer = writer.layer();
|
||||
|
||||
layer->setVisible(!layer->isVisible());
|
||||
|
||||
update_screen_for_document(writer.document());
|
||||
}
|
||||
|
||||
Command* CommandFactory::createLayerVisibilityCommand()
|
||||
{
|
||||
return new LayerVisibilityCommand;
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -20,6 +20,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/cmd_save_file.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
@ -79,9 +81,11 @@ private:
|
||||
FileOp* m_fop;
|
||||
};
|
||||
|
||||
static void save_document_in_background(Context* context, Document* document, bool mark_as_saved)
|
||||
static void save_document_in_background(Context* context, Document* document,
|
||||
bool mark_as_saved, const std::string& fn_format)
|
||||
{
|
||||
base::UniquePtr<FileOp> fop(fop_to_save_document(context, document));
|
||||
base::UniquePtr<FileOp> fop(fop_to_save_document(context, document,
|
||||
fn_format.c_str()));
|
||||
if (!fop)
|
||||
return;
|
||||
|
||||
@ -113,111 +117,112 @@ static void save_document_in_background(Context* context, Document* document, bo
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SaveFileBaseCommand : public Command {
|
||||
public:
|
||||
SaveFileBaseCommand(const char* short_name, const char* friendly_name, CommandFlags flags)
|
||||
: Command(short_name, friendly_name, flags) {
|
||||
SaveFileBaseCommand::SaveFileBaseCommand(const char* short_name, const char* friendly_name, CommandFlags flags)
|
||||
: Command(short_name, friendly_name, flags)
|
||||
{
|
||||
}
|
||||
|
||||
void SaveFileBaseCommand::onLoadParams(Params* params)
|
||||
{
|
||||
m_filename = params->get("filename");
|
||||
m_filenameFormat = params->get("filename-format");
|
||||
}
|
||||
|
||||
// Returns true if there is a current sprite to save.
|
||||
// [main thread]
|
||||
bool SaveFileBaseCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
}
|
||||
|
||||
void SaveFileBaseCommand::saveAsDialog(const ContextReader& reader, const char* dlgTitle, bool markAsSaved)
|
||||
{
|
||||
const Document* document = reader.document();
|
||||
std::string filename;
|
||||
|
||||
if (!m_filename.empty()) {
|
||||
filename = m_filename;
|
||||
}
|
||||
else {
|
||||
filename = document->filename();
|
||||
|
||||
protected:
|
||||
void onLoadParams(Params* params) override {
|
||||
m_filename = params->get("filename");
|
||||
}
|
||||
char exts[4096];
|
||||
get_writable_extensions(exts, sizeof(exts));
|
||||
|
||||
// Returns true if there is a current sprite to save.
|
||||
// [main thread]
|
||||
bool onEnabled(Context* context) override {
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
}
|
||||
for (;;) {
|
||||
std::string newfilename = app::show_file_selector(dlgTitle, filename, exts);
|
||||
if (newfilename.empty())
|
||||
return;
|
||||
|
||||
void saveAsDialog(const ContextReader& reader, const char* dlgTitle, bool markAsSaved)
|
||||
{
|
||||
const Document* document = reader.document();
|
||||
std::string filename;
|
||||
filename = newfilename;
|
||||
|
||||
if (!m_filename.empty()) {
|
||||
filename = m_filename;
|
||||
}
|
||||
else {
|
||||
filename = document->filename();
|
||||
// Ask if the user wants overwrite the existent file.
|
||||
int ret = 0;
|
||||
if (base::is_file(filename)) {
|
||||
ret = ui::Alert::show("Warning<<The file already exists, overwrite it?<<%s||&Yes||&No||&Cancel",
|
||||
base::get_file_name(filename).c_str());
|
||||
|
||||
char exts[4096];
|
||||
get_writable_extensions(exts, sizeof(exts));
|
||||
|
||||
for (;;) {
|
||||
std::string newfilename = app::show_file_selector(dlgTitle, filename, exts);
|
||||
if (newfilename.empty())
|
||||
return;
|
||||
|
||||
filename = newfilename;
|
||||
|
||||
// Ask if the user wants overwrite the existent file.
|
||||
int ret = 0;
|
||||
if (base::is_file(filename)) {
|
||||
ret = ui::Alert::show("Warning<<The file already exists, overwrite it?<<%s||&Yes||&No||&Cancel",
|
||||
base::get_file_name(filename).c_str());
|
||||
|
||||
// Check for read-only attribute.
|
||||
if (ret == 1) {
|
||||
if (!confirmReadonly(filename))
|
||||
ret = 2; // Select file again.
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
// "yes": we must continue with the operation...
|
||||
// Check for read-only attribute.
|
||||
if (ret == 1) {
|
||||
break;
|
||||
if (!confirmReadonly(filename))
|
||||
ret = 2; // Select file again.
|
||||
else
|
||||
break;
|
||||
}
|
||||
// "cancel" or <esc> per example: we back doing nothing
|
||||
else if (ret != 2)
|
||||
return;
|
||||
|
||||
// "no": we must back to select other file-name
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
{
|
||||
ContextWriter writer(reader);
|
||||
Document* documentWriter = writer.document();
|
||||
std::string oldFilename = documentWriter->filename();
|
||||
// "yes": we must continue with the operation...
|
||||
if (ret == 1) {
|
||||
break;
|
||||
}
|
||||
// "cancel" or <esc> per example: we back doing nothing
|
||||
else if (ret != 2)
|
||||
return;
|
||||
|
||||
// Change the document file name
|
||||
documentWriter->setFilename(filename.c_str());
|
||||
m_selectedFilename = filename;
|
||||
|
||||
// Save the document
|
||||
save_document_in_background(writer.context(), documentWriter, markAsSaved);
|
||||
|
||||
if (documentWriter->isModified())
|
||||
documentWriter->setFilename(oldFilename);
|
||||
|
||||
update_screen_for_document(documentWriter);
|
||||
// "no": we must back to select other file-name
|
||||
}
|
||||
}
|
||||
|
||||
static bool confirmReadonly(const std::string& filename)
|
||||
{
|
||||
if (!base::has_readonly_attr(filename))
|
||||
return true;
|
||||
ContextWriter writer(reader);
|
||||
Document* documentWriter = writer.document();
|
||||
std::string oldFilename = documentWriter->filename();
|
||||
|
||||
int ret = ui::Alert::show("Warning<<The file is read-only, do you really want to overwrite it?<<%s||&Yes||&No",
|
||||
base::get_file_name(filename).c_str());
|
||||
// Change the document file name
|
||||
documentWriter->setFilename(filename.c_str());
|
||||
m_selectedFilename = filename;
|
||||
|
||||
if (ret == 1) {
|
||||
base::remove_readonly_attr(filename);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
// Save the document
|
||||
save_document_in_background(writer.context(), documentWriter,
|
||||
markAsSaved, m_filenameFormat);
|
||||
|
||||
if (documentWriter->isModified())
|
||||
documentWriter->setFilename(oldFilename);
|
||||
|
||||
update_screen_for_document(documentWriter);
|
||||
}
|
||||
}
|
||||
|
||||
std::string m_filename;
|
||||
std::string m_selectedFilename;
|
||||
};
|
||||
//static
|
||||
bool SaveFileBaseCommand::confirmReadonly(const std::string& filename)
|
||||
{
|
||||
if (!base::has_readonly_attr(filename))
|
||||
return true;
|
||||
|
||||
int ret = ui::Alert::show("Warning<<The file is read-only, do you really want to overwrite it?<<%s||&Yes||&No",
|
||||
base::get_file_name(filename).c_str());
|
||||
|
||||
if (ret == 1) {
|
||||
base::remove_readonly_attr(filename);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SaveFileCommand : public SaveFileBaseCommand {
|
||||
public:
|
||||
@ -249,7 +254,8 @@ void SaveFileCommand::onExecute(Context* context)
|
||||
if (!confirmReadonly(documentWriter->filename()))
|
||||
return;
|
||||
|
||||
save_document_in_background(context, documentWriter, true);
|
||||
save_document_in_background(context, documentWriter, true,
|
||||
m_filenameFormat.c_str());
|
||||
update_screen_for_document(documentWriter);
|
||||
}
|
||||
// If the document isn't associated to a file, we must to show the
|
||||
|
@ -35,10 +35,6 @@ namespace app {
|
||||
return m_selectedFilename;
|
||||
}
|
||||
|
||||
void setFilename(const std::string& fn) {
|
||||
m_filename = fn;
|
||||
}
|
||||
|
||||
protected:
|
||||
void onLoadParams(Params* params) override;
|
||||
bool onEnabled(Context* context) override;
|
||||
@ -48,6 +44,7 @@ namespace app {
|
||||
static bool confirmReadonly(const std::string& filename);
|
||||
|
||||
std::string m_filename;
|
||||
std::string m_filenameFormat;
|
||||
std::string m_selectedFilename;
|
||||
};
|
||||
|
||||
|
@ -65,6 +65,7 @@ FOR_EACH_COMMAND(KeyboardShortcuts)
|
||||
FOR_EACH_COMMAND(Launch)
|
||||
FOR_EACH_COMMAND(LayerFromBackground)
|
||||
FOR_EACH_COMMAND(LayerProperties)
|
||||
FOR_EACH_COMMAND(LayerVisibility)
|
||||
FOR_EACH_COMMAND(LoadMask)
|
||||
FOR_EACH_COMMAND(LoadPalette)
|
||||
FOR_EACH_COMMAND(MakeUniqueEditor)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "app/console.h"
|
||||
#include "app/document.h"
|
||||
#include "app/file/file.h"
|
||||
#include "app/filename_formatter.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/path.h"
|
||||
@ -272,24 +273,28 @@ void DocumentExporter::captureSamples(Samples& samples)
|
||||
Document* doc = item.doc;
|
||||
Sprite* sprite = doc->sprite();
|
||||
Layer* layer = item.layer;
|
||||
bool hasFrames = (doc->sprite()->totalFrames() > frame_t(1));
|
||||
bool hasLayer = (layer != NULL);
|
||||
|
||||
std::string format = m_filenameFormat;
|
||||
if (format.empty()) {
|
||||
if (hasFrames && hasLayer)
|
||||
format = "{title} ({layer}) {frame}.{extension}";
|
||||
else if (hasFrames)
|
||||
format = "{title} {frame}.{extension}";
|
||||
else if (hasLayer)
|
||||
format = "{title} ({layer}).{extension}";
|
||||
else
|
||||
format = "{fullname}";
|
||||
}
|
||||
|
||||
for (frame_t frame=frame_t(0);
|
||||
frame<sprite->totalFrames(); ++frame) {
|
||||
std::string filename = doc->filename();
|
||||
|
||||
if (sprite->totalFrames() > frame_t(1)) {
|
||||
std::string path = base::get_file_path(filename);
|
||||
std::string title = base::get_file_title(filename);
|
||||
if (layer) {
|
||||
title += " (";
|
||||
title += layer->name();
|
||||
title += ") ";
|
||||
}
|
||||
|
||||
filename = base::join_path(path, title +
|
||||
base::convert_to<std::string>((int)frame + 1)
|
||||
+ "." + base::get_file_extension(filename));
|
||||
}
|
||||
std::string filename =
|
||||
filename_formatter(format,
|
||||
doc->filename(),
|
||||
layer ? layer->name(): "",
|
||||
(sprite->totalFrames() > frame_t(1)) ? frame: frame_t(-1));
|
||||
|
||||
Sample sample(doc, sprite, layer, frame, filename);
|
||||
|
||||
|
@ -93,6 +93,10 @@ namespace app {
|
||||
m_ignoreEmptyCels = ignore;
|
||||
}
|
||||
|
||||
void setFilenameFormat(const std::string& format) {
|
||||
m_filenameFormat = format;
|
||||
}
|
||||
|
||||
void addDocument(Document* document, doc::Layer* layer = NULL) {
|
||||
m_documents.push_back(Item(document, layer));
|
||||
}
|
||||
@ -133,6 +137,7 @@ namespace app {
|
||||
ScaleMode m_scaleMode;
|
||||
bool m_ignoreEmptyCels;
|
||||
Items m_documents;
|
||||
std::string m_filenameFormat;
|
||||
|
||||
DISABLE_COPYING(DocumentExporter);
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "app/file/file_formats_manager.h"
|
||||
#include "app/file/format_options.h"
|
||||
#include "app/file/split_filename.h"
|
||||
#include "app/filename_formatter.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
@ -120,7 +121,8 @@ int save_document(Context* context, doc::Document* document)
|
||||
ASSERT(dynamic_cast<app::Document*>(document));
|
||||
|
||||
int ret;
|
||||
FileOp* fop = fop_to_save_document(context, static_cast<app::Document*>(document));
|
||||
FileOp* fop = fop_to_save_document(context,
|
||||
static_cast<app::Document*>(document), "");
|
||||
if (!fop)
|
||||
return -1;
|
||||
|
||||
@ -235,7 +237,7 @@ done:;
|
||||
return fop;
|
||||
}
|
||||
|
||||
FileOp* fop_to_save_document(Context* context, Document* document)
|
||||
FileOp* fop_to_save_document(Context* context, Document* document, const char* fn_format_arg)
|
||||
{
|
||||
FileOp *fop;
|
||||
bool fatal;
|
||||
@ -359,26 +361,59 @@ FileOp* fop_to_save_document(Context* context, Document* document)
|
||||
if (fop->format->support(FILE_SUPPORT_SEQUENCES)) {
|
||||
fop_prepare_for_sequence(fop);
|
||||
|
||||
// To save one frame
|
||||
if (fop->document->sprite()->totalFrames() == 1) {
|
||||
fop->seq.filename_list.push_back(fop->document->filename());
|
||||
}
|
||||
// To save more frames
|
||||
else {
|
||||
std::string left, right;
|
||||
int width, start_from;
|
||||
std::string fn = fop->document->filename();
|
||||
std::string fn_format = fn_format_arg;
|
||||
bool default_format = false;
|
||||
|
||||
start_from = split_filename(fop->document->filename().c_str(), left, right, width);
|
||||
if (start_from < 0) {
|
||||
start_from = 1;
|
||||
width = 1;
|
||||
if (fn_format.empty()) {
|
||||
if (fop->document->sprite()->totalFrames() == 1)
|
||||
fn_format = "{fullname}";
|
||||
else {
|
||||
fn_format = "{path}/{title}{frame}.{extension}";
|
||||
default_format = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Save one frame
|
||||
if (fop->document->sprite()->totalFrames() == 1) {
|
||||
fn = filename_formatter(fn_format, fn);
|
||||
fop->seq.filename_list.push_back(fn);
|
||||
}
|
||||
// Save multiple frames
|
||||
else {
|
||||
int width = 0;
|
||||
int start_from = 0;
|
||||
|
||||
if (default_format) {
|
||||
std::string left, right;
|
||||
start_from = split_filename(fn.c_str(), left, right, width);
|
||||
if (start_from < 0) {
|
||||
start_from = 1;
|
||||
width = 1;
|
||||
}
|
||||
else {
|
||||
fn = left;
|
||||
fn += right;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char> buf(32);
|
||||
std::sprintf(&buf[0], "{frame%0*d}", width, 0);
|
||||
if (default_format)
|
||||
fn_format = set_frame_format(fn_format, &buf[0]);
|
||||
else if (fop->document->sprite()->totalFrames() > 1)
|
||||
fn_format = add_frame_format(fn_format, &buf[0]);
|
||||
|
||||
printf("start_from = %d\n", start_from);
|
||||
printf("fn_format = %s\n", fn_format.c_str());
|
||||
printf("fn = %s\n", fn.c_str());
|
||||
|
||||
for (frame_t frame(0); frame<fop->document->sprite()->totalFrames(); ++frame) {
|
||||
// Get the name for this frame
|
||||
char buf[4096];
|
||||
sprintf(buf, "%s%0*d%s", left.c_str(), width, start_from+frame, right.c_str());
|
||||
fop->seq.filename_list.push_back(buf);
|
||||
std::string frame_fn =
|
||||
filename_formatter(fn_format, fn, "", start_from+frame);
|
||||
|
||||
printf("frame_fn = %s\n", frame_fn.c_str());
|
||||
fop->seq.filename_list.push_back(frame_fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ namespace app {
|
||||
// Low-level routines to load/save documents.
|
||||
|
||||
FileOp* fop_to_load_document(Context* context, const char* filename, int flags);
|
||||
FileOp* fop_to_save_document(Context* context, Document* document);
|
||||
FileOp* fop_to_save_document(Context* context, Document* document, const char* fn_format);
|
||||
void fop_operate(FileOp* fop, IFileOpProgress* progress);
|
||||
void fop_done(FileOp* fop);
|
||||
void fop_stop(FileOp* fop);
|
||||
|
@ -545,7 +545,7 @@ bool GifFormat::onSave(FileOp* fop)
|
||||
int sprite_h = sprite->height();
|
||||
PixelFormat sprite_format = sprite->pixelFormat();
|
||||
bool interlaced = gif_options->interlaced();
|
||||
int loop = 0;
|
||||
int loop = (gif_options->loop() ? 0: -1);
|
||||
bool has_background = (sprite->backgroundLayer() ? true: false);
|
||||
int background_color = (sprite_format == IMAGE_INDEXED ? sprite->transparentColor(): 0);
|
||||
int transparent_index = (has_background ? -1: sprite->transparentColor());
|
||||
@ -801,6 +801,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
|
||||
// Configuration parameters
|
||||
gif_options->setQuantize((GifOptions::Quantize)get_config_int("GIF", "Quantize", (int)gif_options->quantize()));
|
||||
gif_options->setInterlaced(get_config_bool("GIF", "Interlaced", gif_options->interlaced()));
|
||||
gif_options->setLoop(get_config_bool("GIF", "Loop", gif_options->loop()));
|
||||
gif_options->setDithering((doc::DitheringMethod)get_config_int("GIF", "Dither", (int)gif_options->dithering()));
|
||||
|
||||
// Load the window to ask to the user the GIF options he wants.
|
||||
@ -814,6 +815,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
|
||||
case GifOptions::QuantizeAll: win.quantizeAll()->setSelected(true); break;
|
||||
}
|
||||
win.interlaced()->setSelected(gif_options->interlaced());
|
||||
win.loop()->setSelected(gif_options->loop());
|
||||
|
||||
win.dither()->setEnabled(true);
|
||||
win.dither()->setSelected(gif_options->dithering() == doc::DitheringMethod::ORDERED);
|
||||
@ -829,12 +831,14 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
|
||||
gif_options->setQuantize(GifOptions::NoQuantize);
|
||||
|
||||
gif_options->setInterlaced(win.interlaced()->isSelected());
|
||||
gif_options->setLoop(win.loop()->isSelected());
|
||||
gif_options->setDithering(win.dither()->isSelected() ?
|
||||
doc::DitheringMethod::ORDERED:
|
||||
doc::DitheringMethod::NONE);
|
||||
|
||||
set_config_int("GIF", "Quantize", gif_options->quantize());
|
||||
set_config_bool("GIF", "Interlaced", gif_options->interlaced());
|
||||
set_config_bool("GIF", "Loop", gif_options->loop());
|
||||
set_config_int("GIF", "Dither", int(gif_options->dithering()));
|
||||
}
|
||||
else {
|
||||
|
@ -33,23 +33,28 @@ namespace app {
|
||||
GifOptions(
|
||||
Quantize quantize = QuantizeEach,
|
||||
bool interlaced = false,
|
||||
bool loop = true,
|
||||
DitheringMethod dithering = doc::DitheringMethod::NONE)
|
||||
: m_quantize(quantize)
|
||||
, m_interlaced(interlaced)
|
||||
, m_loop(loop)
|
||||
, m_dithering(dithering) {
|
||||
}
|
||||
|
||||
Quantize quantize() const { return m_quantize; }
|
||||
bool interlaced() const { return m_interlaced; }
|
||||
bool loop() const { return m_loop; }
|
||||
doc::DitheringMethod dithering() const { return m_dithering; }
|
||||
|
||||
void setQuantize(const Quantize quantize) { m_quantize = quantize; }
|
||||
void setInterlaced(bool interlaced) { m_interlaced = interlaced; }
|
||||
void setLoop(bool loop) { m_loop = loop; }
|
||||
void setDithering(const doc::DitheringMethod dithering) { m_dithering = dithering; }
|
||||
|
||||
private:
|
||||
Quantize m_quantize;
|
||||
bool m_interlaced;
|
||||
bool m_loop;
|
||||
doc::DitheringMethod m_dithering;
|
||||
};
|
||||
|
||||
|
105
src/app/filename_formatter.cpp
Normal file
105
src/app/filename_formatter.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2015 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/filename_formatter.h"
|
||||
|
||||
#include "base/convert_to.h"
|
||||
#include "base/path.h"
|
||||
#include "base/replace_string.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
|
||||
std::string filename_formatter(
|
||||
const std::string& format,
|
||||
const std::string& filename,
|
||||
const std::string& layerName,
|
||||
int frame, bool replaceFrame)
|
||||
{
|
||||
std::string output = format;
|
||||
base::replace_string(output, "{fullname}", filename);
|
||||
base::replace_string(output, "{path}", base::get_file_path(filename));
|
||||
base::replace_string(output, "{name}", base::get_file_name(filename));
|
||||
base::replace_string(output, "{title}", base::get_file_title(filename));
|
||||
base::replace_string(output, "{extension}", base::get_file_extension(filename));
|
||||
base::replace_string(output, "{layer}", layerName);
|
||||
|
||||
if (replaceFrame) {
|
||||
size_t i = output.find("{frame");
|
||||
if (i != std::string::npos) {
|
||||
size_t j = output.find("}", i+6);
|
||||
if (j != std::string::npos) {
|
||||
std::string from = output.substr(i, j - i + 1);
|
||||
if (frame >= 0) {
|
||||
std::vector<char> to(32);
|
||||
int offset = std::strtol(from.c_str()+6, NULL, 10);
|
||||
|
||||
std::sprintf(&to[0], "%0*d", (int(j)-int(i+6)), frame + offset);
|
||||
base::replace_string(output, from, &to[0]);
|
||||
}
|
||||
else
|
||||
base::replace_string(output, from, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string set_frame_format(
|
||||
const std::string& format,
|
||||
const std::string& newFrameFormat)
|
||||
{
|
||||
std::string output = format;
|
||||
|
||||
size_t i = output.find("{frame");
|
||||
if (i != std::string::npos) {
|
||||
size_t j = output.find("}", i+6);
|
||||
if (j != std::string::npos) {
|
||||
output.replace(i, j - i + 1, newFrameFormat);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string add_frame_format(
|
||||
const std::string& format,
|
||||
const std::string& newFrameFormat)
|
||||
{
|
||||
std::string output = format;
|
||||
|
||||
size_t i = output.find("{frame");
|
||||
if (i == std::string::npos) {
|
||||
output =
|
||||
base::join_path(
|
||||
base::get_file_path(format),
|
||||
base::get_file_title(format))
|
||||
+ newFrameFormat + "." +
|
||||
base::get_file_extension(format);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace app
|
44
src/app/filename_formatter.h
Normal file
44
src/app/filename_formatter.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2015 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef APP_FILENAME_FORMATTER_H_INCLUDED
|
||||
#define APP_FILENAME_FORMATTER_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
|
||||
std::string filename_formatter(
|
||||
const std::string& format,
|
||||
const std::string& filename,
|
||||
const std::string& layerName = "",
|
||||
int frame = -1,
|
||||
bool replaceFrame = true);
|
||||
|
||||
std::string set_frame_format(
|
||||
const std::string& format,
|
||||
const std::string& newFrameFormat);
|
||||
|
||||
std::string add_frame_format(
|
||||
const std::string& format,
|
||||
const std::string& newFrameFormat);
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
142
src/app/filename_formatter_tests.cpp
Normal file
142
src/app/filename_formatter_tests.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2015 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "app/filename_formatter.h"
|
||||
|
||||
#include "base/path.h"
|
||||
|
||||
using namespace app;
|
||||
|
||||
TEST(FilenameFormatter, Basic)
|
||||
{
|
||||
EXPECT_EQ("C:/temp/file.png",
|
||||
filename_formatter("{fullname}",
|
||||
"C:/temp/file.png"));
|
||||
|
||||
EXPECT_EQ("file.png",
|
||||
filename_formatter("{name}",
|
||||
"C:/temp/file.png"));
|
||||
|
||||
EXPECT_EQ("C:/temp/other.png",
|
||||
filename_formatter("{path}/other.png",
|
||||
"C:/temp/file.png"));
|
||||
}
|
||||
|
||||
TEST(FilenameFormatter, WithoutFrame)
|
||||
{
|
||||
EXPECT_EQ("C:/temp/file.png",
|
||||
filename_formatter("{path}/{title}.png",
|
||||
"C:/temp/file.ase"));
|
||||
|
||||
EXPECT_EQ("C:/temp/file.png",
|
||||
filename_formatter("{path}/{title}{frame}.{extension}",
|
||||
"C:/temp/file.png"));
|
||||
|
||||
EXPECT_EQ("C:/temp/file{frame}.png",
|
||||
filename_formatter("{path}/{title}{frame}.{extension}",
|
||||
"C:/temp/file.png", "", -1, false));
|
||||
|
||||
EXPECT_EQ("C:/temp/file (Background).png",
|
||||
filename_formatter("{path}/{title} ({layer}).{extension}",
|
||||
"C:/temp/file.png", "Background"));
|
||||
}
|
||||
|
||||
TEST(FilenameFormatter, WithFrame)
|
||||
{
|
||||
EXPECT_EQ("C:/temp/file0.png",
|
||||
filename_formatter("{path}/{title}{frame}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file1.png",
|
||||
filename_formatter("{path}/{title}{frame}.{extension}",
|
||||
"C:/temp/file.png", "", 1));
|
||||
|
||||
EXPECT_EQ("C:/temp/file10.png",
|
||||
filename_formatter("{path}/{title}{frame}.{extension}",
|
||||
"C:/temp/file.png", "", 10));
|
||||
|
||||
EXPECT_EQ("C:/temp/file0.png",
|
||||
filename_formatter("{path}/{title}{frame0}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file1.png",
|
||||
filename_formatter("{path}/{title}{frame1}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file2.png",
|
||||
filename_formatter("{path}/{title}{frame1}.{extension}",
|
||||
"C:/temp/file.png", "", 1));
|
||||
|
||||
EXPECT_EQ("C:/temp/file00.png",
|
||||
filename_formatter("{path}/{title}{frame00}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file01.png",
|
||||
filename_formatter("{path}/{title}{frame01}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file002.png",
|
||||
filename_formatter("{path}/{title}{frame000}.{extension}",
|
||||
"C:/temp/file.png", "", 2));
|
||||
|
||||
EXPECT_EQ("C:/temp/file0032.png",
|
||||
filename_formatter("{path}/{title}{frame0032}.{extension}",
|
||||
"C:/temp/file.png", "", 0));
|
||||
|
||||
EXPECT_EQ("C:/temp/file-Background-2.png",
|
||||
filename_formatter("{path}/{title}-{layer}-{frame}.{extension}",
|
||||
"C:/temp/file.png", "Background", 2));
|
||||
}
|
||||
|
||||
TEST(SetFrameFormat, Tests)
|
||||
{
|
||||
EXPECT_EQ("{path}/{title}{frame1}.{extension}",
|
||||
set_frame_format("{path}/{title}{frame}.{extension}",
|
||||
"{frame1}"));
|
||||
|
||||
EXPECT_EQ("{path}/{title}{frame01}.{extension}",
|
||||
set_frame_format("{path}/{title}{frame}.{extension}",
|
||||
"{frame01}"));
|
||||
|
||||
EXPECT_EQ("{path}/{title}{frame}.{extension}",
|
||||
set_frame_format("{path}/{title}{frame01}.{extension}",
|
||||
"{frame}"));
|
||||
}
|
||||
|
||||
TEST(AddFrameFormat, Tests)
|
||||
{
|
||||
EXPECT_EQ(base::fix_path_separators("{path}/{title}{frame001}.{extension}"),
|
||||
add_frame_format("{path}/{title}.{extension}",
|
||||
"{frame001}"));
|
||||
|
||||
EXPECT_EQ("{path}/{title}{frame1}.{extension}",
|
||||
add_frame_format("{path}/{title}{frame1}.{extension}",
|
||||
"{frame001}"));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
@ -800,7 +800,7 @@ gfx::Point Editor::autoScroll(MouseMessage* msg, AutoScroll dir, bool blit_valid
|
||||
}
|
||||
setEditorScroll(scroll, blit_valid_rgn);
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32) || defined(__APPLE__)
|
||||
mousePos -= delta;
|
||||
ui::set_mouse_position(mousePos);
|
||||
#endif
|
||||
|
@ -96,8 +96,12 @@ bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
|
||||
|
||||
DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
|
||||
if (range.enabled()) {
|
||||
for (Cel* cel : get_cels_in_range(writer.sprite(), range))
|
||||
api.setCelPosition(writer.sprite(), cel, cel->x()+delta.x, cel->y()+delta.y);
|
||||
for (Cel* cel : get_cels_in_range(writer.sprite(), range)) {
|
||||
Layer* layer = cel->layer();
|
||||
ASSERT(layer);
|
||||
if (layer && layer->isMovable() && !layer->isBackground())
|
||||
api.setCelPosition(writer.sprite(), cel, cel->x()+delta.x, cel->y()+delta.y);
|
||||
}
|
||||
}
|
||||
else if (m_cel) {
|
||||
api.setCelPosition(writer.sprite(), m_cel, m_celNew.x, m_celNew.y);
|
||||
|
@ -238,7 +238,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
|
||||
if (handle != NoHandle) {
|
||||
int x, y, opacity;
|
||||
Image* image = location.image(&x, &y, &opacity);
|
||||
if (image) {
|
||||
if (layer && image) {
|
||||
if (!layer->isEditable()) {
|
||||
StatusBar::instance()->showTip(1000,
|
||||
"Layer '%s' is locked", layer->name().c_str());
|
||||
@ -253,7 +253,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
|
||||
}
|
||||
|
||||
// Move selected pixels
|
||||
if (editor->isInsideSelection() && msg->left()) {
|
||||
if (layer && editor->isInsideSelection() && msg->left()) {
|
||||
if (!layer->isEditable()) {
|
||||
StatusBar::instance()->showTip(1000,
|
||||
"Layer '%s' is locked", layer->name().c_str());
|
||||
|
@ -31,17 +31,32 @@ namespace app {
|
||||
using namespace doc;
|
||||
|
||||
// TODO the DocumentRange should be "iteratable" to replace this function
|
||||
CelList get_cels_in_range(Sprite* sprite, const DocumentRange& range)
|
||||
CelList get_cels_in_range(Sprite* sprite, const DocumentRange& inrange)
|
||||
{
|
||||
DocumentRange range = inrange;
|
||||
CelList cels;
|
||||
|
||||
switch (range.type()) {
|
||||
case DocumentRange::kNone:
|
||||
return cels;
|
||||
case DocumentRange::kCels:
|
||||
break;
|
||||
case DocumentRange::kFrames:
|
||||
range.startRange(LayerIndex(0), inrange.frameBegin(), DocumentRange::kCels);
|
||||
range.endRange(LayerIndex(sprite->countLayers()-1), inrange.frameEnd());
|
||||
break;
|
||||
case DocumentRange::kLayers:
|
||||
range.startRange(inrange.layerBegin(), frame_t(0), DocumentRange::kCels);
|
||||
range.endRange(inrange.layerEnd(), sprite->lastFrame());
|
||||
break;
|
||||
}
|
||||
|
||||
for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) {
|
||||
Layer* layer = sprite->indexToLayer(layerIdx);
|
||||
if (!layer->isImage())
|
||||
if (!layer || !layer->isImage())
|
||||
continue;
|
||||
|
||||
LayerImage* layerImage = static_cast<LayerImage*>(layer);
|
||||
|
||||
for (frame_t frame = range.frameEnd(),
|
||||
begin = range.frameBegin()-1;
|
||||
frame != begin;
|
||||
|
@ -32,6 +32,7 @@ set(BASE_SOURCES
|
||||
mutex.cpp
|
||||
path.cpp
|
||||
program_options.cpp
|
||||
replace_string.cpp
|
||||
serialization.cpp
|
||||
sha1.cpp
|
||||
sha1_rfc3174.c
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2001-2014 David Capello
|
||||
Copyright (c) 2001-2015 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Aseprite Base Library
|
||||
*Copyright (C) 2001-2013 David Capello*
|
||||
*Copyright (C) 2001-2015 David Capello*
|
||||
|
||||
> Distributed under [MIT license](LICENSE.txt)
|
||||
|
||||
|
33
src/base/replace_string.cpp
Normal file
33
src/base/replace_string.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base/replace_string.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
void replace_string(
|
||||
std::string& subject,
|
||||
const std::string& replace_this,
|
||||
const std::string& with_that)
|
||||
{
|
||||
if (replace_this.empty()) // Do nothing case
|
||||
return;
|
||||
|
||||
size_t i = 0;
|
||||
while (true) {
|
||||
i = subject.find(replace_this, i);
|
||||
if (i == std::string::npos)
|
||||
break;
|
||||
subject.replace(i, replace_this.size(), with_that);
|
||||
i += with_that.size();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
22
src/base/replace_string.h
Normal file
22
src/base/replace_string.h
Normal file
@ -0,0 +1,22 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef BASE_REPLACE_STRING_H_INCLUDED
|
||||
#define BASE_REPLACE_STRING_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace base {
|
||||
|
||||
void replace_string(
|
||||
std::string& subject,
|
||||
const std::string& replace_this,
|
||||
const std::string& with_that);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
31
src/base/replace_string_tests.cpp
Normal file
31
src/base/replace_string_tests.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base/replace_string.h"
|
||||
|
||||
inline std::string rs(const std::string& s, const std::string& a, const std::string& b) {
|
||||
std::string res = s;
|
||||
base::replace_string(res, a, b);
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(ReplaceString, Basic)
|
||||
{
|
||||
EXPECT_EQ("", rs("", "", ""));
|
||||
EXPECT_EQ("aa", rs("ab", "b", "a"));
|
||||
EXPECT_EQ("abc", rs("accc", "cc", "b"));
|
||||
EXPECT_EQ("abb", rs("acccc", "cc", "b"));
|
||||
EXPECT_EQ("aabbbbaabbbb", rs("aabbaabb", "bb", "bbbb"));
|
||||
EXPECT_EQ("123123123", rs("111", "1", "123"));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
@ -42,7 +42,7 @@
|
||||
#define WEBSITE_DOWNLOAD WEBSITE "download/"
|
||||
#define WEBSITE_CONTRIBUTORS WEBSITE "contributors/"
|
||||
#define UPDATE_URL WEBSITE "update/?xml=1"
|
||||
#define COPYRIGHT "Copyright (C) 2001-2014 David Capello"
|
||||
#define COPYRIGHT "Copyright (C) 2001-2015 David Capello"
|
||||
|
||||
#define PRINTF verbose_printf
|
||||
|
||||
|
@ -23,7 +23,7 @@ BEGIN
|
||||
VALUE "FileDescription", "Aseprite - Animated sprites editor & pixel art tool"
|
||||
VALUE "FileVersion", "1,1,0,0"
|
||||
VALUE "InternalName", "aseprite"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2001-2014 by David Capello"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2001-2015 by David Capello"
|
||||
VALUE "OriginalFilename", "aseprite.exe"
|
||||
VALUE "ProductName", "ASEPRITE"
|
||||
VALUE "ProductVersion", "1,1,0,0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user