* observing Piano Roll by dragging cursor outside
* dragging blue arrow (moving Playback cursor) * moving Markers by drag'n'drop, "Marker Drag" and "Marker Swap" operations * Config->Doubleclick on Frame# affects Playback * Config->Draw Input by dragging
This commit is contained in:
parent
a484b4eb15
commit
1af2f936ff
|
@ -348,6 +348,8 @@ static CFGSTRUCT fceuconfig[] = {
|
|||
AC(taseditor_config.findnote_matchcase),
|
||||
AC(taseditor_config.findnote_search_up),
|
||||
AC(taseditor_config.deselect_on_doubleclick),
|
||||
AC(taseditor_config.doubleclick_affects_playback),
|
||||
AC(taseditor_config.draw_input),
|
||||
AC(taseditor_config.silent_autosave),
|
||||
AC(taseditor_config.tooltips),
|
||||
AC(taseditor_config.current_pattern),
|
||||
|
|
|
@ -71,6 +71,10 @@
|
|||
#include "utils/xstring.h"
|
||||
#include <string.h>
|
||||
#include "taseditor/taseditor_window.h"
|
||||
#include "taseditor/piano_roll.h"
|
||||
|
||||
extern TASEDITOR_WINDOW taseditor_window;
|
||||
extern PIANO_ROLL piano_roll;
|
||||
|
||||
//---------------------------
|
||||
//mbg merge 6/29/06 - new aboutbox
|
||||
|
@ -308,7 +312,6 @@ int BlockingCheck()
|
|||
{
|
||||
//other accelerator capable dialogs could be added here
|
||||
extern HWND hwndMemWatch;
|
||||
extern TASEDITOR_WINDOW taseditor_window;
|
||||
|
||||
int handled = 0;
|
||||
|
||||
|
@ -336,12 +339,14 @@ int BlockingCheck()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!handled && taseditor_window.hwndTasEditor)
|
||||
{
|
||||
if(IsChild(taseditor_window.hwndTasEditor, msg.hwnd))
|
||||
{
|
||||
handled = TranslateAccelerator(taseditor_window.hwndTasEditor, fceu_hAccel, &msg);
|
||||
if (handled)
|
||||
piano_roll.AcceleratorDispatched();
|
||||
}
|
||||
}
|
||||
if(!handled && taseditor_window.hwndFindNote)
|
||||
{
|
||||
|
|
|
@ -292,6 +292,8 @@ BEGIN
|
|||
MENUITEM MFT_SEPARATOR
|
||||
MENUITEM "Autofire Pattern skips Lag", ID_CONFIG_COLUMNSETPATTERNSKIPSLAG,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Deselect on doubleclick", ID_CONFIG_DESELECTONDOUBLECLICK,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Doubleclick on Frame# affects Playback", ID_CONFIG_DOUBLECLICKONFRAME,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Draw Input by dragging", ID_CONFIG_DRAWINPUTBYDRAGGING,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM MFT_SEPARATOR
|
||||
MENUITEM "Silent Autosave", ID_CONFIG_SILENTAUTOSAVE,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Mute Turbo", ID_CONFIG_MUTETURBO,MFT_STRING,MFS_ENABLED
|
||||
|
@ -1391,56 +1393,56 @@ BEGIN
|
|||
EDITTEXT IDC_LABEL_NEWPPUUSED,76,166,155,12,ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
|
||||
END
|
||||
|
||||
TASEDITOR DIALOGEX 0, 0, 323, 351
|
||||
TASEDITOR DIALOGEX 0, 0, 325, 353
|
||||
STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "TAS Editor"
|
||||
MENU TASEDITORMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,199,36,116,12
|
||||
CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,206,167,104,11
|
||||
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,4,13,187,320
|
||||
GROUPBOX " Playback ",IDC_PLAYBACK_BOX,196,0,123,62,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Recorder ",IDC_RECORDER_BOX,196,63,123,46,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Splicer ",IDC_SPLICER_BOX,196,110,123,30,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Lua ",IDC_LUA_BOX,196,141,123,26,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,196,169,123,102,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " History ",IDC_HISTORY_BOX,196,272,123,56,BS_CENTER,WS_EX_RIGHT
|
||||
PUSHBUTTON "<<",TASEDITOR_REWIND_FULL,200,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "<",TASEDITOR_REWIND,223,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "||",TASEDITOR_PLAYSTOP,246,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">",TASEDITOR_FORWARD,269,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">>",TASEDITOR_FORWARD_FULL,292,9,23,14,NOT WS_TABSTOP
|
||||
CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,200,39,115,6
|
||||
CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,202,25,56,12
|
||||
CONTROL "",IDC_PROGRESS_BUTTON,"Button",BS_OWNERDRAW,200,36,116,12
|
||||
CONTROL "",IDC_BRANCHES_BUTTON,"Button",BS_OWNERDRAW,207,167,104,11
|
||||
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER,5,13,187,320
|
||||
GROUPBOX " Playback ",IDC_PLAYBACK_BOX,197,0,123,62,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Recorder ",IDC_RECORDER_BOX,197,63,123,46,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Splicer ",IDC_SPLICER_BOX,197,110,123,30,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Lua ",IDC_LUA_BOX,197,141,123,26,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " Bookmarks ",IDC_BOOKMARKS_BOX,197,169,123,102,BS_CENTER,WS_EX_RIGHT
|
||||
GROUPBOX " History ",IDC_HISTORY_BOX,197,272,123,56,BS_CENTER,WS_EX_RIGHT
|
||||
PUSHBUTTON "<<",TASEDITOR_REWIND_FULL,201,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "<",TASEDITOR_REWIND,224,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "||",TASEDITOR_PLAYSTOP,247,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">",TASEDITOR_FORWARD,270,9,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">>",TASEDITOR_FORWARD_FULL,293,9,23,14,NOT WS_TABSTOP
|
||||
CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,201,39,115,6
|
||||
CONTROL " Follow cursor",CHECK_FOLLOW_CURSOR,"Button",BS_AUTOCHECKBOX,203,25,56,12
|
||||
CONTROL " Auto-restore last position",CHECK_AUTORESTORE_PLAYBACK,
|
||||
"Button",BS_AUTOCHECKBOX,202,48,105,12
|
||||
CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,201,178,113,89
|
||||
CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,201,282,113,42
|
||||
CONTROL " All",IDC_RADIO_ALL,"Button",BS_AUTORADIOBUTTON,290,71,24,10
|
||||
CONTROL " 1P",IDC_RADIO_1P,"Button",BS_AUTORADIOBUTTON,202,83,25,10
|
||||
CONTROL " 2P",IDC_RADIO_2P,"Button",BS_AUTORADIOBUTTON,231,83,25,10
|
||||
CONTROL " 3P",IDC_RADIO_3P,"Button",BS_AUTORADIOBUTTON,261,83,24,10
|
||||
CONTROL " 4P",IDC_RADIO_4P,"Button",BS_AUTORADIOBUTTON,290,83,24,10
|
||||
CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTO3STATE,202,96,55,10
|
||||
PUSHBUTTON "<<",TASEDITOR_PREV_MARKER,201,332,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "Similar",TASEDITOR_FIND_BEST_SIMILAR_MARKER,224,332,34,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "More",TASEDITOR_FIND_NEXT_SIMILAR_MARKER,258,332,34,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">>",TASEDITOR_NEXT_MARKER,291,332,23,14,NOT WS_TABSTOP
|
||||
CONTROL "",IDC_JUMP_PLAYBACK_BUTTON,"Button",BS_OWNERDRAW,4,0,59,13
|
||||
EDITTEXT IDC_PLAYBACK_MARKER_EDIT,64,0,127,13,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
|
||||
RTEXT "Marker 0",IDC_PLAYBACK_MARKER,3,2,58,10,0,WS_EX_RIGHT
|
||||
CONTROL "",IDC_JUMP_SELECTION_BUTTON,"Button",BS_OWNERDRAW,4,333,59,13
|
||||
EDITTEXT IDC_SELECTION_MARKER_EDIT,64,333,127,13,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
|
||||
RTEXT "Marker 99999",IDC_SELECTION_MARKER,3,335,58,10,0,WS_EX_RIGHT
|
||||
CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,201,178,113,89
|
||||
CONTROL " Turbo seek",CHECK_TURBO_SEEK,"Button",BS_AUTOCHECKBOX,262,25,50,12
|
||||
LTEXT "Selection: 0 rows, 16 columns",IDC_TEXT_SELECTION,203,118,112,10
|
||||
LTEXT "Clipboard: 0 rows, 16 columns",IDC_TEXT_CLIPBOARD,202,128,114,10
|
||||
CONTROL " Recording",IDC_RECORDING,"Button",BS_AUTO3STATE,202,71,64,10
|
||||
PUSHBUTTON "Run function",TASEDITOR_RUN_MANUAL,201,150,54,14,WS_DISABLED | NOT WS_TABSTOP
|
||||
CONTROL "Auto function",IDC_RUN_AUTO,"Button",BS_AUTOCHECKBOX,260,152,55,10
|
||||
CONTROL " Use pattern",IDC_USEPATTERN,"Button",BS_AUTOCHECKBOX,261,96,53,10
|
||||
"Button",BS_AUTOCHECKBOX,203,48,105,12
|
||||
CONTROL "",IDC_BOOKMARKSLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | NOT WS_VISIBLE | WS_BORDER,202,178,113,89
|
||||
CONTROL "",IDC_HISTORYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER,202,282,113,42
|
||||
CONTROL " All",IDC_RADIO_ALL,"Button",BS_AUTORADIOBUTTON,291,71,24,10
|
||||
CONTROL " 1P",IDC_RADIO_1P,"Button",BS_AUTORADIOBUTTON,203,83,25,10
|
||||
CONTROL " 2P",IDC_RADIO_2P,"Button",BS_AUTORADIOBUTTON,232,83,25,10
|
||||
CONTROL " 3P",IDC_RADIO_3P,"Button",BS_AUTORADIOBUTTON,262,83,24,10
|
||||
CONTROL " 4P",IDC_RADIO_4P,"Button",BS_AUTORADIOBUTTON,291,83,24,10
|
||||
CONTROL " Superimpose",IDC_SUPERIMPOSE,"Button",BS_AUTO3STATE,203,96,55,10
|
||||
PUSHBUTTON "<<",TASEDITOR_PREV_MARKER,202,332,23,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "Similar",TASEDITOR_FIND_BEST_SIMILAR_MARKER,225,332,34,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON "More",TASEDITOR_FIND_NEXT_SIMILAR_MARKER,259,332,34,14,NOT WS_TABSTOP
|
||||
PUSHBUTTON ">>",TASEDITOR_NEXT_MARKER,292,332,23,14,NOT WS_TABSTOP
|
||||
CONTROL "",IDC_JUMP_PLAYBACK_BUTTON,"Button",BS_OWNERDRAW,5,0,59,13
|
||||
EDITTEXT IDC_PLAYBACK_MARKER_EDIT,65,0,127,13,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
|
||||
RTEXT "Marker 0",IDC_PLAYBACK_MARKER,4,2,58,10,0,WS_EX_RIGHT
|
||||
CONTROL "",IDC_JUMP_SELECTION_BUTTON,"Button",BS_OWNERDRAW,5,333,59,13
|
||||
EDITTEXT IDC_SELECTION_MARKER_EDIT,65,333,127,13,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
|
||||
RTEXT "Marker 99999",IDC_SELECTION_MARKER,4,335,58,10,0,WS_EX_RIGHT
|
||||
CONTROL "",IDC_BRANCHES_BITMAP,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_REALSIZEIMAGE | NOT WS_VISIBLE,202,178,113,89
|
||||
CONTROL " Turbo seek",CHECK_TURBO_SEEK,"Button",BS_AUTOCHECKBOX,263,25,50,12
|
||||
LTEXT "Selection: 0 rows, 16 columns",IDC_TEXT_SELECTION,204,118,112,10
|
||||
LTEXT "Clipboard: 0 rows, 16 columns",IDC_TEXT_CLIPBOARD,203,128,114,10
|
||||
CONTROL " Recording",IDC_RECORDING,"Button",BS_AUTO3STATE,203,71,64,10
|
||||
PUSHBUTTON "Run function",TASEDITOR_RUN_MANUAL,202,150,54,14,WS_DISABLED | NOT WS_TABSTOP
|
||||
CONTROL "Auto function",IDC_RUN_AUTO,"Button",BS_AUTOCHECKBOX,261,152,55,10
|
||||
CONTROL " Use pattern",IDC_USEPATTERN,"Button",BS_AUTOCHECKBOX,262,96,53,10
|
||||
END
|
||||
|
||||
IDD_TASEDITOR_ABOUT DIALOGEX 0, 0, 238, 78
|
||||
|
@ -1982,6 +1984,8 @@ BEGIN
|
|||
|
||||
"TASEDITOR", DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 323
|
||||
BOTTOMMARGIN, 351
|
||||
END
|
||||
|
||||
IDD_TASEDITOR_ABOUT, DIALOG
|
||||
|
|
|
@ -995,6 +995,8 @@
|
|||
#define ID_EDIT_DESELECT 40536
|
||||
#define ID_SELECTED_DESELECT 40537
|
||||
#define ID_CONFIG_DESELECTONDOUBLECLICK 40538
|
||||
#define ID_CONFIG_DRAWINPUTBYDRAGGING 40539
|
||||
#define ID_CONFIG_DOUBLECLICKONFRAME 40540
|
||||
#define IDC_DEBUGGER_ICONTRAY 55535
|
||||
#define MW_ValueLabel2 65423
|
||||
#define MW_ValueLabel1 65426
|
||||
|
@ -1004,7 +1006,7 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 206
|
||||
#define _APS_NEXT_COMMAND_VALUE 40539
|
||||
#define _APS_NEXT_COMMAND_VALUE 40541
|
||||
#define _APS_NEXT_CONTROL_VALUE 1281
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
@ -290,10 +290,10 @@ void UpdateTasEditor()
|
|||
|
||||
// update all modules that need to be updated every frame
|
||||
taseditor_window.update();
|
||||
greenzone.update();
|
||||
recorder.update();
|
||||
piano_roll.update();
|
||||
markers_manager.update();
|
||||
greenzone.update();
|
||||
playback.update();
|
||||
bookmarks.update();
|
||||
popup_display.update();
|
||||
|
|
|
@ -83,7 +83,9 @@ char modCaptions[MODTYPES_TOTAL][20] = {" Init Project",
|
|||
" Marker Unset",
|
||||
" Marker Pattern",
|
||||
" Marker Rename",
|
||||
" Marker Move",
|
||||
" Marker Drag",
|
||||
" Marker Swap",
|
||||
" Marker Shift",
|
||||
" LUA Marker Set",
|
||||
" LUA Marker Unset",
|
||||
" LUA Marker Rename",
|
||||
|
@ -445,10 +447,15 @@ void HISTORY::RegisterMarkersChange(int mod_type, int start, int end, const char
|
|||
_itoa(start, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
strcat(inp.description, framenum);
|
||||
if (end > start)
|
||||
if (end > start || mod_type == MODTYPE_MARKER_DRAG || mod_type == MODTYPE_MARKER_SWAP)
|
||||
{
|
||||
if (mod_type == MODTYPE_MARKER_DRAG)
|
||||
strcat(inp.description, "=>");
|
||||
else if (mod_type == MODTYPE_MARKER_SWAP)
|
||||
strcat(inp.description, "<=>");
|
||||
else
|
||||
strcat(inp.description, "-");
|
||||
_itoa(end, framenum, 10);
|
||||
strcat(inp.description, "-");
|
||||
strcat(inp.description, framenum);
|
||||
}
|
||||
// add comment if there is one specified
|
||||
|
@ -838,8 +845,13 @@ bool HISTORY::CursorOverHistoryList()
|
|||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
RECT wrect;
|
||||
GetWindowRect(hwndHistoryList, &wrect);
|
||||
ScreenToClient(hwndHistoryList, &p);
|
||||
if (p.x >= 0 && p.y >= 0 && p.x < window_items[HISTORYLIST_IN_WINDOWITEMS].width && p.y < (taseditor_config.wndheight + window_items[HISTORYLIST_IN_WINDOWITEMS].height - window_items[HISTORYLIST_IN_WINDOWITEMS].y))
|
||||
if (p.x >= 0
|
||||
&& p.y >= 0
|
||||
&& p.x < window_items[HISTORYLIST_IN_WINDOWITEMS].width
|
||||
&& p.y < (wrect.bottom - wrect.top))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -44,7 +44,9 @@ enum
|
|||
MODTYPE_MARKER_UNSET,
|
||||
MODTYPE_MARKER_PATTERN,
|
||||
MODTYPE_MARKER_RENAME,
|
||||
MODTYPE_MARKER_MOVE,
|
||||
MODTYPE_MARKER_DRAG,
|
||||
MODTYPE_MARKER_SWAP,
|
||||
MODTYPE_MARKER_SHIFT,
|
||||
MODTYPE_LUA_MARKER_SET,
|
||||
MODTYPE_LUA_MARKER_UNSET,
|
||||
MODTYPE_LUA_MARKER_RENAME,
|
||||
|
@ -54,7 +56,6 @@ enum
|
|||
};
|
||||
#define HISTORY_NORMAL_COLOR 0x000000
|
||||
|
||||
#define HISTORYLIST_IN_WINDOWITEMS 18
|
||||
#define WM_MOUSEWHEEL_RESENT WM_APP+123
|
||||
|
||||
#define HISTORY_ID_LEN 8
|
||||
|
|
|
@ -185,7 +185,7 @@ void MARKERS_MANAGER::ClearMarker(int frame)
|
|||
{
|
||||
// erase corresponding note
|
||||
markers.notes.erase(markers.notes.begin() + markers.markers_array[frame]);
|
||||
// erase marker
|
||||
// clear marker
|
||||
markers.markers_array[frame] = 0;
|
||||
// decrease following markers' ids
|
||||
int size = markers.markers_array.size();
|
||||
|
|
|
@ -10,7 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
Piano Roll - Piano Roll interface
|
||||
[Singleton]
|
||||
|
||||
* implements the working of Piano Roll List: creating, redrawing, scrolling, clicks
|
||||
* implements the working of Piano Roll List: creating, redrawing, scrolling, mouseover, clicks, drag
|
||||
* on demand: scrolls visible area of the List to any given item: to Playback Cursor, to Selection Cursor, to "undo pointer", to a Marker
|
||||
* saves and loads current position of vertical scrolling from a project file. On error: scrolls the List to the beginning
|
||||
* implements the working of Piano Roll List Header: creating, redrawing, animating, mouseover, clicks
|
||||
|
@ -18,6 +18,7 @@ Piano Roll - Piano Roll interface
|
|||
* regularly updates the size of the List according to current movie input, also updates lights in the List Header according to button presses data from Recorder and Alt key state
|
||||
* implements the working of mouse wheel: List scrolling, Playback cursor movement, Selection cursor movement
|
||||
* implements context menu on Right-click
|
||||
* updates mouse cursor icon depending on item under cursor
|
||||
* stores resources: save id, ids of columns, widths of columns, tables of colors, gradient of Hot Changes, gradient of Header flashings, timings of flashes, all fonts used in TAS Editor, images
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
|
@ -43,21 +44,48 @@ extern HISTORY history;
|
|||
extern MARKERS_MANAGER markers_manager;
|
||||
extern SELECTION selection;
|
||||
|
||||
extern Window_items_struct window_items[];
|
||||
extern int GetInputType(MovieData& md);
|
||||
|
||||
LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
WNDPROC hwndList_oldWndProc = 0, hwndHeader_oldWndproc = 0;
|
||||
|
||||
LRESULT APIENTRY MarkerDragBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// resources
|
||||
char piano_roll_save_id[PIANO_ROLL_ID_LEN] = "PIANO_ROLL";
|
||||
char piano_roll_skipsave_id[PIANO_ROLL_ID_LEN] = "PIANO_ROLX";
|
||||
COLORREF hot_changes_colors[16] = { 0x0, 0x5c4c44, 0x854604, 0xab2500, 0xc20006, 0xd6006f, 0xd40091, 0xba00a4, 0x9500ba, 0x7a00cc, 0x5800d4, 0x0045e2, 0x0063ea, 0x0079f4, 0x0092fa, 0x00aaff };
|
||||
//COLORREF hot_changes_colors[16] = { 0x0, 0x661212, 0x842B4E, 0x652C73, 0x48247D, 0x383596, 0x2947AE, 0x1E53C1, 0x135DD2, 0x116EDA, 0x107EE3, 0x0F8EEB, 0x209FF4, 0x3DB1FD, 0x51C2FF, 0x4DCDFF };
|
||||
COLORREF header_lights_colors[11] = { 0x0, 0x007313, 0x009100, 0x1daf00, 0x42c700, 0x65d900, 0x91e500, 0xb0f000, 0xdaf700, 0xf0fc7c, 0xfcffba };
|
||||
char markerDragBoxClassName[] = "MarkerDragBox";
|
||||
|
||||
PIANO_ROLL::PIANO_ROLL()
|
||||
{
|
||||
hwndMarkerDragBox = 0;
|
||||
// register MARKER_DRAG_BOX window class
|
||||
wincl.hInstance = fceu_hInstance;
|
||||
wincl.lpszClassName = markerDragBoxClassName;
|
||||
wincl.lpfnWndProc = MarkerDragBoxWndProc;
|
||||
wincl.style = CS_DBLCLKS;
|
||||
wincl.cbSize = sizeof(WNDCLASSEX);
|
||||
wincl.hIcon = 0;
|
||||
wincl.hIconSm = 0;
|
||||
wincl.hCursor = 0;
|
||||
wincl.lpszMenuName = 0;
|
||||
wincl.cbClsExtra = 0;
|
||||
wincl.cbWndExtra = 0;
|
||||
wincl.hbrBackground = 0;
|
||||
if(!RegisterClassEx(&wincl))
|
||||
FCEU_printf("Error registering MARKER_DRAG_BOX window class\n");
|
||||
|
||||
// create blendfunction
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.BlendFlags = 0;
|
||||
blend.AlphaFormat = 0;
|
||||
blend.SourceConstantAlpha = 255;
|
||||
|
||||
}
|
||||
|
||||
void PIANO_ROLL::init()
|
||||
|
@ -97,6 +125,8 @@ void PIANO_ROLL::init()
|
|||
"Arial"); /*font name*/
|
||||
|
||||
bg_brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
|
||||
marker_drag_box_brush = CreateSolidBrush(MARKED_FRAMENUM_COLOR);
|
||||
marker_drag_box_brush_bind = CreateSolidBrush(BINDMARKED_FRAMENUM_COLOR);
|
||||
|
||||
hwndList = GetDlgItem(taseditor_window.hwndTasEditor, IDC_LIST1);
|
||||
// prepare the main listview
|
||||
|
@ -183,6 +213,20 @@ void PIANO_ROLL::init()
|
|||
lvc.mask = LVCF_WIDTH;
|
||||
lvc.cx = COLUMN_ICONS_WIDTH;
|
||||
ListView_InsertColumn(hwndList, 0, &lvc);
|
||||
// find rows top/height (for mouseover hittest calculations)
|
||||
ListView_SetItemCountEx(hwndList, 1, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);
|
||||
RECT temp_rect;
|
||||
if (ListView_GetSubItemRect(hwndList, 0, 0, LVIR_BOUNDS, &temp_rect) && temp_rect.bottom != temp_rect.top)
|
||||
{
|
||||
list_row_top = temp_rect.top;
|
||||
list_row_height = temp_rect.bottom - temp_rect.top;
|
||||
} else
|
||||
{
|
||||
// couldn't get rect, set default values
|
||||
list_row_top = 20;
|
||||
list_row_height = 14;
|
||||
}
|
||||
ListView_SetItemCountEx(hwndList, 0, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);
|
||||
|
||||
hrmenu = LoadMenu(fceu_hInstance,"TASEDITORCONTEXTMENUS");
|
||||
header_colors.resize(TOTAL_COLUMNS);
|
||||
|
@ -190,7 +234,7 @@ void PIANO_ROLL::init()
|
|||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwndHeader;
|
||||
|
||||
drag_mode = DRAG_MODE_NONE;
|
||||
}
|
||||
void PIANO_ROLL::free()
|
||||
{
|
||||
|
@ -224,6 +268,21 @@ void PIANO_ROLL::free()
|
|||
DeleteObject(bg_brush);
|
||||
bg_brush = 0;
|
||||
}
|
||||
if (marker_drag_box_brush)
|
||||
{
|
||||
DeleteObject(marker_drag_box_brush);
|
||||
marker_drag_box_brush = 0;
|
||||
}
|
||||
if (marker_drag_box_brush_bind)
|
||||
{
|
||||
DeleteObject(marker_drag_box_brush_bind);
|
||||
marker_drag_box_brush_bind = 0;
|
||||
}
|
||||
if (bg_brush)
|
||||
{
|
||||
DeleteObject(bg_brush);
|
||||
bg_brush = 0;
|
||||
}
|
||||
if (himglist)
|
||||
{
|
||||
ImageList_Destroy(himglist);
|
||||
|
@ -233,6 +292,7 @@ void PIANO_ROLL::free()
|
|||
}
|
||||
void PIANO_ROLL::reset()
|
||||
{
|
||||
must_check_item_under_mouse = true;
|
||||
vk_shift_release_time = vk_control_release_time = 0;
|
||||
next_header_update_time = header_item_under_mouse = 0;
|
||||
// delete all columns except 0th
|
||||
|
@ -274,7 +334,136 @@ void PIANO_ROLL::update()
|
|||
if(currLVItemCount != movie_size)
|
||||
ListView_SetItemCountEx(hwndList, movie_size, LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);
|
||||
|
||||
// once per 40 milliseconds update colors alpha
|
||||
// update dragging
|
||||
if (drag_mode != DRAG_MODE_NONE)
|
||||
{
|
||||
// check if user released left button
|
||||
if (GetAsyncKeyState(GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON) >= 0)
|
||||
FinishDrag();
|
||||
}
|
||||
// also scroll Piano Roll if user is dragging cursor outside
|
||||
if (drag_mode != DRAG_MODE_NONE)
|
||||
{
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
int scroll_dx = 0, scroll_dy = 0;
|
||||
RECT wrect;
|
||||
GetWindowRect(hwndList, &wrect);
|
||||
ScreenToClient(hwndList, &p);
|
||||
if (p.x < 0)
|
||||
scroll_dx = p.x;
|
||||
else if (p.x > (wrect.right - wrect.left))
|
||||
scroll_dx = p.x - (wrect.right - wrect.left);
|
||||
if (p.y < 0)
|
||||
scroll_dy = p.y;
|
||||
else if (p.y > (wrect.bottom - wrect.top))
|
||||
scroll_dy = p.y - (wrect.bottom - wrect.top);
|
||||
if (scroll_dx || scroll_dy)
|
||||
ListView_Scroll(hwndList, scroll_dx, scroll_dy);
|
||||
}
|
||||
}
|
||||
// perform drag
|
||||
switch (drag_mode)
|
||||
{
|
||||
case DRAG_MODE_PLAYBACK:
|
||||
{
|
||||
if (!playback.pause_frame)
|
||||
DragPlaybackCursor();
|
||||
break;
|
||||
}
|
||||
case DRAG_MODE_MARKER:
|
||||
{
|
||||
// if suddenly source frame lost its Marker, abort drag
|
||||
if (!markers_manager.GetMarker(marker_drag_framenum))
|
||||
{
|
||||
if (hwndMarkerDragBox)
|
||||
{
|
||||
DestroyWindow(hwndMarkerDragBox);
|
||||
hwndMarkerDragBox = 0;
|
||||
}
|
||||
drag_mode = DRAG_MODE_NONE;
|
||||
break;
|
||||
}
|
||||
// when dragging, always show semi-transparent yellow rectangle under mouse
|
||||
POINT p = {0, 0};
|
||||
GetCursorPos(&p);
|
||||
int window_x = p.x - marker_drag_box_dx;
|
||||
int window_y = p.y - marker_drag_box_dy;
|
||||
if (!hwndMarkerDragBox)
|
||||
{
|
||||
hwndMarkerDragBox = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, markerDragBoxClassName, markerDragBoxClassName, WS_POPUP, window_x, window_y, COLUMN_FRAMENUM_WIDTH, list_row_height, taseditor_window.hwndTasEditor, NULL, fceu_hInstance, NULL);
|
||||
ShowWindow(hwndMarkerDragBox, SW_SHOWNA);
|
||||
SetLayeredWindowAttributes(hwndMarkerDragBox, 0, MARKER_DRAG_BOX_ALPHA, LWA_ALPHA);
|
||||
UpdateLayeredWindow(hwndMarkerDragBox, 0, 0, 0, 0, 0, 0, &blend, ULW_ALPHA);
|
||||
} else
|
||||
{
|
||||
SetWindowPos(hwndMarkerDragBox, 0, window_x, window_y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
}
|
||||
// force dragging cursor icon
|
||||
SetCursor(LoadCursor(0, IDC_ARROW));
|
||||
must_check_item_under_mouse = false;
|
||||
break;
|
||||
}
|
||||
case DRAG_MODE_SET:
|
||||
case DRAG_MODE_UNSET:
|
||||
{
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
RECT wrect;
|
||||
GetWindowRect(hwndList, &wrect);
|
||||
ScreenToClient(hwndList, &p);
|
||||
int drawing_current_x = p.x + GetScrollPos(hwndList, SB_HORZ);
|
||||
int drawing_current_y = p.y + GetScrollPos(hwndList, SB_VERT) * list_row_height;
|
||||
// draw (or erase) line from [drawing_current_x, drawing_current_y] to (drawing_last_x, drawing_last_y)
|
||||
int total_dx = drawing_last_x - drawing_current_x, total_dy = drawing_last_y - drawing_current_y;
|
||||
double total_len = sqrt((double)(total_dx * total_dx + total_dy * total_dy));
|
||||
LVHITTESTINFO info;
|
||||
int row_index, column_index, joy, bit;
|
||||
int min_row_index = currMovieData.getNumRecords(), max_row_index = -1;
|
||||
bool changes_made = false;
|
||||
for (double len = 0; len < total_len; len += DRAWING_MIN_LINE_LEN)
|
||||
{
|
||||
// perform hit test
|
||||
info.pt.x = p.x + (len / total_len) * total_dx;
|
||||
info.pt.y = p.y + (len / total_len) * total_dy;
|
||||
ListView_SubItemHitTest(hwndList, &info);
|
||||
row_index = info.iItem;
|
||||
column_index = info.iSubItem;
|
||||
if (row_index >= 0 && column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
|
||||
{
|
||||
joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
|
||||
bit = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
|
||||
if (drag_mode == DRAG_MODE_SET && !currMovieData.records[row_index].checkBit(joy, bit))
|
||||
{
|
||||
currMovieData.records[row_index].setBit(joy, bit);
|
||||
changes_made = true;
|
||||
if (min_row_index > row_index) min_row_index = row_index;
|
||||
if (max_row_index < row_index) max_row_index = row_index;
|
||||
} else if (drag_mode == DRAG_MODE_UNSET && currMovieData.records[row_index].checkBit(joy, bit))
|
||||
{
|
||||
currMovieData.records[row_index].clearBit(joy, bit);
|
||||
changes_made = true;
|
||||
if (min_row_index > row_index) min_row_index = row_index;
|
||||
if (max_row_index < row_index) max_row_index = row_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changes_made)
|
||||
{
|
||||
if (drag_mode == DRAG_MODE_SET)
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, min_row_index, max_row_index));
|
||||
else
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, min_row_index, max_row_index));
|
||||
}
|
||||
drawing_last_x = drawing_current_x;
|
||||
drawing_last_y = drawing_current_y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// once per 40 milliseconds update colors alpha in the Header
|
||||
if (clock() > next_header_update_time)
|
||||
{
|
||||
next_header_update_time = clock() + HEADER_LIGHT_UPDATE_TICK;
|
||||
|
@ -283,7 +472,7 @@ void PIANO_ROLL::update()
|
|||
// 1 - update Frame# columns' heads
|
||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
||||
light_value = HEADER_LIGHT_HOLD;
|
||||
else if (header_item_under_mouse == COLUMN_FRAMENUM || header_item_under_mouse == COLUMN_FRAMENUM2)
|
||||
else if (drag_mode == DRAG_MODE_NONE && (header_item_under_mouse == COLUMN_FRAMENUM || header_item_under_mouse == COLUMN_FRAMENUM2))
|
||||
light_value = (selection.GetCurrentSelectionSize() > 0) ? HEADER_LIGHT_MOUSEOVER_SEL : HEADER_LIGHT_MOUSEOVER;
|
||||
if (header_colors[COLUMN_FRAMENUM] < light_value)
|
||||
{
|
||||
|
@ -303,7 +492,7 @@ void PIANO_ROLL::update()
|
|||
light_value = 0;
|
||||
if (recorder.current_joy[(i - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS] & (1 << ((i - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS)))
|
||||
light_value = HEADER_LIGHT_HOLD;
|
||||
else if (header_item_under_mouse == i)
|
||||
else if (drag_mode == DRAG_MODE_NONE && header_item_under_mouse == i)
|
||||
light_value = (selection.GetCurrentSelectionSize() > 0) ? HEADER_LIGHT_MOUSEOVER_SEL : HEADER_LIGHT_MOUSEOVER;
|
||||
if (header_colors[i] < light_value)
|
||||
{
|
||||
|
@ -319,6 +508,56 @@ void PIANO_ROLL::update()
|
|||
if (changes_made)
|
||||
RedrawHeader();
|
||||
}
|
||||
|
||||
// change mouse cursor depending on what it points at
|
||||
if (must_check_item_under_mouse)
|
||||
{
|
||||
LPCSTR cursor_icon = IDC_ARROW;
|
||||
switch (drag_mode)
|
||||
{
|
||||
case DRAG_MODE_NONE:
|
||||
{
|
||||
// normal mouseover
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
RECT wrect;
|
||||
GetWindowRect(hwndList, &wrect);
|
||||
ScreenToClient(hwndList, &p);
|
||||
if (p.x >= 0 && p.y >= 0 && p.x < (wrect.right - wrect.left) && p.y < (wrect.bottom - wrect.top))
|
||||
{
|
||||
// perform hit test
|
||||
LVHITTESTINFO info;
|
||||
info.pt.x = p.x;
|
||||
info.pt.y = p.y;
|
||||
ListView_SubItemHitTest(hwndList, &info);
|
||||
int row_index = info.iItem;
|
||||
int column_index = info.iSubItem;
|
||||
if (row_index >= 0
|
||||
&& (column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
|
||||
&& markers_manager.GetMarker(row_index))
|
||||
cursor_icon = IDC_SIZEALL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRAG_MODE_PLAYBACK:
|
||||
{
|
||||
// dragging Playback cursor - show either normal arrow or arrow+wait
|
||||
if (playback.pause_frame)
|
||||
cursor_icon = IDC_APPSTARTING;
|
||||
break;
|
||||
}
|
||||
case DRAG_MODE_MARKER:
|
||||
case DRAG_MODE_OBSERVE:
|
||||
case DRAG_MODE_SET:
|
||||
case DRAG_MODE_UNSET:
|
||||
// show normal arrow
|
||||
break;
|
||||
}
|
||||
SetCursor(LoadCursor(0, cursor_icon));
|
||||
must_check_item_under_mouse = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PIANO_ROLL::save(EMUFILE *os, bool really_save)
|
||||
|
@ -370,6 +609,7 @@ error:
|
|||
void PIANO_ROLL::RedrawList()
|
||||
{
|
||||
InvalidateRect(hwndList, 0, FALSE);
|
||||
must_check_item_under_mouse = true;
|
||||
}
|
||||
void PIANO_ROLL::RedrawRow(int index)
|
||||
{
|
||||
|
@ -483,6 +723,111 @@ void PIANO_ROLL::SetHeaderColumnLight(int column, int level)
|
|||
}
|
||||
}
|
||||
|
||||
void PIANO_ROLL::DragPlaybackCursor()
|
||||
{
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
ScreenToClient(hwndList, &p);
|
||||
// perform hit test
|
||||
LVHITTESTINFO info;
|
||||
info.pt.x = p.x;
|
||||
info.pt.y = p.y;
|
||||
ListView_SubItemHitTest(hwndList, &info);
|
||||
int row_index = info.iItem;
|
||||
if (row_index < 0)
|
||||
row_index = ListView_GetTopIndex(hwndList) + (p.y - list_row_top) / list_row_height;
|
||||
// send Playback there
|
||||
if (currFrameCounter != row_index)
|
||||
{
|
||||
int lastCursor = currFrameCounter;
|
||||
playback.jump(row_index);
|
||||
if (lastCursor != currFrameCounter)
|
||||
{
|
||||
// redraw row where Playback cursor was (in case there's two or more drags before playback.update())
|
||||
RedrawRow(lastCursor);
|
||||
bookmarks.RedrawChangedBookmarks(lastCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PIANO_ROLL::FinishDrag()
|
||||
{
|
||||
switch (drag_mode)
|
||||
{
|
||||
case DRAG_MODE_MARKER:
|
||||
{
|
||||
// place Marker here
|
||||
if (markers_manager.GetMarker(marker_drag_framenum))
|
||||
{
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
ScreenToClient(hwndList, &p);
|
||||
// perform hit test
|
||||
LVHITTESTINFO info;
|
||||
info.pt.x = p.x;
|
||||
info.pt.y = p.y;
|
||||
ListView_SubItemHitTest(hwndList, &info);
|
||||
int row_index = info.iItem;
|
||||
int column_index = info.iSubItem;
|
||||
if (row_index >= 0 && row_index != marker_drag_framenum && (column_index <= COLUMN_FRAMENUM || column_index >= COLUMN_FRAMENUM2))
|
||||
{
|
||||
if (markers_manager.GetMarker(row_index))
|
||||
{
|
||||
int dragged_marker_id = markers_manager.GetMarker(marker_drag_framenum);
|
||||
int destination_marker_id = markers_manager.GetMarker(row_index);
|
||||
// swap Notes of these Markers
|
||||
char dragged_marker_note[MAX_NOTE_LEN];
|
||||
strcpy(dragged_marker_note, markers_manager.GetNote(dragged_marker_id).c_str());
|
||||
if (strcmp(markers_manager.GetNote(destination_marker_id).c_str(), dragged_marker_note))
|
||||
{
|
||||
// notes are different, swap them
|
||||
markers_manager.SetNote(dragged_marker_id, markers_manager.GetNote(destination_marker_id).c_str());
|
||||
markers_manager.SetNote(destination_marker_id, dragged_marker_note);
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SWAP, marker_drag_framenum, row_index);
|
||||
selection.must_find_current_marker = playback.must_find_current_marker = true;
|
||||
SetHeaderColumnLight(COLUMN_FRAMENUM, HEADER_LIGHT_MAX);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// move Marker
|
||||
int new_marker_id = markers_manager.SetMarker(row_index);
|
||||
if (new_marker_id)
|
||||
{
|
||||
markers_manager.SetNote(new_marker_id, markers_manager.GetNote(markers_manager.GetMarker(marker_drag_framenum)).c_str());
|
||||
// and delete it from old frame
|
||||
markers_manager.ClearMarker(marker_drag_framenum);
|
||||
RedrawRow(marker_drag_framenum);
|
||||
RedrawRow(row_index);
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_DRAG, marker_drag_framenum, row_index, markers_manager.GetNote(markers_manager.GetMarker(row_index)).c_str());
|
||||
selection.must_find_current_marker = playback.must_find_current_marker = true;
|
||||
SetHeaderColumnLight(COLUMN_FRAMENUM, HEADER_LIGHT_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hwndMarkerDragBox)
|
||||
{
|
||||
DestroyWindow(hwndMarkerDragBox);
|
||||
hwndMarkerDragBox = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
drag_mode = DRAG_MODE_NONE;
|
||||
must_check_item_under_mouse = true;
|
||||
}
|
||||
|
||||
void PIANO_ROLL::AcceleratorDispatched()
|
||||
{
|
||||
// hack for tapping Ctrl twice - if first was accelerator, then it won't count as first tap
|
||||
vk_control_release_time = -1;
|
||||
}
|
||||
|
||||
void PIANO_ROLL::GetDispInfo(NMLVDISPINFO* nmlvDispInfo)
|
||||
{
|
||||
LVITEM& item = nmlvDispInfo->item;
|
||||
|
@ -1063,6 +1408,18 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_CHAR:
|
||||
case WM_KILLFOCUS:
|
||||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
if (LOWORD(lParam) == HTCLIENT)
|
||||
{
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
return 0;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
if (((LPNMHDR)lParam)->hwndFrom == piano_roll.hwndHeader)
|
||||
|
@ -1082,9 +1439,18 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_KEYUP:
|
||||
{
|
||||
if (wParam == VK_SHIFT)
|
||||
piano_roll.vk_shift_release_time = clock();
|
||||
else if (wParam == VK_CONTROL)
|
||||
piano_roll.vk_control_release_time = clock();
|
||||
{
|
||||
if (piano_roll.vk_shift_release_time >= 0)
|
||||
piano_roll.vk_shift_release_time = clock();
|
||||
else // this was accelerator
|
||||
piano_roll.vk_shift_release_time = 0;
|
||||
} else if (wParam == VK_CONTROL)
|
||||
{
|
||||
if (piano_roll.vk_control_release_time >= 0)
|
||||
piano_roll.vk_control_release_time = clock();
|
||||
else // this was accelerator
|
||||
piano_roll.vk_control_release_time = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
|
@ -1092,19 +1458,21 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if (wParam == VK_SHIFT)
|
||||
{
|
||||
// double-tap of Shift key
|
||||
if (piano_roll.vk_shift_release_time + GetDoubleClickTime() > clock())
|
||||
if ((int)(piano_roll.vk_shift_release_time + GetDoubleClickTime()) > clock())
|
||||
piano_roll.FollowPlayback();
|
||||
} else if (wParam == VK_CONTROL)
|
||||
{
|
||||
// double-tap of Ctrl key
|
||||
if (piano_roll.vk_control_release_time + GetDoubleClickTime() > clock())
|
||||
if ((int)(piano_roll.vk_control_release_time + GetDoubleClickTime()) > clock())
|
||||
piano_roll.FollowSelection();
|
||||
}
|
||||
// only allow 8 keys
|
||||
if (taseditor_config.keyboard_for_piano_roll && (wParam == VK_LEFT || wParam == VK_UP || wParam == VK_RIGHT || wParam == VK_DOWN || wParam == VK_END || wParam == VK_HOME || wParam == VK_PRIOR || wParam == VK_NEXT))
|
||||
{
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
break;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_TIMER:
|
||||
// disable timer of entering edit mode (there's no edit mode anyway)
|
||||
|
@ -1118,25 +1486,32 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
LVHITTESTINFO info;
|
||||
info.pt.x = GET_X_LPARAM(lParam);
|
||||
info.pt.y = GET_Y_LPARAM(lParam);
|
||||
ListView_SubItemHitTest(hWnd, (LPARAM)&info);
|
||||
ListView_SubItemHitTest(hWnd, &info);
|
||||
int row_index = info.iItem;
|
||||
int column_index = info.iSubItem;
|
||||
if(row_index >= 0)
|
||||
if(column_index == COLUMN_ICONS)
|
||||
{
|
||||
if(column_index == COLUMN_ICONS)
|
||||
// click on the "icons" column
|
||||
piano_roll.DragPlaybackCursor();
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
piano_roll.drag_mode = DRAG_MODE_PLAYBACK;
|
||||
} else if(column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
|
||||
{
|
||||
// clicked on the "Frame#" column
|
||||
if (msg == WM_LBUTTONDBLCLK && !alt_pressed)
|
||||
{
|
||||
// click on the "icons" column - jump to the frame
|
||||
playback.jump(row_index);
|
||||
} else if(column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
|
||||
{
|
||||
// clicked on the "Frame#" column
|
||||
if (msg == WM_LBUTTONDBLCLK && !alt_pressed)
|
||||
// doubleclick - jump to the frame
|
||||
if (taseditor_config.deselect_on_doubleclick)
|
||||
selection.ClearSelection();
|
||||
if (taseditor_config.doubleclick_affects_playback)
|
||||
{
|
||||
// doubleclick - jump to the frame
|
||||
if (taseditor_config.deselect_on_doubleclick)
|
||||
selection.ClearSelection();
|
||||
playback.jump(row_index);
|
||||
} else
|
||||
piano_roll.DragPlaybackCursor();
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
piano_roll.drag_mode = DRAG_MODE_PLAYBACK;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (row_index >= 0)
|
||||
{
|
||||
// set marker if clicked with Alt
|
||||
if (alt_pressed)
|
||||
|
@ -1148,14 +1523,39 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
else
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_UNSET, row_index);
|
||||
piano_roll.RedrawRow(row_index);
|
||||
} else if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
{
|
||||
// check if user clicked on a Marker
|
||||
if (markers_manager.GetMarker(row_index))
|
||||
{
|
||||
// start dragging the Marker
|
||||
RECT temp_rect;
|
||||
if (ListView_GetSubItemRect(piano_roll.hwndList, row_index, column_index, LVIR_BOUNDS, &temp_rect))
|
||||
{
|
||||
piano_roll.marker_drag_box_dx = GET_X_LPARAM(lParam) - temp_rect.left;
|
||||
piano_roll.marker_drag_box_dy = GET_Y_LPARAM(lParam) - temp_rect.top;
|
||||
} else
|
||||
{
|
||||
piano_roll.marker_drag_box_dx = 0;
|
||||
piano_roll.marker_drag_box_dy = 0;
|
||||
}
|
||||
piano_roll.drag_mode = DRAG_MODE_MARKER;
|
||||
piano_roll.marker_drag_framenum = row_index;
|
||||
} else
|
||||
{
|
||||
piano_roll.drag_mode = DRAG_MODE_OBSERVE;
|
||||
}
|
||||
}
|
||||
// also select the row by calling hwndList_oldWndProc
|
||||
PostMessage(hWnd, WM_LBUTTONUP, 0, 0); // ensure that oldWndProc will exit its modal message loop immediately
|
||||
CallWindowProc(hwndList_oldWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
} else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
|
||||
}
|
||||
} else if(column_index >= COLUMN_JOYPAD1_A && column_index <= COLUMN_JOYPAD4_R)
|
||||
{
|
||||
// clicked on input
|
||||
if (row_index >= 0)
|
||||
{
|
||||
// clicked on input
|
||||
// first call old wndproc to set selection on the row
|
||||
if (alt_pressed)
|
||||
wParam |= MK_SHIFT; // Alt should select region, just like Shift
|
||||
|
@ -1170,6 +1570,25 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
} else
|
||||
{
|
||||
piano_roll.ToggleJoypadBit(column_index, row_index, GET_KEYSTATE_WPARAM(wParam));
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
{
|
||||
if (taseditor_config.draw_input)
|
||||
{
|
||||
// if clicked on empty cell - start drawing, else start erasing
|
||||
int joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
|
||||
int bit = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
|
||||
if (currMovieData.records[row_index].checkBit(joy, bit))
|
||||
piano_roll.drag_mode = DRAG_MODE_SET;
|
||||
else
|
||||
piano_roll.drag_mode = DRAG_MODE_UNSET;
|
||||
piano_roll.drawing_last_x = GET_X_LPARAM(lParam) + GetScrollPos(piano_roll.hwndList, SB_HORZ);
|
||||
piano_roll.drawing_last_y = GET_Y_LPARAM(lParam) + GetScrollPos(piano_roll.hwndList, SB_VERT) * piano_roll.list_row_height;
|
||||
} else
|
||||
{
|
||||
piano_roll.drag_mode = DRAG_MODE_OBSERVE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1195,7 +1614,6 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
playback.ForwardFull(-zDelta / 120);
|
||||
else if (zDelta > 0)
|
||||
playback.RewindFull(zDelta / 120);
|
||||
return 0;
|
||||
} else if (fwKeys & MK_CONTROL)
|
||||
{
|
||||
// Ctrl + wheel = Selection rewind full(speed)/forward full(speed)
|
||||
|
@ -1203,7 +1621,6 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
selection.JumpNextMarker(-zDelta / 120);
|
||||
else if (zDelta > 0)
|
||||
selection.JumpPrevMarker(zDelta / 120);
|
||||
return 0;
|
||||
} else if (alt_pressed || fwKeys & MK_RBUTTON)
|
||||
{
|
||||
// Right button + wheel = Alt + wheel = rewind/forward
|
||||
|
@ -1220,12 +1637,15 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
piano_roll.RedrawRow(lastCursor);
|
||||
bookmarks.RedrawChangedBookmarks(lastCursor);
|
||||
}
|
||||
return 0;
|
||||
} else if (history.CursorOverHistoryList())
|
||||
{
|
||||
return SendMessage(history.hwndHistoryList, WM_MOUSEWHEEL_RESENT, wParam, lParam);
|
||||
} else
|
||||
{
|
||||
// normal scrolling
|
||||
CallWindowProc(hwndList_oldWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
|
@ -1238,17 +1658,78 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
LVHITTESTINFO info;
|
||||
info.pt.x = GET_X_LPARAM(lParam);
|
||||
info.pt.y = GET_Y_LPARAM(lParam);
|
||||
ListView_SubItemHitTest(hWnd, (LPARAM)&info);
|
||||
ListView_SubItemHitTest(hWnd, &info);
|
||||
// show context menu if user right-clicked on Frame#
|
||||
if(info.iSubItem <= COLUMN_FRAMENUM || info.iSubItem >= COLUMN_FRAMENUM2)
|
||||
piano_roll.RightClick(info);
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEACTIVATE:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
{
|
||||
if (wParam == HTBORDER)
|
||||
{
|
||||
POINT p;
|
||||
p.x = GET_X_LPARAM(lParam);
|
||||
p.y = GET_Y_LPARAM(lParam);
|
||||
ScreenToClient(piano_roll.hwndList, &p);
|
||||
if (p.x <= 0)
|
||||
{
|
||||
// user clicked on left border of the Piano Roll
|
||||
// consider this as a "misclick" on Piano Roll's first column
|
||||
piano_roll.DragPlaybackCursor();
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
piano_roll.drag_mode = DRAG_MODE_PLAYBACK;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEACTIVATE:
|
||||
{
|
||||
if (GetFocus() != hWnd)
|
||||
SetFocus(hWnd);
|
||||
break;
|
||||
}
|
||||
case LVM_ENSUREVISIBLE:
|
||||
{
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return CallWindowProc(hwndList_oldWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
// ----------------------------------------------------------------------------------------
|
||||
LRESULT APIENTRY MarkerDragBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
extern PIANO_ROLL piano_roll;
|
||||
switch(message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
// create static bitmap placeholder
|
||||
char framenum[DIGITS_IN_FRAMENUM + 1];
|
||||
U32ToDecStr(framenum, piano_roll.marker_drag_framenum, DIGITS_IN_FRAMENUM);
|
||||
piano_roll.hwndMarkerDragBoxText = CreateWindow(WC_STATIC, framenum, SS_CENTER| WS_CHILD | WS_VISIBLE, 0, 0, COLUMN_FRAMENUM_WIDTH, piano_roll.list_row_height, hwnd, NULL, NULL, NULL);
|
||||
SendMessage(piano_roll.hwndMarkerDragBoxText, WM_SETFONT, (WPARAM)piano_roll.hMainListSelectFont, 0);
|
||||
return 0;
|
||||
}
|
||||
case WM_CTLCOLORSTATIC:
|
||||
{
|
||||
// change color of static text fields
|
||||
if ((HWND)lParam == piano_roll.hwndMarkerDragBoxText)
|
||||
{
|
||||
SetTextColor((HDC)wParam, NORMAL_TEXT_COLOR);
|
||||
SetBkMode((HDC)wParam, TRANSPARENT);
|
||||
if (taseditor_config.bind_markers)
|
||||
return (LRESULT)(piano_roll.marker_drag_box_brush_bind);
|
||||
else
|
||||
return (LRESULT)(piano_roll.marker_drag_box_brush);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#define BOOST_WHEN_BOTH_RIGHTBUTTON_AND_ALT_PRESSED 4
|
||||
|
||||
#define MARKER_DRAG_BOX_ALPHA 175
|
||||
#define DRAWING_MIN_LINE_LEN 14 // = min(list_row_width, list_row_height) in pixels
|
||||
|
||||
enum
|
||||
{
|
||||
COLUMN_ICONS,
|
||||
|
@ -60,6 +63,16 @@ enum
|
|||
TOTAL_COLUMNS
|
||||
};
|
||||
|
||||
enum DRAG_MODES
|
||||
{
|
||||
DRAG_MODE_NONE,
|
||||
DRAG_MODE_OBSERVE,
|
||||
DRAG_MODE_PLAYBACK,
|
||||
DRAG_MODE_MARKER,
|
||||
DRAG_MODE_SET,
|
||||
DRAG_MODE_UNSET,
|
||||
};
|
||||
|
||||
// when there's too many button columns, there's need for 2nd Frame# column at the end
|
||||
#define NUM_COLUMNS_NEED_2ND_FRAMENUM COLUMN_JOYPAD4_R
|
||||
|
||||
|
@ -139,6 +152,11 @@ public:
|
|||
|
||||
void SetHeaderColumnLight(int column, int level);
|
||||
|
||||
void DragPlaybackCursor();
|
||||
void FinishDrag();
|
||||
|
||||
void AcceleratorDispatched();
|
||||
|
||||
void GetDispInfo(NMLVDISPINFO* nmlvDispInfo);
|
||||
LONG CustomDraw(NMLVCUSTOMDRAW* msg);
|
||||
LONG HeaderCustomDraw(NMLVCUSTOMDRAW* msg);
|
||||
|
@ -158,13 +176,22 @@ public:
|
|||
HWND hwndList, hwndHeader;
|
||||
TRACKMOUSEEVENT tme;
|
||||
|
||||
unsigned int drag_mode;
|
||||
int list_row_top, list_row_height;
|
||||
int marker_drag_box_dx, marker_drag_box_dy;
|
||||
int marker_drag_framenum;
|
||||
int drawing_last_x, drawing_last_y;
|
||||
|
||||
bool must_check_item_under_mouse;
|
||||
|
||||
int vk_shift_release_time;
|
||||
int vk_control_release_time;
|
||||
|
||||
HWND hwndMarkerDragBox, hwndMarkerDragBoxText;
|
||||
// GDI stuff
|
||||
HIMAGELIST himglist;
|
||||
HFONT hMainListFont, hMainListSelectFont, hMarkersFont, hMarkersEditFont, hTaseditorAboutFont;
|
||||
HBRUSH bg_brush;
|
||||
HBRUSH bg_brush, marker_drag_box_brush, marker_drag_box_brush_bind;
|
||||
|
||||
private:
|
||||
void CenterListAt(int frame);
|
||||
|
@ -175,4 +202,7 @@ private:
|
|||
|
||||
HMENU hrmenu;
|
||||
|
||||
WNDCLASSEX wincl;
|
||||
BLENDFUNCTION blend;
|
||||
|
||||
};
|
||||
|
|
|
@ -68,7 +68,7 @@ void PLAYBACK::reset()
|
|||
{
|
||||
must_find_current_marker = true;
|
||||
shown_marker = 0;
|
||||
lastCursor = -1;
|
||||
lastCursor = currFrameCounter;
|
||||
lost_position_frame = pause_frame = old_pauseframe = 0;
|
||||
old_show_pauseframe = show_pauseframe = false;
|
||||
old_rewind_button_state = rewind_button_state = false;
|
||||
|
@ -172,17 +172,29 @@ void PLAYBACK::update()
|
|||
emu_paused = (FCEUI_EmulationPaused() != 0);
|
||||
if (pause_frame)
|
||||
{
|
||||
if (old_show_pauseframe != show_pauseframe)
|
||||
if (old_show_pauseframe != show_pauseframe) // update progressbar from time to time
|
||||
SetProgressbar(currFrameCounter - seeking_start_frame, pause_frame - seeking_start_frame);
|
||||
} else if (old_emu_paused != emu_paused)
|
||||
{
|
||||
// emulator got paused/unpaused externally
|
||||
if (old_emu_paused && !emu_paused)
|
||||
// externally unpaused - progressbar should be empty
|
||||
SetProgressbar(0, 1);
|
||||
else
|
||||
{
|
||||
// externally unpaused
|
||||
if (currFrameCounter < currMovieData.getNumRecords()-1)
|
||||
{
|
||||
// don't forget to stop at the end of the movie
|
||||
pause_frame = currMovieData.getNumRecords();
|
||||
seeking_start_frame = currFrameCounter;
|
||||
} else
|
||||
{
|
||||
// unlimited emulation, appending the movie - progressbar should be empty
|
||||
SetProgressbar(0, 1);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// externally paused - progressbar should be full
|
||||
SetProgressbar(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// update the playback cursor
|
||||
|
@ -278,6 +290,17 @@ void PLAYBACK::SeekingStart(int finish_frame)
|
|||
turbo = true;
|
||||
UnpauseEmulation();
|
||||
}
|
||||
void PLAYBACK::SeekingContinue()
|
||||
{
|
||||
if (pause_frame)
|
||||
{
|
||||
if (taseditor_config.turbo_seek)
|
||||
turbo = true;
|
||||
UnpauseEmulation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PLAYBACK::SeekingStop()
|
||||
{
|
||||
pause_frame = 0;
|
||||
|
@ -388,10 +411,16 @@ bool PLAYBACK::JumpToFrame(int index)
|
|||
// Returns true if a jump to the frame is made, false if started seeking outside greenzone or if nothing's done
|
||||
if (index < 0) return false;
|
||||
|
||||
if (index+1 == pause_frame && emu_paused)
|
||||
{
|
||||
SeekingContinue();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index >= greenzone.greenZoneCount)
|
||||
{
|
||||
// handle jump outside greenzone
|
||||
if (currFrameCounter == greenzone.greenZoneCount-1 || JumpToFrame(greenzone.greenZoneCount-1))
|
||||
if (currFrameCounter >= greenzone.greenZoneCount-1 || JumpToFrame(greenzone.greenZoneCount-1))
|
||||
// seek from the end of greenzone
|
||||
SeekingStart(index+1);
|
||||
return false;
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
void updateProgressbar();
|
||||
|
||||
void SeekingStart(int finish_frame);
|
||||
void SeekingContinue();
|
||||
void SeekingStop();
|
||||
void ToggleEmulationPause();
|
||||
void PauseEmulation();
|
||||
|
@ -43,6 +44,7 @@ public:
|
|||
|
||||
bool JumpToFrame(int index);
|
||||
|
||||
int lastCursor; // but for currentCursor we use external variable currFrameCounter
|
||||
int lost_position_frame;
|
||||
int pause_frame;
|
||||
bool must_find_current_marker;
|
||||
|
@ -53,7 +55,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
int lastCursor; // but for currentCursor we use external variable currFrameCounter
|
||||
bool old_emu_paused, emu_paused;
|
||||
int old_pauseframe;
|
||||
bool old_show_pauseframe, show_pauseframe;
|
||||
|
|
|
@ -26,7 +26,7 @@ extern PIANO_ROLL piano_roll;
|
|||
extern MARKERS_MANAGER markers_manager;
|
||||
|
||||
LRESULT CALLBACK ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT APIENTRY MarkerNoteTooltipWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT APIENTRY MarkerNoteDescrWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// resources
|
||||
char szClassName[] = "ScrBmp";
|
||||
|
@ -34,6 +34,8 @@ char szClassName2[] = "MarketNoteTooltip";
|
|||
|
||||
POPUP_DISPLAY::POPUP_DISPLAY()
|
||||
{
|
||||
hwndScrBmp = 0;
|
||||
hwndMarkerNoteTooltip = 0;
|
||||
// create BITMAPINFO
|
||||
scr_bmi = (LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); // 256 color in palette
|
||||
scr_bmi->bmiHeader.biSize = sizeof(scr_bmi->bmiHeader);
|
||||
|
@ -44,7 +46,7 @@ POPUP_DISPLAY::POPUP_DISPLAY()
|
|||
scr_bmi->bmiHeader.biCompression = BI_RGB;
|
||||
scr_bmi->bmiHeader.biSizeImage = 0;
|
||||
|
||||
// register MarketNoteTooltip window class
|
||||
// register SCREENSHOT_DISPLAY window class
|
||||
wincl1.hInstance = fceu_hInstance;
|
||||
wincl1.lpszClassName = szClassName;
|
||||
wincl1.lpfnWndProc = ScrBmpWndProc;
|
||||
|
@ -60,10 +62,10 @@ POPUP_DISPLAY::POPUP_DISPLAY()
|
|||
if(!RegisterClassEx(&wincl1))
|
||||
FCEU_printf("Error registering SCREENSHOT_DISPLAY window class\n");
|
||||
|
||||
// register ScrBmp window class
|
||||
// register MARKER_NOTE_DESCRIPTION window class
|
||||
wincl2.hInstance = fceu_hInstance;
|
||||
wincl2.lpszClassName = szClassName2;
|
||||
wincl2.lpfnWndProc = MarkerNoteTooltipWndProc;
|
||||
wincl2.lpfnWndProc = MarkerNoteDescrWndProc;
|
||||
wincl2.style = CS_DBLCLKS;
|
||||
wincl2.cbSize = sizeof(WNDCLASSEX);
|
||||
wincl2.hIcon = 0;
|
||||
|
@ -74,7 +76,7 @@ POPUP_DISPLAY::POPUP_DISPLAY()
|
|||
wincl2.cbWndExtra = 0;
|
||||
wincl2.hbrBackground = 0;
|
||||
if(!RegisterClassEx(&wincl2))
|
||||
FCEU_printf("Error registering MARKER_NOTE_TOOLTIP window class\n");
|
||||
FCEU_printf("Error registering MARKER_NOTE_DESCRIPTION window class\n");
|
||||
|
||||
// create blendfunction
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
|
@ -272,7 +274,7 @@ LRESULT APIENTRY ScrBmpWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lP
|
|||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
LRESULT APIENTRY MarkerNoteTooltipWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
LRESULT APIENTRY MarkerNoteDescrWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
extern POPUP_DISPLAY popup_display;
|
||||
switch(message)
|
||||
|
|
|
@ -144,7 +144,7 @@ void SPLICER::CloneFrames()
|
|||
greenzone.InvalidateAndCheck(first_changes);
|
||||
} else if (markers_changed)
|
||||
{
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_MOVE, *current_selection->begin());
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SHIFT, *current_selection->begin());
|
||||
piano_roll.RedrawList();
|
||||
}
|
||||
if (markers_changed)
|
||||
|
@ -191,7 +191,7 @@ void SPLICER::InsertFrames()
|
|||
greenzone.InvalidateAndCheck(first_changes);
|
||||
} else if (markers_changed)
|
||||
{
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_MOVE, *current_selection->begin());
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SHIFT, *current_selection->begin());
|
||||
piano_roll.RedrawList();
|
||||
}
|
||||
if (markers_changed)
|
||||
|
@ -239,7 +239,7 @@ void SPLICER::InsertNumFrames()
|
|||
greenzone.InvalidateAndCheck(first_changes);
|
||||
} else if (markers_changed)
|
||||
{
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_MOVE, index);
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SHIFT, index);
|
||||
piano_roll.RedrawList();
|
||||
}
|
||||
if (markers_changed)
|
||||
|
@ -287,7 +287,7 @@ void SPLICER::DeleteFrames()
|
|||
else
|
||||
piano_roll.RedrawList();
|
||||
if (markers_changed)
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_MOVE, start_index);
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SHIFT, start_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,7 @@ bool SPLICER::PasteInsert()
|
|||
greenzone.InvalidateAndCheck(first_changes);
|
||||
} else if (markers_changed)
|
||||
{
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_MOVE, *current_selection->begin());
|
||||
history.RegisterMarkersChange(MODTYPE_MARKER_SHIFT, *current_selection->begin());
|
||||
piano_roll.RedrawList();
|
||||
}
|
||||
if (markers_changed)
|
||||
|
|
|
@ -71,6 +71,8 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
|
|||
findnote_search_up = false;
|
||||
enable_auto_function = true;
|
||||
deselect_on_doubleclick = false;
|
||||
doubleclick_affects_playback = true;
|
||||
draw_input = true;
|
||||
silent_autosave = true;
|
||||
tooltips = true;
|
||||
current_pattern = 0;
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
bool findnote_search_up;
|
||||
bool enable_auto_function;
|
||||
bool deselect_on_doubleclick;
|
||||
bool doubleclick_affects_playback;
|
||||
bool draw_input;
|
||||
bool silent_autosave;
|
||||
bool tooltips;
|
||||
int current_pattern;
|
||||
|
|
|
@ -60,7 +60,7 @@ void TASEDITOR_PROJECT::reset()
|
|||
void TASEDITOR_PROJECT::update()
|
||||
{
|
||||
// if it's time to autosave - pop Save As dialog
|
||||
if (changed && taseditor_config.autosave_period && clock() >= next_save_shedule)
|
||||
if (changed && taseditor_config.autosave_period && clock() >= next_save_shedule && piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
{
|
||||
if (taseditor_config.silent_autosave)
|
||||
SaveProject();
|
||||
|
@ -123,6 +123,8 @@ bool TASEDITOR_PROJECT::save(const char* different_name, bool save_binary, bool
|
|||
ofs = FCEUD_UTF8_fstream(GetProjectFile().c_str(), "wb");
|
||||
if (ofs)
|
||||
{
|
||||
// change cursor to hourglass
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
currMovieData.loadFrameCount = currMovieData.records.size();
|
||||
currMovieData.emuVersion = FCEU_VERSION_NUMERIC;
|
||||
currMovieData.dump(ofs, save_binary);
|
||||
|
@ -146,6 +148,8 @@ bool TASEDITOR_PROJECT::save(const char* different_name, bool save_binary, bool
|
|||
// also reset autosave period if we saved the project to its current filename
|
||||
if (!different_name)
|
||||
this->reset();
|
||||
// restore cursor
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
|
@ -162,6 +166,8 @@ bool TASEDITOR_PROJECT::load(char* fullname)
|
|||
return false;
|
||||
}
|
||||
|
||||
// change cursor to hourglass
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
MovieData tempMovieData = MovieData();
|
||||
extern bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader);
|
||||
if (LoadFM2(tempMovieData, &ifs, ifs.size(), false))
|
||||
|
@ -227,6 +233,8 @@ bool TASEDITOR_PROJECT::load(char* fullname)
|
|||
popup_display.reset();
|
||||
reset();
|
||||
RenameProject(fullname);
|
||||
// restore cursor
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ Window - User Interface
|
|||
|
||||
* implements all operations with TAS Editor window: creating, redrawing, resizing, moving, tooltips, clicks
|
||||
* processes OS messages and sends signals from user to TAS Editor modules (also implements some minor commands on-site, like Greenzone capacity dialog and such)
|
||||
* regularly checks if Shift or Ctrl key is held and sets keyboard focus to Piano Roll
|
||||
* switches off/on emulator's keyboard input when the window loses/gains focus
|
||||
* on demand: updates the window caption
|
||||
* updates all checkboxes and menu items when some settings change
|
||||
|
@ -449,6 +450,8 @@ void TASEDITOR_WINDOW::UpdateCheckedItems()
|
|||
CheckMenuItem(hmenu, ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE, taseditor_config.superimpose_affects_paste?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_COLUMNSETPATTERNSKIPSLAG, taseditor_config.pattern_skips_lag?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_DESELECTONDOUBLECLICK, taseditor_config.deselect_on_doubleclick?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_DOUBLECLICKONFRAME, taseditor_config.doubleclick_affects_playback?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_DRAWINPUTBYDRAGGING, taseditor_config.draw_input?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_SILENTAUTOSAVE, taseditor_config.silent_autosave?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_HELP_TOOLTIPS, taseditor_config.tooltips?MF_CHECKED : MF_UNCHECKED);
|
||||
|
@ -694,6 +697,9 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
case LVN_ODSTATECHANGED:
|
||||
selection.ItemRangeChanged((LPNMLVODSTATECHANGE) lParam);
|
||||
break;
|
||||
case LVN_ENDSCROLL:
|
||||
piano_roll.must_check_item_under_mouse = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDC_BOOKMARKSLIST:
|
||||
|
@ -1064,6 +1070,14 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
taseditor_config.deselect_on_doubleclick ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_DOUBLECLICKONFRAME:
|
||||
taseditor_config.doubleclick_affects_playback ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_DRAWINPUTBYDRAGGING:
|
||||
taseditor_config.draw_input ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_SILENTAUTOSAVE:
|
||||
taseditor_config.silent_autosave ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
|
@ -1304,6 +1318,26 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
}
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
// if user clicked on a narrow space to the left of Piano Roll
|
||||
// consider this as a "misclick" on Piano Roll's first column
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
RECT wrect;
|
||||
GetWindowRect(piano_roll.hwndList, &wrect);
|
||||
if (x > 0
|
||||
&& x <= window_items[PIANOROLL_IN_WINDOWITEMS].x
|
||||
&& y > window_items[PIANOROLL_IN_WINDOWITEMS].y
|
||||
&& y < window_items[PIANOROLL_IN_WINDOWITEMS].y + (wrect.bottom - wrect.top))
|
||||
{
|
||||
piano_roll.DragPlaybackCursor();
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
piano_roll.drag_mode = DRAG_MODE_PLAYBACK;
|
||||
}
|
||||
if (GetFocus() != hWnd)
|
||||
SetFocus(hWnd);
|
||||
break;
|
||||
}
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
{
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Specification file for TASEDITOR_WINDOW class
|
||||
|
||||
#define TASEDITOR_WINDOW_TOTAL_ITEMS 43
|
||||
#define PIANOROLL_IN_WINDOWITEMS 2
|
||||
#define HISTORYLIST_IN_WINDOWITEMS 18
|
||||
|
||||
#define TOOLTIP_TEXT_MAX_LEN 80
|
||||
#define TOOLTIPS_AUTOPOP_TIMEOUT 30000
|
||||
|
||||
|
|
Loading…
Reference in New Issue