doc: Add an UML class diagram like table of cardinalities.

It will help users find how to get some objects from other objects.
This commit is contained in:
Emmanuel Lepage Vallee 2019-06-27 02:14:17 -04:00
parent c48b03ca9c
commit f0bf0df6f0
10 changed files with 715 additions and 1 deletions

View File

@ -82,6 +82,8 @@
* To get all the clients for a screen use either `screen.clients` or
* `screen.tiled_clients`.
*
* @DOC_uml_nav_tables_client_EXAMPLE@
*
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @coreclassmod client
@ -129,7 +131,7 @@
* it is only useful when setting or getting these properties require code to
* executed.
*
* @table awful.object
* @table awful.client.object
*/
/** When a client gains focus.

View File

@ -40,6 +40,8 @@
* Furthermore to the classes described here, one can also use signals as
* described in @{signals}.
*
* @DOC_uml_nav_tables_screen_EXAMPLE@
*
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @coreclassmod screen

View File

@ -178,6 +178,8 @@
* the documentation generation, you get the real signal name by
* removing the starting dot.
*
* @DOC_uml_nav_tables_tag_EXAMPLE@
*
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @coreclassmod tag

View File

@ -0,0 +1,101 @@
--DOC_GEN_OUTPUT --DOC_NO_USAGE --DOC_HIDE_ALL --DOC_ASTERISK --DOC_RAW_OUTPUT --DOC_GEN_IMAGE
local module = ...
module.generate_nav_table {
class = "client",
content = {
{
association = "aggregation",
class = "tag",
to_property = "c.tags",
from_property = "t:clients()",
left = {
msg = "Is tagged on",
card = "1..N",
},
right = {
msg = "Attached to",
card = "0..N",
},
},
{
association = "aggregation",
class = "screen",
to_property = "c.screen",
from_property = "s.clients",
left = {
msg = "Is on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
{
association = "aggregation",
class = "screen",
from_property = "s.hidden_clients",
left = {
msg = "Is on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
{
association = "aggregation",
class = "screen",
from_property = "s.tiled_clients",
left = {
msg = "Is on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
{
association = "aggregation",
class = "awful.key",
to_property = "c:keys()",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Attached to",
card = "0..N",
},
},
{
association = "aggregation",
class = "awful.button",
to_property = "c:buttons()",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Attached to",
card = "0..N",
},
},
{
association = "aggregation",
class = "mouse",
from_property = "mouse.current_client",
left = {
msg = "Is below",
card = "0..1",
},
right = {
msg = "Is over",
card = "0..1",
},
},
}
}

View File

@ -0,0 +1,77 @@
Core components relationship
===
<table><tr>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire other objects from a client</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client1.svg"></td>
<td>c.tags</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client2.svg"></td>
<td>c.screen</td>
</tr>
<tr>
<td>awful.key</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client3.svg"></td>
<td>c:keys()</td>
</tr>
<tr>
<td>awful.button</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client4.svg"></td>
<td>c:buttons()</td>
</tr>
</table></td>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire a client from other objects</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client5.svg"></td>
<td>t:clients()</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client6.svg"></td>
<td>s.clients</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client7.svg"></td>
<td>s.hidden_clients</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client8.svg"></td>
<td>s.tiled_clients</td>
</tr>
<tr>
<td>mouse</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_client9.svg"></td>
<td>mouse.current_client</td>
</tr>
</table></td>
</tr><tr>
<td colspan=2 style="color:#00000044">
<b>Legend:</b> <i>c</i>: a client object, <i>t</i>: a tag object,
<i>s</i>: a screen object, <i>k</i>: an awful.key object,
<i>b</i>: a awful.button object, <i>n</i>: a naughty.notification object
</td>
</tr>
</table>

View File

@ -0,0 +1,101 @@
--DOC_GEN_OUTPUT --DOC_NO_USAGE --DOC_HIDE_ALL --DOC_ASTERISK --DOC_RAW_OUTPUT --DOC_GEN_IMAGE
local module = ...
module.generate_nav_table {
class = "screen",
content = {
{
association = "aggregation",
class = "tag",
to_property = "s.tags",
from_property = "t.screen",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Attached to",
card = "1..1",
},
},
{
association = "composition",
class = "tag",
to_property = "s.selected_tag",
left = {
msg = "Has",
card = "0..1",
},
right = {
msg = "Is on",
card = "1..1",
},
},
{
association = "composition",
class = "tag",
to_property = "s.selected_tags",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Is on",
card = "1..1",
},
},
{
association = "aggregation",
class = "client",
from_property = "c.screen",
to_property = "s.clients",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Is on",
card = "1..1",
},
},
{
association = "aggregation",
class = "client",
to_property = "s.hidden_clients",
left = {
msg = "Has",
card = "1..1",
},
right = {
msg = "Is on",
card = "1..1",
},
},
{
association = "aggregation",
class = "client",
to_property = "s.tiled_clients",
left = {
msg = "Has",
card = "0..N",
},
right = {
msg = "Has",
card = "1..1",
},
},
{
association = "aggregation",
class = "naughty.notification",
from_property = "n.screen",
left = {
msg = "Displays",
card = "0..N",
},
right = {
msg = "Is displayed on",
card = "1..N",
},
},
}
}

View File

@ -0,0 +1,77 @@
Core components relationship
===
<table><tr>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire other objects from a screen</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen1.svg"></td>
<td>s.tags</td>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen2.svg"></td>
<td>s.selected_tag</td>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen3.svg"></td>
<td>s.selected_tags</td>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen4.svg"></td>
<td>s.clients</td>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen5.svg"></td>
<td>s.hidden_clients</td>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen6.svg"></td>
<td>s.tiled_clients</td>
</tr>
</table></td>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire a screen from other objects</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>tag</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen7.svg"></td>
<td>t.screen</td>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen8.svg"></td>
<td>c.screen</td>
</tr>
<tr>
<td>naughty.notification</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_screen9.svg"></td>
<td>n.screen</td>
</tr>
</table></td>
</tr><tr>
<td colspan=2 style="color:#00000044">
<b>Legend:</b> <i>c</i>: a client object, <i>t</i>: a tag object,
<i>s</i>: a screen object, <i>k</i>: an awful.key object,
<i>b</i>: a awful.button object, <i>n</i>: a naughty.notification object
</td>
</tr>
</table>

View File

@ -0,0 +1,62 @@
--DOC_GEN_OUTPUT --DOC_NO_USAGE --DOC_HIDE_ALL --DOC_ASTERISK --DOC_RAW_OUTPUT --DOC_GEN_IMAGE
local module = ...
module.generate_nav_table {
class = "tag",
content = {
{
association = "aggregation",
class = "client",
from_property = "c.tags",
to_property = "t:clients()",
right = {
msg = "Is tagged on",
card = "1..N",
},
left = {
msg = "Has",
card = "0..N",
},
},
{
association = "composition",
class = "screen",
to_property = "t.screen",
from_property = "s.tags",
left = {
msg = "Is displayed on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
{
association = "composition",
class = "screen",
from_property = "s.selected_tag",
left = {
msg = "Is on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
{
association = "composition",
class = "screen",
from_property = "s.selected_tags",
left = {
msg = "Is on",
card = "1..1",
},
right = {
msg = "Has",
card = "0..N",
},
},
}
}

View File

@ -0,0 +1,62 @@
Core components relationship
===
<table><tr>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire other objects from a tag</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag1.svg"></td>
<td>t:clients()</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag2.svg"></td>
<td>t.screen</td>
</tr>
</table></td>
<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>Acquire a tag from other objects</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>
<tr>
<td>client</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag3.svg"></td>
<td>c.tags</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag4.svg"></td>
<td>s.tags</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag5.svg"></td>
<td>s.selected_tag</td>
</tr>
<tr>
<td>screen</td>
<td><img src="../images/AUTOGEN_uml_nav_tables_tag6.svg"></td>
<td>s.selected_tags</td>
</tr>
</table></td>
</tr><tr>
<td colspan=2 style="color:#00000044">
<b>Legend:</b> <i>c</i>: a client object, <i>t</i>: a tag object,
<i>s</i>: a screen object, <i>k</i>: an awful.key object,
<i>b</i>: a awful.button object, <i>n</i>: a naughty.notification object
</td>
</tr>
</table>

View File

@ -0,0 +1,228 @@
local file_path, image_path = ...
require("_common_template")(...)
local cairo = require("lgi").cairo
local shape = require("gears.shape")
local wibox = require("wibox")
local beautiful = require("beautiful")
-- Make the path relative.
image_path = "../" .. image_path:match("/(images/[^/]+)$")
-- This template generates an HTML table with how other classes are associated
-- with a given class.
local function gen_class(name)
return wibox.widget {
{
{
{
valign = "center",
align = "center",
markup = "<b>"..name.."</b>",
widget = wibox.widget.textbox
},
fg = "#ffffff",
bg = beautiful.bg_normal,
widget = wibox.container.background,
},
nil,
nil,
widget = wibox.layout.align.vertical,
},
shape = function(cr,w,h)
shape.partially_rounded_rect(cr,w,h, true,true,false,false,5)
end,
forced_width = 75,
border_width = 1,
border_strategy = "inner",
border_color = beautiful.border_color,
bg = "#00000000",
widget = wibox.container.background
}
end
local function gen_arrow(association)
local w = wibox.widget.base.make_widget()
function w:fit(_, width, _)
return width, 15
end
function w:draw(_, cr, width, height)
cr:set_line_width(1.5)
cr:move_to(0, height/2)
cr:line_to(width-(association == "association" and 0 or 40), height/2)
cr:stroke()
if association ~= "association" then
cr:set_antialias(cairo.ANTIALIAS_SUBPIXEL)
cr:set_line_width(1)
cr:translate(0,2)
width, height = width-2, height-4
cr:move_to(width-40, height/2)
cr:line_to(width-20, 0 )
cr:line_to(width , height/2)
cr:line_to(width-20, height )
cr:line_to(width-40, height/2)
cr:close_path()
if association == "composition" then
cr:fill()
else
cr:stroke()
end
end
end
w.forced_height = 15
return w
end
local function arrow_widget(dir)
local w = wibox.widget.base.make_widget()
function w:fit(_, width, _)
return width, 5
end
function w:draw(_, cr, width, height)
cr:translate(10, 0)
width = width - 20
cr:set_source_rgba(0,0,0,0.2)
cr:set_line_width(1)
cr:move_to(0, height/2)
cr:line_to(width,height/2)
cr:stroke()
if dir == "left" then
cr:move_to(height/2, 0)
cr:line_to(0, height/2)
cr:line_to(height/2, height)
cr:stroke()
else
cr:move_to(width-height/2, 0)
cr:line_to(width, height/2)
cr:line_to(width-height/2, height)
cr:stroke()
end
end
return w
end
local function gen_table_uml(entry, class1, class2, revert)
local left = revert and entry.right or entry.left
local right = revert and entry.left or entry.right
return wibox.widget {
gen_class(class2),
{
{
{
text = " "..left.card,
widget = wibox.widget.textbox
},
arrow_widget "left",
{
wrap = "char",
markup = left.msg.."<span alpha='1'> .</span>",
widget = wibox.widget.textbox
},
spacing = 5,
layout = wibox.layout.align.horizontal
},
gen_arrow(entry.composition),
{
{
wrap = "char",
markup = right.msg.."<span alpha='1'> .</span>",
widget = wibox.widget.textbox
},
arrow_widget "right",
{
text = right.card.." ",
widget = wibox.widget.textbox
},
spacing = 5,
layout = wibox.layout.align.horizontal
},
layout = wibox.layout.fixed.vertical,
},
gen_class(class1),
layout = wibox.layout.align.horizontal
}
end
local map = {
to = function(o) return "Acquire other objects from a "..o end,
from = function(o) return "Acquire a "..o.." from other objects" end
}
local function gen_table_header(title, o)
print([[<td valign="top"><table class='widget_list' border=1>
<colgroup span="3"></colgroup>
<tr><th align='center' colspan=3 scope=colgroup>]]..map[title](o)..[[</th></tr>
<tr style='font-weight: bold;'>
<th align='center'>Class</th>
<th align='center'></th>
<th align='center'>Property</th>
</tr>]])
end
local function get_table_row(path, class, prop)
print([[<tr>
<td>]].. class ..[[</td>
<td><img src="]]..path..[["></td>
<td>]].. prop ..[[</td>
</tr>]])
end
local function get_table_footer()
print '</table></td>'
end
local module = {}
local counter = 1
function module.generate_nav_table(t)
assert(t.content and t.class)
print("\n\nCore components relationship\n===\n")
print '<table><tr>'
-- Validate early to avoid debugging cryptic backtraces.
for _, tab in ipairs {"to", "from"} do
gen_table_header(tab, t.class)
for _, entry in ipairs(t.content) do
if entry[tab.."_property"] then
assert(entry.left and entry.right and entry.association)
assert(entry.class)
assert(entry.left.msg and entry.left.card)
assert(entry.right.msg and entry.right.card)
local path = image_path..counter..".svg"
local widget = gen_table_uml(entry, t.class, entry.class, false)
wibox.widget.draw_to_svg_file(widget, path, 320, 50)
get_table_row(path, entry.class, entry[tab.."_property"])
counter = counter + 1
end
end
get_table_footer()
end
print([[</tr><tr>
<td colspan=2 style="color:#00000044">
<b>Legend:</b> <i>c</i>: a client object, <i>t</i>: a tag object,
<i>s</i>: a screen object, <i>k</i>: an awful.key object,
<i>b</i>: a awful.button object, <i>n</i>: a naughty.notification object
</td>
</tr>
</table>]])
end
loadfile(file_path)(module)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80