2 * Move history for WinBoard
\r
4 * Author: Alessandro Scotti (Dec 2005)
\r
5 * front-end code split off by HGM
\r
7 * Copyright 2005 Alessandro Scotti
\r
9 * Enhancements Copyright 2009, 2010, 2014, 2015, 2016 Free Software
\r
12 * ------------------------------------------------------------------------
\r
14 * GNU XBoard is free software: you can redistribute it and/or modify
\r
15 * it under the terms of the GNU General Public License as published by
\r
16 * the Free Software Foundation, either version 3 of the License, or (at
\r
17 * your option) any later version.
\r
19 * GNU XBoard is distributed in the hope that it will be useful, but
\r
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
\r
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
22 * General Public License for more details.
\r
24 * You should have received a copy of the GNU General Public License
\r
25 * along with this program. If not, see http://www.gnu.org/licenses/.
\r
27 * ------------------------------------------------------------------------
\r
28 ** See the file ChangeLog for a revision history. */
\r
35 #include <windows.h> /* required for all Windows applications */
\r
36 #include <richedit.h>
\r
37 #include <commdlg.h>
\r
41 #include "frontend.h"
\r
42 #include "backend.h"
\r
43 #include "winboard.h"
\r
46 // templates for calls into back-end
\r
47 void RefreshMemoContent P((void));
\r
48 void MemoContentUpdated P((void));
\r
49 void FindMoveByCharIndex P(( int char_index ));
\r
51 #define DEFAULT_COLOR 0xFFFFFFFF
\r
56 static BOOLEAN moveHistoryDialogUp = FALSE;
\r
58 // ------------- low-level front-end actions called by MoveHistory back-end -----------------
\r
60 // low-level front-end, after calculating from & to is left to caller
\r
61 // it task is to highlight the indicated characters. (In WinBoard it makes them bold and blue.)
\r
62 void HighlightMove( int from, int to, Boolean highlight )
\r
65 HWND hMemo = GetDlgItem( moveHistoryDialog, IDC_MoveHistory );
\r
67 SendMessage( hMemo, EM_SETSEL, from, to);
\r
71 ZeroMemory( &cf, sizeof(cf) );
\r
73 cf.cbSize = sizeof(cf);
\r
74 cf.dwMask = CFM_BOLD | CFM_COLOR;
\r
77 cf.dwEffects |= CFE_BOLD;
\r
78 cf.crTextColor = RGB( 0x00, 0x00, 0xFF );
\r
81 cf.dwEffects |= CFE_AUTOCOLOR;
\r
84 SendMessage( hMemo, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf );
\r
87 // low-level front-end, but replace Windows data types to make it callable from back-end
\r
88 // its task is to clear the contents of the move-history text edit
\r
89 void ClearHistoryMemo()
\r
91 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, WM_SETTEXT, 0, (LPARAM) "" );
\r
94 // low-level front-end, made callable from back-end by passing flags and color numbers
\r
95 // its task is to append the given text to the text edit
\r
96 // the bold argument says 0 = normal, 1 = bold typeface
\r
97 // the colorNr argument says 0 = font-default, 1 = gray
\r
98 int AppendToHistoryMemo( char * text, int bold, int colorNr )
\r
101 DWORD flags = bold ? CFE_BOLD :0;
\r
102 DWORD color = colorNr ? GetSysColor(COLOR_GRAYTEXT) : DEFAULT_COLOR;
\r
104 HWND hMemo = GetDlgItem( moveHistoryDialog, IDC_MoveHistory );
\r
106 /* Select end of text */
\r
107 int cbTextLen = (int) SendMessage( hMemo, WM_GETTEXTLENGTH, 0, 0 );
\r
109 SendMessage( hMemo, EM_SETSEL, cbTextLen, cbTextLen );
\r
112 ZeroMemory( &cf, sizeof(cf) );
\r
114 cf.cbSize = sizeof(cf);
\r
115 cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_COLOR | CFM_UNDERLINE;
\r
116 cf.dwEffects = flags;
\r
118 if( color != DEFAULT_COLOR ) {
\r
119 cf.crTextColor = color;
\r
122 cf.dwEffects |= CFE_AUTOCOLOR;
\r
125 SendMessage( hMemo, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf );
\r
128 SendMessage( hMemo, EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text );
\r
130 /* Return offset of appended text */
\r
134 // low-level front-end; wrapper for the code to scroll the mentioned character in view (-1 = end)
\r
135 void ScrollToCurrent(int caretPos)
\r
138 caretPos = (int) SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, WM_GETTEXTLENGTH, 0, 0 );
\r
139 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, EM_SETSEL, caretPos, caretPos );
\r
141 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, EM_SCROLLCARET, 0, 0 );
\r
145 // ------------------------------ call backs --------------------------
\r
147 // front-end. Universal call-back for any event. Recognized vents are dialog creation, OK and cancel button-press
\r
148 // (dead code, as these buttons do not exist?), mouse clicks on the text edit, and moving / sizing
\r
149 LRESULT CALLBACK HistoryDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
\r
151 static SnapData sd;
\r
154 case WM_INITDIALOG:
\r
155 if( moveHistoryDialog == NULL ) {
\r
156 moveHistoryDialog = hDlg;
\r
157 Translate(hDlg, DLG_MoveHistory);
\r
159 /* Enable word wrapping and notifications */
\r
160 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, EM_SETTARGETDEVICE, 0, 0 );
\r
162 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );
\r
165 SendDlgItemMessage( moveHistoryDialog, IDC_MoveHistory, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 ));
\r
167 /* Restore window placement */
\r
168 RestoreWindowPlacement( hDlg, &wpMoveHistory );
\r
172 RefreshMemoContent();
\r
174 MemoContentUpdated();
\r
179 switch (LOWORD(wParam)) {
\r
181 EndDialog(hDlg, TRUE);
\r
185 EndDialog(hDlg, FALSE);
\r
195 if( wParam == IDC_MoveHistory ) {
\r
196 MSGFILTER * lpMF = (MSGFILTER *) lParam;
\r
198 if( lpMF->msg == WM_LBUTTONDBLCLK && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) {
\r
202 pt.x = LOWORD( lpMF->lParam );
\r
203 pt.y = HIWORD( lpMF->lParam );
\r
205 index = SendDlgItemMessage( hDlg, IDC_MoveHistory, EM_CHARFROMPOS, 0, (LPARAM) &pt );
\r
207 FindMoveByCharIndex( index ); // [HGM] also does the actual moving to it, now
\r
209 /* Zap the message for good: apparently, returning non-zero is not enough */
\r
210 lpMF->msg = WM_USER;
\r
218 SetWindowPos( GetDlgItem( moveHistoryDialog, IDC_MoveHistory ),
\r
220 H_MARGIN, V_MARGIN,
\r
221 LOWORD(lParam) - 2*H_MARGIN,
\r
222 HIWORD(lParam) - 2*V_MARGIN,
\r
226 case WM_GETMINMAXINFO:
\r
228 MINMAXINFO * mmi = (MINMAXINFO *) lParam;
\r
230 mmi->ptMinTrackSize.x = 100;
\r
231 mmi->ptMinTrackSize.y = 100;
\r
236 MoveHistoryPopDown();
\r
239 case WM_ENTERSIZEMOVE:
\r
240 return OnEnterSizeMove( &sd, hDlg, wParam, lParam );
\r
243 return OnSizing( &sd, hDlg, wParam, lParam );
\r
246 return OnMoving( &sd, hDlg, wParam, lParam );
\r
248 case WM_EXITSIZEMOVE:
\r
249 return OnExitSizeMove( &sd, hDlg, wParam, lParam );
\r
255 // ------------ standard entry points into MoveHistory code -----------
\r
258 VOID MoveHistoryPopUp()
\r
262 CheckMenuItem(GetMenu(hwndMain), IDM_ShowMoveHistory, MF_CHECKED);
\r
264 if( moveHistoryDialog ) {
\r
265 SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );
\r
267 if( ! moveHistoryDialogUp ) {
\r
268 ShowWindow(moveHistoryDialog, SW_SHOW);
\r
272 lpProc = MakeProcInstance( (FARPROC) HistoryDialogProc, hInst );
\r
274 /* Note to self: dialog must have the WS_VISIBLE style set, otherwise it's not shown! */
\r
275 CreateDialog( hInst, MAKEINTRESOURCE(DLG_MoveHistory), hwndMain, (DLGPROC)lpProc );
\r
277 FreeProcInstance(lpProc);
\r
280 moveHistoryDialogUp = TRUE;
\r
282 // Note that in WIndows creating the dialog causes its call-back to perform
\r
283 // RefreshMemoContent() and MemoContentUpdated() immediately after it is realized.
\r
284 // To port this to X we might have to do that from here.
\r
288 VOID MoveHistoryPopDown()
\r
290 CheckMenuItem(GetMenu(hwndMain), IDM_ShowMoveHistory, MF_UNCHECKED);
\r
292 if( moveHistoryDialog ) {
\r
293 ShowWindow(moveHistoryDialog, SW_HIDE);
\r
296 moveHistoryDialogUp = FALSE;
\r
300 Boolean MoveHistoryIsUp()
\r
302 return moveHistoryDialogUp;
\r
306 Boolean MoveHistoryDialogExists()
\r
308 return moveHistoryDialog != NULL;
\r