Skip to content

Commit 6669b22

Browse files
committed
Added validate function and button labels to utils.inputbox
1 parent 7da05d3 commit 6669b22

File tree

5 files changed

+162
-24
lines changed

5 files changed

+162
-24
lines changed

dialogs/LuaInputBox.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
static char THIS_FILE[] = __FILE__;
1212
#endif
1313

14+
#pragma warning (disable : 4800) // forcing value to bool 'true' or 'false' (performance warning)
15+
1416
/////////////////////////////////////////////////////////////////////////////
1517
// CLuaInputBox dialog
1618

@@ -25,6 +27,7 @@ CLuaInputBox::CLuaInputBox(CWnd* pParent /*=NULL*/)
2527
//}}AFX_DATA_INIT
2628

2729
m_font = NULL;
30+
m_L = NULL;
2831

2932
}
3033

@@ -42,8 +45,43 @@ void CLuaInputBox::DoDataExchange(CDataExchange* pDX)
4245
{
4346
if (!m_strFont.IsEmpty () && m_iFontSize > 3)
4447
FixFont (m_font, m_ctlReply, m_strFont, m_iFontSize, FW_NORMAL, DEFAULT_CHARSET);
48+
return;
4549
}
4650

51+
52+
if (m_L && lua_type (m_L, -1) == LUA_TFUNCTION)
53+
{
54+
bool bWanted = false;
55+
56+
// Lua validation: function f (value) ... end
57+
58+
// validate function (make copy)
59+
lua_pushvalue (m_L, -1);
60+
// what they have currently typed
61+
lua_pushlstring (m_L, m_strReply, m_strReply.GetLength ());
62+
63+
// call the function: arg1: what they typed
64+
if (lua_pcall (m_L, 1, 1, 0)) // call with 1 arg and 1 result
65+
{
66+
LuaError (m_L); // note that this clears the stack, so we won't call it again
67+
lua_settop (m_L, 0); // clear stack, just in case LuaError changes behaviour
68+
pDX->Fail();
69+
} // end of error
70+
else
71+
{
72+
bWanted = lua_toboolean (m_L, -1);
73+
lua_pop (m_L, 1); // pop result
74+
} // end of no error
75+
76+
if (!bWanted)
77+
{
78+
DDX_Text(pDX, IDC_INPUT_BOX_REPLY, m_strReply);
79+
pDX->Fail();
80+
}
81+
82+
} // end of Lua validation function available
83+
84+
4785
}
4886

4987

@@ -67,6 +105,7 @@ BOOL CLuaInputBox::OnInitDialog()
67105

68106
PostMessage (WM_COMMAND, CLEAR_SELECTION);
69107

108+
// move dialog into position
70109
WINDOWPLACEMENT wndpl;
71110

72111
GetWindowPlacement (&wndpl);
@@ -79,9 +118,17 @@ BOOL CLuaInputBox::OnInitDialog()
79118

80119
MoveWindow(wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top, m_iBoxWidth, m_iBoxHeight);
81120

121+
// limit text entry length if desired
82122
if (m_iMaxReplyLength > 0)
83123
::SendMessage(m_ctlReply, EM_LIMITTEXT, m_iMaxReplyLength, 0);
84124

125+
// new OK button label
126+
if (!m_strOKbuttonLabel.IsEmpty ())
127+
GetDlgItem (IDOK)->SetWindowText (m_strOKbuttonLabel);
128+
129+
// new Cancel button label
130+
if (!m_strCancelbuttonLabel.IsEmpty ())
131+
GetDlgItem (IDCANCEL)->SetWindowText (m_strCancelbuttonLabel);
85132

86133
return TRUE; // return TRUE unless you set the focus to a control
87134
// EXCEPTION: OCX Property Pages should return FALSE

dialogs/LuaInputBox.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class CLuaInputBox : public CDialog
4040
int m_iReplyWidth;
4141
int m_iReplyHeight;
4242
int m_iMaxReplyLength;
43+
CString m_strOKbuttonLabel;
44+
CString m_strCancelbuttonLabel;
45+
46+
lua_State *m_L; // for validating
4347

4448
// Overrides
4549
// ClassWizard generated virtual function overrides

dialogs/LuaInputEditDlg.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
static char THIS_FILE[] = __FILE__;
1212
#endif
1313

14+
#pragma warning (disable : 4800) // forcing value to bool 'true' or 'false' (performance warning)
15+
1416
/////////////////////////////////////////////////////////////////////////////
1517
// CLuaInputEditDlg dialog
1618

