HTML-AHK radial menus
This technique allows you to use the power of AutoHotkey combined with Javascript, HTML, CSS and GDI+. There are many HTML/CSS/JS based radial menus/circular navigation bars on the web. This technique shows how to "get them out of browser" and combine with AutoHotkey. You can also insert HTML UI in such radial menus; on/off switches, text areas, sliders, etc. Here is the picture which explains the drawing process and the scripts (unpolished & hardcoded for now). You'll have to include Gdip.ahk in the script. Pressing F1 shows/hides menu. Tested on Windows 10.
Pie type
Code: Select all
/*==Description=========================================================================
HTML-AHK pie type radial menu example by Learning one
https://autohotkey.com/boards/viewtopic.php?p=74494#p74494
Press F1 to show/hide menu. Tested on Windows 10.
*/
;===Auto-execute========================================================================
html =
(`%
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><meta http-equiv="X-UA-Compatible" content="IE=Edge"></head>
<style>
.SVGRM {
width: 200px;
height: 200px;
fill: #6666aa;
/* border: 1px solid red; */
}
.SVGArc:hover {
fill: #7777ff;
}
.ArcText {
width: 50px;
height: 50px;
position: fixed;
text-align: center;
align-items: center;
display: flex;
justify-content: center;
font-size: 11px;
font-family: Arial, Helvetica, sans-serif;
margin: 0px;
padding: 0px;
position: fixed;
color: white;
pointer-events: none;
/* border: 1px solid red; */
}
</style>
<svg class="SVGRM" viewBox="0 0 200 200" transform="translate(111,111)">
<g transform="translate(-7,-7)">
<ellipse class="SVGArc" id="SVGArc0" cx="100" cy="100" rx="33" ry="33"
/>
<path class="SVGArc" id="SVGArc1" d="m 0.99999372,95.680191 c 0,-1.1579 0.27259638,-4.43539 0.60581058,-7.283324 C 4.9151368,60.108904 20.32805,34.587891 43.916474,18.337932 c 2.12355,-1.462923 4.018697,-2.659734 4.211421,-2.659734 0.192832,0 7.181311,11.831985 15.529833,26.293212 l 15.179403,26.293312 -1.164824,0.827442 c -1.90376,1.352538 -6.47264,5.859909 -8.149007,8.039394 -3.605046,4.686858 -6.361592,11.305107 -7.255859,17.420633 l -0.472913,3.23314 -30.397208,0 -30.39732628,0 0,-2.10514 z"
/>
<path class="SVGArc" id="SVGArc2" d="M 67.787572,39.550563 C 59.474859,25.144479 52.673658,13.236561 52.673658,13.088556 c 0,-0.46233 9.611564,-4.8526829 13.993274,-6.3918359 25.027428,-8.7914971 51.896518,-7.3728271 76.071828,4.0166279 2.4988,1.177209 4.48164,2.322243 4.40629,2.544498 -0.0759,0.222255 -6.8966,12.127104 -15.15844,26.455275 -10.99449,19.067401 -15.18246,26.001658 -15.62217,25.866721 -0.3305,-0.101376 -1.85334,-0.656667 -3.38423,-1.234035 -8.36358,-3.154635 -18.716008,-3.065535 -26.805526,0.23067 -1.571565,0.640332 -2.950982,1.164933 -3.065297,1.165725 -0.114434,7.92e-4 -7.00921,-11.785455 -15.321815,-26.191639 z"
/>
<path class="SVGArc" id="SVGArc3" d="m 137.99517,97.437351 c 0,-0.19147 -0.26455,-1.85863 -0.5879,-3.70488 -0.64785,-3.69894 -2.01377,-8.007911 -3.41527,-10.774169 -2.35186,-4.642011 -7.0943,-10.244718 -11.58558,-13.687047 L 121.03801,68.22235 136.2029,41.950224 c 8.34059,-14.449644 15.28738,-26.272026 15.43716,-26.272026 0.58133,0 6.37383,4.019895 10.18916,7.071174 16.82779,13.457862 29.17393,32.758408 34.19374,53.454358 1.48217,6.111072 2.3472,11.636658 2.70433,17.275991 l 0.2727,4.30561 -30.50235,0 c -17.00272,0 -30.50247,-0.15404 -30.50247,-0.34798 z"
/>
<path class="SVGArc" id="SVGArc4" d="m 136.47912,158.51193 c -8.19284,-14.18254 -14.99654,-26.04809 -15.11934,-26.36796 -0.1422,-0.37045 0.34849,-0.97792 1.35108,-1.6726 2.23186,-1.54648 6.84176,-6.42342 8.74857,-9.25541 3.15412,-4.68448 5.13707,-9.77368 6.12549,-15.72051 l 0.48265,-2.90377 30.46451,0 30.4644,0 -0.27407,4.10533 c -1.23076,18.43747 -7.91413,36.72594 -18.94817,51.84987 -4.47416,6.13255 -10.41734,12.44163 -16.39169,17.40083 -3.87062,3.21305 -11.03472,8.35065 -11.64449,8.35065 -0.19952,0 -7.06609,-11.60389 -15.25894,-25.78643 z"
/>
<path class="SVGArc" id="SVGArc5" d="m 91.528941,198.66633 c -5.803598,-0.46886 -14.215905,-2.06157 -19.754163,-3.74012 -8.682073,-2.63132 -19.36647,-7.35619 -18.970153,-8.38896 0.188536,-0.49114 29.863242,-51.96362 30.110118,-52.22755 0.06346,-0.0683 1.222492,0.34244 2.575505,0.91189 8.633909,3.6335 19.496972,3.69765 28.384452,0.1676 1.64544,-0.65349 3.03595,-1.13602 3.08988,-1.07217 0.31905,0.37749 30.24381,52.38308 30.24381,52.56 0,0.36224 -6.14419,3.33006 -10.42211,5.03415 -14.34949,5.71606 -29.72094,8.01048 -45.257339,6.75516 z"
/>
<path class="SVGArc" id="SVGArc6" d="M 43.861064,181.62358 C 23.027503,167.13206 8.6887689,145.8725 3.2537286,121.41624 2.1250494,116.33714 0.99999372,107.99579 0.99999372,104.70632 l 0,-2.11464 30.41884928,0 30.418849,0 0.255262,1.90248 c 0.809978,6.03514 3.442576,12.84308 6.751582,17.46014 1.757488,2.45203 6.601221,7.35233 8.830256,8.93317 l 1.16721,0.82783 -15.182235,26.29153 c -8.350224,14.46034 -15.364652,26.2853 -15.587728,26.27757 -0.223087,-0.01 -2.118006,-1.20502 -4.210975,-2.66082 z"
/>
/>
</svg>
<p class="ArcText" id="ArcText1" style="top: 42px; left: 18px;">Notepad</p>
<p class="ArcText" id="ArcText2" style="top: 9px; left: 75px;">Calc</p>
<p class="ArcText" id="ArcText3" style="top: 42px; left: 132px;">Change style</p>
<p class="ArcText" id="ArcText4" style="top: 108px; left: 132px;">Item 4</p>
<p class="ArcText" id="ArcText5" style="top: 141px; left: 75px;">Item 5</p>
<p class="ArcText" id="ArcText6" style="top: 108px; left: 18px;">Item 6</p>
<p class="ArcText" id="ArcText0" style="top: 75px; left: 75px;">x</p>
</body></html>
)
Size := 202, SizeAdd := 216
;=== ActiveX, WinSet Region ===
Gui, New, +HwndhGui
Gui %hGui%: +ToolWindow -Caption +AlwaysOnTop
Gui %hGui%:Add, ActiveX, x0 y0 w%Size% h%Size% vwb, about:<!DOCTYPE html><meta http-equiv="X-UA-Compatible" content="IE=edge">
document := WB.Document
document.write(html)
DetectHiddenWindows, on
WinSet, Region, % "0-0 W" Size+1 " H" Size+1 " E", % "ahk_id " hGui
Gui %hGui%:Show, w%Size% h%Size% hide
ComObjConnect(document, "document_")
;=== GDI+ ===
Gui, New, +HwndhLayeredWin
Gui %hLayeredWin%:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui %hLayeredWin%:Show, hide
WinSet, ExStyle, +0x20, % "ahk_id " hLayeredWin ; click through style
pToken := Gdip_Startup()
hbm := CreateDIBSection(SizeAdd, SizeAdd), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4)
;Paint
pBrush := Gdip_BrushCreateSolid(0xffffffff)
Gdip_FillEllipse(G, pBrush, 1, 1, SizeAdd-3, SizeAdd-3)
Gdip_DeleteBrush(pBrush)
pPen := Gdip_CreatePen(0xff6666aa, 4)
Gdip_DrawEllipse(G, pPen, 2, 2, SizeAdd-5, SizeAdd-5)
Gdip_DeletePen(pPen)
;Update, Delete, Shutdown
UpdateLayeredWindow(hLayeredWin, hdc, (A_ScreenWidth-SizeAdd)//2, (A_ScreenHeight-SizeAdd)//2, SizeAdd, SizeAdd)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
;=== Show ===
ToggleShowMenu()
Return
;===Hotkeys=============================================================================
F1::ToggleShowMenu()
Escape::ExitApp
;===Functions===========================================================================
#Include Gdip_All.ahk ; credits: Tic, Rseding91, fincs. http://www.autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-72#entry533310
document_OnClick(document) {
SelectedArcId := document.parentWindow.event.srcElement.id ; example: "SVGArc6"
SelectedArcNum := SubStr(SelectedArcId, 7) ; example: "6"
ArcText := document.getElementById("ArcText" SelectedArcNum).innerHTML
if (ArcText = "Notepad") {
Run, Notepad
ToggleShowMenu()
}
else if (ArcText = "Calc") {
Run, Calc
ToggleShowMenu()
}
else if (ArcText = "x") {
ToggleShowMenu()
}
else if (ArcText = "Change style") {
NewFontStyle := (document.getElementById("ArcText" SelectedArcNum).style.fontStyle = "italic") ? "normal" : "italic"
document.getElementById("ArcText" SelectedArcNum).style.fontStyle := NewFontStyle
}
}
ToggleShowMenu() {
global hLayeredWin, hGui, Size, SizeAdd
if (DllCall("IsWindowVisible", A_PtrSize ? "Ptr" : "UInt", hGui) = 1) {
Gui %hLayeredWin%:Hide
Gui %hGui%:Hide
}
else {
CoordMode, Mouse, Screen
MouseGetPos, x,y
Gui %hLayeredWin%:Show, % "x" x-Round(SizeAdd/2) " y" y-Round(SizeAdd/2) " NA"
Gui %hGui%:Show, % "x" x-Round(Size/2) " y" y-Round(Size/2) " NA"
}
}
Code: Select all
/*==Description=========================================================================
HTML-AHK circle type radial menu example by Learning one
https://autohotkey.com/boards/viewtopic.php?p=74494#p74494
Press F1 to show/hide menu. Tested on Windows 10.
*/
;===Auto-execute========================================================================
html =
(`%
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><meta http-equiv="X-UA-Compatible" content="IE=Edge"></head>
<style>
body {
background-color: #6666aa;
}
.button {
width: 60px;
height: 60px;
padding: 0px;
text-align: center;
font-size: 11px;
margin: 2px;
cursor: pointer;
position: fixed;
background-color: #6666aa;
color: #ffffff;
border: 4px solid #ffffff;
border-radius: 50%;
box-shadow: 0px 0px 8px #111111;
}
.button:hover {
background-color: #7777ff;
}
.Central {
border: 0px;
box-shadow: none;
}
</style>
<body>
<button class="button Central" style="top: 105px; left: 105px;">x</button>
<button class="button" style="top: 105px; left: 51px;">Item</button>
<button class="button" style="top: 152px; left: 78px;">Item</button>
<button class="button" style="top: 152px; left: 132px;">Item</button>
<button class="button" style="top: 105px; left: 159px;">Change style</button>
<button class="button" style="top: 58px; left: 132px;">Notepad</button>
<button class="button" style="top: 58px; left: 78px;">Calc</button>
<button class="button" style="top: 105px; left: 1px;">Item</button>
<button class="button" style="top: 157px; left: 15px;">Item</button>
<button class="button" style="top: 195px; left: 53px;">Item</button>
<button class="button" style="top: 209px; left: 105px;">Item</button>
<button class="button" style="top: 195px; left: 157px;">Item</button>
<button class="button" style="top: 157px; left: 195px;">Item</button>
<button class="button" style="top: 105px; left: 209px;">Item</button>
<button class="button" style="top: 53px; left: 195px;">Item</button>
<button class="button" style="top: 15px; left: 157px;">Item</button>
<button class="button" style="top: 1px; left: 105px;">Item</button>
<button class="button" style="top: 15px; left: 53px;">Item</button>
<button class="button" style="top: 53px; left: 15px;">Item</button>
</body>
</html>
)
;=== ActiveX, WinSet Region ===
Gui, New, +HwndhGui
Gui %hGui%: +ToolWindow -Caption +AlwaysOnTop
Gui %hGui%:Add, ActiveX, x2 y2 w276 h276 vwb, about:<!DOCTYPE html><meta http-equiv="X-UA-Compatible" content="IE=edge">
Gui %hGui%:Color, 6666aa
document := wb.Document
document.write(html)
DetectHiddenWindows, on
WinSet, Region, 2-2 W276 H276 E, % "ahk_id " hGui
Gui %hGui%:Show, w280 w280 hide
ComObjConnect(document, "document_")
;=== GDI+ ===
Gui, New, +HwndhLayeredWin
Gui %hLayeredWin%:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui %hLayeredWin%:Show, hide
WinSet, ExStyle, +0x20, % "ahk_id " hLayeredWin ; click through style
w := 308, h := w
pToken := Gdip_Startup()
hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4)
;Paint
pBrush := Gdip_BrushCreateSolid(0xff6666aa)
Gdip_FillEllipse(G, pBrush, 4, 4, w-10, h-10)
Gdip_DeleteBrush(pBrush)
pPen := Gdip_CreatePen(0xffffffff, 4)
Gdip_DrawEllipse(G, pPen, 11, 11, w-24, h-24)
Gdip_DeletePen(pPen)
;Update, Delete, Shutdown
UpdateLayeredWindow(hLayeredWin, hdc, (A_ScreenWidth-w)//2, (A_ScreenHeight-h)//2, w, h)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
;=== Show ===
ToggleShowMenu()
Return
;===Hotkeys=============================================================================
F1::ToggleShowMenu()
Escape::ExitApp
;===Functions===========================================================================
#Include Gdip_All.ahk ; credits: Tic, Rseding91, fincs. http://www.autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-72#entry533310
document_OnClick(document) {
InnerHTML := document.parentWindow.event.srcElement.innerHTML
if (InnerHTML = "Notepad") {
Run, Notepad
ToggleShowMenu()
}
else if (InnerHTML = "Calc") {
Run, Calc
ToggleShowMenu()
}
else if (InnerHTML = "x") {
ToggleShowMenu()
}
else if (InnerHTML = "Change style") {
NewFontStyle := (document.parentWindow.event.srcElement.style.fontStyle = "italic") ? "normal" : "italic"
document.parentWindow.event.srcElement.style.fontStyle := NewFontStyle
}
}
ToggleShowMenu() {
global hLayeredWin, hGui, w, h
if (DllCall("IsWindowVisible", A_PtrSize ? "Ptr" : "UInt", hGui) = 1) {
Gui %hLayeredWin%:Hide
Gui %hGui%:Hide
}
else {
CoordMode, Mouse, Screen
MouseGetPos, x,y
Gui %hLayeredWin%:Show, % "x" x-w/2 " y" y-h/2 " NA"
Gui %hGui%:Show, % "x" x-140 " y" y-140 " NA"
}
}