Skip to content

Commit 6ad6163

Browse files
committed
Bug fixes & Sub-menu improvements
Allow Menu objects representing sub-menus to be inserted anywhere in the parent menu list. Fixed bug with menu-bar break followed by sub-menu. Allow sub-menus to be disabled.
1 parent 74e55f1 commit 6ad6163

File tree

10 files changed

+85
-57
lines changed

10 files changed

+85
-57
lines changed

Distro/Winsh2-0.zip

-187 Bytes
Binary file not shown.

Doc/Publishing.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Generating the Published (read only) version of the documentation TiddlyWiki.
2+
-----------------------------------------------------------------------------
3+
4+
The internal SaveAs function no longer works, so must process the file manually:
5+
6+
1. Copy the source file to a new file.
7+
2. Find and edit the "Imprint" tiddler. Add the tag "$$!published!" to its tags.
8+
3. Find and delete all tiddlers tagged "excludePublished".
9+
4. Save and close the file.
10+
5. Open the file in a text editor.
11+
6. In the "versionArea" script section near the top of the file, edit the title "TiddlyWiki" to "TW".
12+
7. Save and close the file - it should now reopen in a browser as a read-only published version.
13+
14+
NB: Step 6 prevents the TiddlySaver plugin for FireFox from bothering the user for permission
15+
to inject saver code into this file. Issue raised on GitHub - hopefully Jeremy will fix at some
16+
point.

Doc/Winsh.html

+24-17
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,7 @@
19021902
The ''Help'' menu contains commands to show various pieces of information including an inventory of resources available in the executable file. This information is supplied by functions defined in the '''"""INIT-CMD"""''' resource, which may be customised as required.
19031903
</pre>
19041904
</div>
1905-
<div title="Introduction" creator="John Hind" modifier="John Hind" created="201005272040" modified="201402211438" tags="startup" changecount="10">
1905+
<div title="Introduction" creator="John Hind" modifier="John Hind" created="201005272040" modified="201403240925" tags="startup" changecount="11">
19061906
<pre>Winsh.lua is an advanced runtime for the [[Lua]] language on Windows. With the supplied libraries it is ideal for writing small, self-contained utilities with simple command line or graphical interfaces such as backup automation scripts, installers and portable application menus.
19071907

19081908
Winsh.lua is compatible with all versions of Windows starting with Windows XP. However a few library features are only supported in later Windows versions. These are noted in this documentation and are designed to degrade as gracefully as possible.
@@ -1921,7 +1921,7 @@
19211921
The [[Interactive Console]] and [[Lua]] topics are good starting points for new users.
19221922