@@ -45,8 +47,41 @@ void CLuaInputEditDlg::DoDataExchange(CDataExchange* pDX)
4547
{
4648
if (!m_strFont.IsEmpty () && m_iFontSize > 3)
4749
FixFont (m_font, m_ctlReply, m_strFont, m_iFontSize, FW_NORMAL, DEFAULT_CHARSET);
50+
return;
4851
}
4952

53+
if (m_L && lua_type (m_L, -1) == LUA_TFUNCTION)
54+
{
55+
bool bWanted = false;
56+
57+
// Lua validation: function f (value) ... end
58+
59+
// validate function (make copy)
60+
lua_pushvalue (m_L, -1);
61+
// what they have currently typed
62+
lua_pushlstring (m_L, m_strReply, m_strReply.GetLength ());
63+
64+
// call the function: arg1: what they typed
65+
if (lua_pcall (m_L, 1, 1, 0)) // call with 1 arg and 1 result
66+
{
67+
LuaError (m_L); // note that this clears the stack, so we won't call it again
68+
lua_settop (m_L, 0); // clear stack, just in case LuaError changes behaviour
69+
pDX->Fail();
70+
} // end of error
71+
else
72+
{
73+
bWanted = lua_toboolean (m_L, -1);
74+
lua_pop (m_L, 1); // pop result
75+
} // end of no error
76+
77+
if (!bWanted)
78+
{
79+
DDX_Text(pDX, IDC_INPUT_BOX_REPLY, m_strReply);
80+
pDX->Fail();
81+
}
82+
83+
} // end of Lua validation function available
84+
5085
}
5186

5287

@@ -85,6 +120,18 @@ BOOL CLuaInputEditDlg::OnInitDialog()
85120
if (m_iMaxReplyLength > 0)
86121
::SendMessage(m_ctlReply, EM_LIMITTEXT, m_iMaxReplyLength, 0);
87122

123+
// limit text entry length if desired
124+
if (m_iMaxReplyLength > 0)
125+
::SendMessage(m_ctlReply, EM_LIMITTEXT, m_iMaxReplyLength, 0);
126+
127+
// new OK button label
128+
if (!m_strOKbuttonLabel.IsEmpty ())
129+
GetDlgItem (IDOK)->SetWindowText (m_strOKbuttonLabel);
130+
131+
// new Cancel button label
132+
if (!m_strCancelbuttonLabel.IsEmpty ())
133+
GetDlgItem (IDCANCEL)->SetWindowText (m_strCancelbuttonLabel);
134+
88135
return TRUE; // return TRUE unless you set the focus to a control
89136
// EXCEPTION: OCX Property Pages should return FALSE
90137
}

dialogs/LuaInputEditDlg.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class CLuaInputEditDlg : public CDialog
4141
int m_iReplyWidth;
4242
int m_iReplyHeight;
4343
int m_iMaxReplyLength;
44+
CString m_strOKbuttonLabel;
45+
CString m_strCancelbuttonLabel;
46+
47+
lua_State *m_L; // for validating
4448

4549
// Overrides
4650
// ClassWizard generated virtual function overrides

scripting/lua_utils.cpp

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static int umsgbox (lua_State *L)
263263
} // end of umsgbox
264264

265265

266-
static int get_extra_field (lua_State *L, const int narg, const char * name)
266+
static int get_extra_integer (lua_State *L, const int narg, const char * name)
267267
{
268268
int iResult;
269269

@@ -272,7 +272,18 @@ static int get_extra_field (lua_State *L, const int narg, const char * name)
272272
lua_pop (L, 1);
273273

274274
return iResult;
275-
} // end of get_extra_field
275+
} // end of get_extra_integer
276+
277+
static CString get_extra_string (lua_State *L, const int narg, const char * name)
278+
{
279+
CString strResult;
280+
281+
lua_getfield (L, narg, name);
282+
strResult = luaL_optstring (L, -1, "");
283+
lua_pop (L, 1);
284+
285+
return strResult;
286+
} // end of get_extra_string
276287

277288
// input-box display routine
278289
// arg1 = message to display
@@ -281,13 +292,16 @@ static int get_extra_field (lua_State *L, const int narg, const char * name)
281292
// arg4 = input font
282293
// arg5 = input font size
283294
// arg6 = table of extra stuff:
284-
// box_width --> width of message box in pixels (min 180)
285-
// box_height --> height of message box in pixels (min 125)
286-
// prompt_width --> width of prompt text in pixels (min 10)
287-
// prompt_height --> height of prompt text in pixels (min 12)
288-
// reply_width --> width of reply in pixels (min 10)
289-
// reply_height --> height of reply in pixels (min 10)
290-
// max_length --> max characters they can type (min 1)
295+
// box_width --> width of message box in pixels (min 180)
296+
// box_height --> height of message box in pixels (min 125)
297+
// prompt_width --> width of prompt text in pixels (min 10)
298+
// prompt_height --> height of prompt text in pixels (min 12)
299+
// reply_width --> width of reply in pixels (min 10)
300+
// reply_height --> height of reply in pixels (min 10)
301+
// max_length --> max characters they can type (min 1)
302+
// validate --> validation function
303+
// ok_button --> what to put on the OK button (default: OK)
304+
// cancel_button --> what to put on the Cancel button (default: Cancel)
291305
//
292306
// returns: what they typed, or nil if cancelled
293307

@@ -309,18 +323,38 @@ static int gen_inputbox (lua_State *L, T & msg)
309323
int iReplyWidth = 0;
310324
int iReplyHeight = 0;
311325
int iMaxReplyLength = 0;
326+
CString strOKbuttonLabel;
327+
CString strCancelbuttonLabel;
328+
329+
312330

313331
// if arg6 present, and a table, grab extra stuff
314332
if (lua_istable (L, nExtraStuffArg))
315333
{
316-
iBoxWidth = get_extra_field (L, nExtraStuffArg, "box_width");
317-
iBoxHeight = get_extra_field (L, nExtraStuffArg, "box_height");
318-
iPromptWidth = get_extra_field (L, nExtraStuffArg, "prompt_width");
319-
iPromptHeight = get_extra_field (L, nExtraStuffArg, "prompt_height");
320-
iReplyWidth = get_extra_field (L, nExtraStuffArg, "reply_width");
321-
iReplyHeight = get_extra_field (L, nExtraStuffArg, "reply_height");
322-
iMaxReplyLength = get_extra_field (L, nExtraStuffArg, "max_length");
323-
}
334+
iBoxWidth = get_extra_integer (L, nExtraStuffArg, "box_width");
335+
iBoxHeight = get_extra_integer (L, nExtraStuffArg, "box_height");
336+
iPromptWidth = get_extra_integer (L, nExtraStuffArg, "prompt_width");
337+
iPromptHeight = get_extra_integer (L, nExtraStuffArg, "prompt_height");
338+
iReplyWidth = get_extra_integer (L, nExtraStuffArg, "reply_width");
339+
iReplyHeight = get_extra_integer (L, nExtraStuffArg, "reply_height");
340+
iMaxReplyLength = get_extra_integer (L, nExtraStuffArg, "max_length");
341+
strOKbuttonLabel = get_extra_string (L, nExtraStuffArg, "ok_button");
342+
strCancelbuttonLabel = get_extra_string (L, nExtraStuffArg, "cancel_button");
343+
344+
345+
// see if validation function there - do this last so we can leave it on the stack
346+
lua_getfield (L, nExtraStuffArg, "validate");
347+
348+
if (!lua_isnil (L, -1))
349+
{
350+
if (!lua_isfunction (L, -1))
351+
luaL_error (L, "inputbox argument 6 value for 'validate' must be a function");
352+
353+
lua_pushvalue (L, -1); // function is now on top of stack
354+
msg.m_L = L; // non-NULL indicates we have function there
355+
} // validate function there
356+
357+
} // table of extra stuff there
324358

325359
// if we leave in & it will make the next letter underlined
326360
string sInputMsg = FindAndReplace (inputmsg, "&", "&&");
@@ -338,13 +372,15 @@ static int gen_inputbox (lua_State *L, T & msg)
338372
msg.m_iFontSize = inputsize;
339373

340374
// extra stuff from table which is argument 6 (if present)
341-
msg.m_iBoxWidth = iBoxWidth ;
342-
msg.m_iBoxHeight = iBoxHeight ;
343-
msg.m_iPromptWidth = iPromptWidth ;
344-
msg.m_iPromptHeight = iPromptHeight;
345-
msg.m_iReplyWidth = iReplyWidth ;
346-
msg.m_iReplyHeight = iReplyHeight ;
347-
msg.m_iMaxReplyLength = iMaxReplyLength;
375+
msg.m_iBoxWidth = iBoxWidth ;
376+
msg.m_iBoxHeight = iBoxHeight ;
377+
msg.m_iPromptWidth = iPromptWidth ;
378+
msg.m_iPromptHeight = iPromptHeight;
379+
msg.m_iReplyWidth = iReplyWidth ;
380+
msg.m_iReplyHeight = iReplyHeight ;
381+
msg.m_iMaxReplyLength = iMaxReplyLength;
382+
msg.m_strOKbuttonLabel = strOKbuttonLabel ;
383+
msg.m_strCancelbuttonLabel = strCancelbuttonLabel;
348384

349385
if (msg.DoModal () != IDOK)
350386
lua_pushnil (L);

0 commit comments

Comments
 (0)