19231923
----
1924-
This help file was created using the superb and innovative &quot;&quot;&quot;TiddlyWiKi&quot;&quot;&quot;: http://classic.tiddlywiki.com/.</pre>
1924+
This document was created using the superb and innovative &quot;&quot;&quot;TiddlyWiKi&quot;&quot;&quot;: http://classic.tiddlywiki.com/.</pre>
19251925
</div>
19261926
<div title="JHBackstagePlugin" creator="John Hind" modifier="John Hind" created="201102041649" modified="201102152102" tags="systemConfig excludeLists excludePublished excludeSearch excludeMissing" changecount="9">
19271927
<pre>/***
@@ -3000,23 +3000,25 @@
30003000
};
30013001
//}}}</pre>
30023002
</div>
3003-
<div title="Menu Class" creator="John Hind" modifier="John Hind" created="201311231135" modified="201402211711" changecount="24">
3003+
<div title="Menu Class" creator="John Hind" modifier="John Hind" created="201311231135" modified="201403241042" changecount="29">
30043004
<pre>!menu = winsh.Menu([title] [, onshow] [, gutter])
3005-
The Menu Class generates objects which represent menus of actions. Menu inherits from [[List Class]] and all List methods may be used to create and modify the menu list. The optional parameters initialise the pre-defined fields (see below). A string parameter initialises '''title''', a callable parameter initialises '''onshow''' and a boolean parameter '''gutter'''.
3005+
The Menu Class generates objects which represent menus of actions. Menu inherits the methods of [[List Class]] and all List methods may be used to create and modify the menu list. However [[list:insert]] inserts Menu class objects as objects rather than as lists allowing sub-menus to be created. The optional parameters initialise some of the pre-defined fields (see below). A string parameter initialises '''title''', a callable parameter initialises '''onshow''' and a boolean parameter '''gutter'''.
30063006

30073007
Each list item must have a value comprising one of the following:
30083008
* A [[Command Class]] object representing a command which may be executed from the menu.
30093009
* A [[Menu Class]] object representing a sub-menu which may be opened from the menu.
30103010
* A string &quot;-&quot; which causes a horizontal separator line to be drawn.
30113011
* A string &quot;|&quot; which specifies a column split dividing the menu into two columns.
30123012
* A string (not one of the above) which becomes a non-selectable menu item (heading) unless it exists in a column on its own, in which case it becomes a vertical side-bar label.
3013-
The pre-defined (read-only) fields are as follows:
3013+
The pre-defined fields are as follows:
30143014
;'''title'''
30153015
:This string value is the menu text shown for a sub-menu. If a menu object is used to define a sub-menu and this field is missing the default text &quot;sub menu&quot; is used.
30163016
;'''onshow'''
30173017
:This is an optional field and if present the value can be any callable Lua object (usually a function) which is called immediately prior to showing the menu and passed a single parameter, the Menu object. It can be used to modify the Menu or Command objects to vary the appearance and function of the menu that is shown to the user.
30183018
;'''gutter'''
30193019
:If present this overrides the default handling which shows a gutter if any Command objects in the menu or any sub-menus have '''icon''' or boolean '''value''' fields and not otherwise. Set to boolean {{{true}}} to show the gutter always, or boolean {{{false}}} to hide it always (in which case icons will be ignored and boolean '''value''' will be rendered using text colour rather than checkmarks). The setting applies globally to the menu and all of its sub-menus, and the '''gutter''' key should be applied in the main Menu table (however '''gutter''' {{{true}}} in a sub-menu will have effect as long as there is no '''gutter''' {{{false}}} in a parent menu or a subsequent sub-menu).
3020+
;'''disabled'''
3021+
:This field is initialised {{{false}}}. It may be changed (usually in an '''onshow''' function). It only has effect for a menu used as a submenu within another menu. If it is true when the menu is shown, the title entry for the sub-menu is shown disabled and the menu itself is not shown.
30203022
</pre>
30213023
</div>
30223024
<div title="Nested Sliders" creator="John Hind" modifier="John Hind" created="201102061601" modified="201105211433" tags="excludeLists excludePublished excludeSearch excludeMissing">
@@ -3821,14 +3823,15 @@
38213823
[[key:deletevalue]] - Delete a named value of the current key.
38223824
</pre>
38233825
</div>
3824-
<div title="Release 2.0" creator="John Hind" modifier="John Hind" created="201102271549" modified="201402181749" tags="imprint excludeLists" changecount="16">
3826+
<div title="Release 2.0" creator="John Hind" modifier="John Hind" created="201102271549" modified="201403251041" tags="imprint excludeLists" changecount="26">
38253827
<pre>|Name|Winsh|
38263828
|Author|[[John Hind]]|
3827-
|Version|2.0|
3828-
|Copyright|&amp;copy;2012 [[John Hind]]|
3829-
|Release Date|26th November 2012|
3829+
|Version|2.0.1|
3830+
|Copyright|&amp;copy;2014 [[John Hind]]|
3831+
|Release Date|25th March 2014|
38303832
{{H3{Release Notes}}}
3831-
&gt;2.0 - Changed object model and added clipboard support.
3833+
&gt;2.0.1 - Added {{{__whole}}} metafield for [[List Class]]. Used this to fix sub-menu insertion. Added {{{disabled}}} field to [[Menu Class]] (for sub-menus).
3834+
&gt;2.0 - Changed object model and added clipboard support. Updated Lua core to 5.2.2. Changed name from Grunt to Winsh.
38323835
&gt;1.2 - Updated the &quot;&quot;&quot;Self-Iterating&quot;&quot;&quot; Objects Lua patch, changed [[winsh.taskicon]].
38333836
&gt;1.1 - Upgraded Lua core to 5.2.1.
38343837
''&lt;&lt;publish&gt;&gt;''</pre>
@@ -5166,7 +5169,7 @@
51665169

51675170
%/&lt;&lt;tiddler {{'ShowPopup##'+('$1'=='$'+'1'?'info':'show')}} with: [[$1]] [[$2]] [[$3]] [[$4]] [[$5]] [[$6]]&gt;&gt;</pre>
51685171
</div>
5169-
<div title="Side-by-side Execution" creator="John Hind" modifier="John Hind" created="201005292130" modified="201402211459" changecount="4">
5172+
<div title="Side-by-side Execution" creator="John Hind" modifier="John Hind" created="201005292130" modified="201403061230" changecount="5">
51705173
<pre>This is like [[Command-line Execution]] except that no command-line is required. Winsh will look for a folder or file with the same name as its own executable and in the same folder, but with the extension {{{.lua}}} rather than {{{.exe}}}. Note that the filename of the Winsh Executable may be changed to reflect the application, allowing more than one script system to exist in the same folder.
51715174

51725175
For example, assuming the following directory layout ({{{myapp.exe}}} being one of the [[Winsh Executables]] renamed):
@@ -5177,11 +5180,11 @@
51775180
Executing {{{myapp.exe}}} will load and run {{{myapp.lua}}}. Alternatively, with the following layout:
51785181
{{{
51795182
C:\test\myapp.exe
5180-
C:\test\myapp\start.lua
5181-
C:\test\myapp\library1.lua
5182-
C:\test\myapp\lib\library2.dll
5183+
C:\test\myapp.lua\start.lua
5184+
C:\test\myapp.lua\library1.lua
5185+
C:\test\myapp.lua\lib\library2.dll
51835186
}}}
5184-
Then executing {{{myapp.exe}}} will load and run {{{myapp\start.lua}}} and that script may contain the following Lua statements:
5187+
Then executing {{{myapp.exe}}} will load and run {{{myapp.lua\start.lua}}} and that script may contain the following Lua statements:
51855188
{{{
51865189
lib1 = require(&quot;library1&quot;)
51875190
lib2 = require(&quot;lib.library2&quot;)
@@ -7687,10 +7690,14 @@
76877690
}}}
76887691
</pre>
76897692
</div>
7690-
<div title="list:insert" creator="John Hind" modifier="John Hind" created="201005152140" modified="201312131731" changecount="6">
7693+
<div title="list:insert" creator="John Hind" modifier="John Hind" created="201005152140" modified="201403241050" changecount="8">
76917694
<pre>!list:insert(index, item)
76927695

7693-
If ''item'' is a List object, the elements in this list are inserted into the list, otherwise, ''item'' is inserted as a single entry. The elements are inserted into the list starting at the given ''index''. Negative indexes are also supported with {{{-1}}} being the last item in the current List, and {{{0}}} meaning to add the new items at the end of the List. The original item at the specified ''index'', and all the subsequent items, are shifted after the inserted items.
7696+
If ''item'' is a List object, the elements in this list are inserted into the list, otherwise, ''item'' is inserted as a single entry.
7697+
7698+
The elements are inserted into the list starting at the given ''index''. Negative indexes are also supported with {{{-1}}} being the last item in the current List, and {{{0}}} representing the index after the last item in the current List. The original item at the specified ''index'', and all the subsequent items, are shifted after the inserted items.
7699+
7700+
Expansion of inserted lists may be overridden for derived classes by providing a {{{__whole}}} metafield. If the object being inserted has this metafield and it tests {{{true}}}, then it is inserted as a single entry, the value being the object itself.
76947701
{{{
76957702
lst = List(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;)
76967703
lst:insert(-2, &quot;one.one&quot;)

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ Packing options are designed to avoid the need for installation and to be locati
1414

1515
A runtime package containing several alternative pre-built binaries and documentation can be downloaded here:
1616

17-
https://github.com/JohnHind/Winsh.lua/releases/tag/2.0.0
18-
1917
The sources on this site can be built using Visual Studio 2010 or later, or probably in any C++ environment with some work. The sources comprise the following:
2018

2119
Patched Lua sources and a project to build these into an object code library.

Winsh/Libraries/LibClass.lua

+15-15
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ do -- Class 'List' (extends partial implementation in C)
169169
if ip < 0 then ip = t + ip end
170170
if ip == 0 then ip = t end
171171
if ip < 1 or ip > t then error("Insert: index out of range") end
172-
if T.istype(v, _C) then
172+
if T.istype(v, _C) and not v.__whole then
173173
local sv = #v
174174
local p = t - ip
175175
if sv <= p then
@@ -194,20 +194,20 @@ do -- Class 'List' (extends partial implementation in C)
194194
self[ip] = v
195195
end
196196
end
197-
function _TID:remove(p1, p2)
198-
T.checkmethod(self, _C)
199-
local t = #self + 1
200-
p1 = T.tonumber(p1 or t-1)
201-
if p1 < 0 then p1 = t + p1 end
202-
if p1 < 1 or p1 >= t then error("Remove: index out of range") end
203-
p2 = T.tonumber(p2 or p1)
204-
if p2 < 0 then p2 = t + p2 end
205-
if p2 < p1 then p2 = p1 end
206-
local d = p2 - p1 + 1
207-
for i=p2+1, t-1 do self[i-d] = self[i] end
208-
for i=t-1, t-d, -1 do self[i] = nil end
209-
end
210-
function _TID:reverse()
197+
function _TID:remove(p1, p2)
198+
T.checkmethod(self, _C)
199+
local t = #self + 1
200+
p1 = T.tonumber(p1 or t-1)
201+
if p1 < 0 then p1 = t + p1 end
202+
if p1 < 1 or p1 >= t then error("Remove: index out of range") end
203+
p2 = T.tonumber(p2 or p1)
204+
if p2 < 0 then p2 = t + p2 end
205+
if p2 < p1 then p2 = p1 end
206+
local d = p2 - p1 + 1
207+
for i=p2+1, t-1 do self[i-d] = self[i] end
208+
for i=t-1, t-d, -1 do self[i] = nil end
209+
end
210+
function _TID:reverse()
211211
T.checkmethod(self, _C)
212212
local e = #self
213213
for i=1, e/2 do

Winsh/Libraries/LibGC.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ WORD GcFirstMenuID = 0; //The first Menu ID allocated when winsh.taskicon fir
1010
WORD GcLastMenuID = 0; //The last Menu ID in the block allocated as above (0 means not done yet)
1111
WORD GcNRCid = 0; //The ID of the Notify Icon Right-click message
1212
WORD GcNLCid = 0; //The ID of the Notify Icon left-click message
13-
int GcRefRMenuTable = LUA_NOREF; //The Registry Table key for the table used to define the Right task icon menu
14-
int GcRefLMenuTable = LUA_NOREF; //The Registry Table key for the table used to define the Left task icon menu
15-
bool m_leftMenu = false; //Is a menu enabled for notify icon left click?
16-
bool m_rightMenu = false; //Is a menu enabled for notify icon right click?
17-
int GcNextKeyID = 1; //The next HotKey ID available for allocation
13+
int GcRefRMenuTable = LUA_NOREF; //The Registry Table key for the table used to define the Right task icon menu
14+
int GcRefLMenuTable = LUA_NOREF; //The Registry Table key for the table used to define the Left task icon menu
15+
bool m_leftMenu = false; //Is a menu enabled for notify icon left click?
16+
bool m_rightMenu = false; //Is a menu enabled for notify icon right click?
17+
int GcNextKeyID = 1; //The next HotKey ID available for allocation
1818
int GcCmdCount = 0; //The number of times winsh.commandline has been used from Lua
1919
int GcRepAct = 0; //Message code for first of two timer messages for setreport.
2020

@@ -115,9 +115,13 @@ int gc_DoPrepMenu(lua_State* L, CMenuHandle m, int mn, WORD* id)
115115
lua_getfield(L, -1, "title"); //|text|submenutab|menutab|...
116116
CString n(lua_tostring(L, -1));
117117
lua_pop(L, 1); //|submenutab|menutab|...
118+
lua_getfield(L, -1, "disabled"); //|da|submenutab|menutab|...
119+
da = lua_toboolean(L, -1);
120+
lua_pop(L, 1); //|submenutab|menutab|...
118121
HICON h = NULL;
119122
CMenuHandle sm; sm.CreatePopupMenu();
120123
UINT f = MF_POPUP; f |= (da? MF_GRAYED : MF_ENABLED);
124+
if (bk) f |= MF_MENUBARBREAK; bk = false;
121125
H->Menu(mn)->AppendCCMenu(m, f, (UINT_PTR)sm.m_hMenu, n, h);
122126
if (!da) gt = gc_DoPrepMenu(L, sm, mn, id); //Recursively call this routine to prepare the sub-menu
123127
lua_pop(L, 1); //|menutab|...
@@ -128,7 +132,7 @@ int gc_DoPrepMenu(lua_State* L, CMenuHandle m, int mn, WORD* id)
128132
lua_getfield(L, -1, "title"); //|text|command|menutab|...
129133
if (lua_isstring(L, -1)) n = CString(lua_tostring(L, -1));
130134
lua_pop(L, 1); //|command|menutab|...
131-
lua_getfield(L, -1, "disabled"); //|df|command|menutab|...
135+
lua_getfield(L, -1, "disabled"); //|da|command|menutab|...
132136
da = lua_toboolean(L, -1);
133137
lua_pop(L, 1); //|command|menutab|...
134138
HICON h = NULL;

Winsh/Libraries/LibGC.lua

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
local T = ...
33
local C = require("class")
44

5-
do -- Class 'Menu' (inherits List)
5+
do -- Class 'Menu' (inherits List methods, but is not a list)
66
local _TID, _PC = C.newmeta(C.List)
77
local _C = function(...)
88
local o = _PC()
9+
C.rawset(o, "disabled", false)
910
for i=1, 3 do
1011
local x = select(i,...)
1112
if not o.title and C.istype(x,'string') then
@@ -19,11 +20,12 @@ do -- Class 'Menu' (inherits List)
1920
C.setmetatable(o, _TID)
2021
return o
2122
end
22-
C.rawset(_TID, "__tostring", function()
23+
C.rawset(_TID, "__tostring", function(self)
2324
return "Menu:" .. (self.title or "anon")
2425
end)
25-
C.rawset(_TID, "__iter", C.pairs)
26+
C.rawset(_TID, "__iter", C.gettid(_PC).__iter)
2627
C.rawset(_TID, "__newindex", C.gettid(_PC).__newindex)
28+
C.rawset(_TID, "__whole", true)
2729
T.Menu = _C
2830
end -- Class 'Menu'
2931

Winsh/Winsh.rc

+11-7
Original file line numberDiff line numberDiff line change
@@ -160,20 +160,24 @@ END
160160
// Icon
161161
//
162162

163-
// Icon with lowest ID value placed first to ensure application icon
164-
// remains consistent on all systems.
163+
// The application icon - must be first in file, compiler sorts
164+
// alphabetically, letters before numbers:
165+
AA.WINSH ICON "res\\lua-std.ico"
166+
167+
// Numbered icons for console commands (menus):
165168
ID_EDIT_DELETE ICON "res\\delete.ico"
166-
WINSH.LUA ICON "res\\lua-std.ico"
167-
LOCK ICON "res\\lock.ico"
168-
LOCK2 ICON "res\\lock48.ico"
169-
KEY ICON "res\\key.ico"
170-
SAFE ICON "res\\safe.ico"
171169
ID_EDIT_CUT ICON "res\\cut.ico"
172170
ID_EDIT_COPY ICON "res\\copy.ico"
173171
ID_EDIT_PASTE ICON "res\\paste.ico"
174172
ID_EDIT_UNDO ICON "res\\undo.ico"
175173
ID_HELP ICON "res\\help.ico"
176174

175+
// Named icons are available to Grunt (freely add or remove):
176+
LOCK ICON "res\\lock.ico"
177+
LOCK2 ICON "res\\lock48.ico"
178+
KEY ICON "res\\key.ico"
179+
SAFE ICON "res\\safe.ico"
180+
177181
/////////////////////////////////////////////////////////////////////////////
178182
//
179183
// LUA

Winsh/Winsh.vcxproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@
8282
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir>
8383
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir>
8484
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
85-
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Win)|Win32'">$(Configuration)\</OutDir>
86-
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Win)|Win32'">$(Configuration)\</OutDir>
85+
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Win)|Win32'">$(SolutionDir)Distro\</OutDir>
86+
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Win)|Win32'">$(SolutionDir)Distro\</OutDir>
8787
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Win)|Win32'">$(Configuration)\</IntDir>
8888
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Win)|Win32'">$(Configuration)\</IntDir>
8989
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release (Max Win)|Win32'">false</LinkIncremental>
9090
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release (Std Win)|Win32'">false</LinkIncremental>
91-
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Con)|Win32'">$(Configuration)\</OutDir>
92-
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Con)|Win32'">$(Configuration)\</OutDir>
91+
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Con)|Win32'">$(SolutionDir)Distro\</OutDir>
92+
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Con)|Win32'">$(SolutionDir)Distro\</OutDir>
9393
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release (Max Con)|Win32'">$(Configuration)\</IntDir>
9494
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release (Std Con)|Win32'">$(Configuration)\</IntDir>
9595
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release (Max Con)|Win32'">false</LinkIncremental>

0 commit comments

Comments
 (0)