{"id":29668079,"url":"https://github.com/yuce/tk9.0","last_synced_at":"2025-10-06T04:23:19.906Z","repository":{"id":299887884,"uuid":"1004446778","full_name":"yuce/tk9.0","owner":"yuce","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-18T19:50:22.000Z","size":225611,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"openbsd","last_synced_at":"2025-06-18T20:39:46.239Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-18T16:26:58.000Z","updated_at":"2025-06-18T19:50:25.000Z","dependencies_parsed_at":"2025-06-18T20:50:03.861Z","dependency_job_id":null,"html_url":"https://github.com/yuce/tk9.0","commit_stats":null,"previous_names":["yuce/tk9.0"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yuce/tk9.0","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Ftk9.0","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Ftk9.0/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Ftk9.0/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Ftk9.0/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuce","download_url":"https://codeload.github.com/yuce/tk9.0/tar.gz/refs/heads/openbsd","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Ftk9.0/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266535695,"owners_count":23944275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-22T17:05:59.109Z","updated_at":"2025-10-06T04:23:19.814Z","avatar_url":"https://github.com/yuce.png","language":"Go","funding_links":["https://liberapay.com/jnml/donate"],"categories":[],"sub_categories":[],"readme":"# tk9.0: The CGo-free, cross platform GUI toolkit for Go\n\n[![LiberaPay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/jnml/donate)\n[![receives](https://img.shields.io/liberapay/receives/jnml.svg?logo=liberapay)](https://liberapay.com/jnml/donate)\n[![patrons](https://img.shields.io/liberapay/patrons/jnml.svg?logo=liberapay)](https://liberapay.com/jnml/donate)\n\n![photo](_examples/photo.png \"photo\")\n\nUsing Go embedded images (_examples/photo.go).\n\n     1\tpackage main\n     2\t\n     3\timport _ \"embed\"\n     4\timport . \"modernc.org/tk9.0\"\n     5\timport _ \"modernc.org/tk9.0/themes/azure\"\n     6\t\n     7\t//go:embed gopher.png\n     8\tvar gopher []byte\n     9\t\n    10\tfunc main() {\n    11\t\tActivateTheme(\"azure light\")\n    12\t\tPack(Label(Image(NewPhoto(Data(gopher)))),\n    13\t\t\tTExit(),\n    14\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    15\t\tApp.Center().Wait()\n    16\t}\n\n![menu](_examples/menu.png \"menu\")\n\nCascading menus (_examples/menu.go)\n\n     1\tpackage main\n     2\t\n     3\timport (\n     4\t\t\"fmt\"\n     5\t\t. \"modernc.org/tk9.0\"\n     6\t\t_ \"modernc.org/tk9.0/themes/azure\"\n     7\t\t\"runtime\"\n     8\t)\n     9\t\n    10\tfunc main() {\n    11\t\tmenubar := Menu()\n    12\t\n    13\t\tfileMenu := menubar.Menu()\n    14\t\tfileMenu.AddCommand(Lbl(\"New\"), Underline(0), Accelerator(\"Ctrl+N\"))\n    15\t\tfileMenu.AddCommand(Lbl(\"Open...\"), Underline(0), Accelerator(\"Ctrl+O\"), Command(func() { GetOpenFile() }))\n    16\t\tBind(App, \"\u003cControl-o\u003e\", Command(func() { fileMenu.Invoke(1) }))\n    17\t\tfileMenu.AddCommand(Lbl(\"Save\"), Underline(0), Accelerator(\"Ctrl+S\"))\n    18\t\tfileMenu.AddCommand(Lbl(\"Save As...\"), Underline(5))\n    19\t\tfileMenu.AddCommand(Lbl(\"Close\"), Underline(0), Accelerator(\"Crtl+W\"))\n    20\t\tfileMenu.AddSeparator()\n    21\t\tfileMenu.AddCommand(Lbl(\"Exit\"), Underline(1), Accelerator(\"Ctrl+Q\"), ExitHandler())\n    22\t\tBind(App, \"\u003cControl-q\u003e\", Command(func() { fileMenu.Invoke(6) }))\n    23\t\tmenubar.AddCascade(Lbl(\"File\"), Underline(0), Mnu(fileMenu))\n    24\t\n    25\t\teditMenu := menubar.Menu()\n    26\t\teditMenu.AddCommand(Lbl(\"Undo\"))\n    27\t\teditMenu.AddSeparator()\n    28\t\teditMenu.AddCommand(Lbl(\"Cut\"))\n    29\t\teditMenu.AddCommand(Lbl(\"Copy\"))\n    30\t\teditMenu.AddCommand(Lbl(\"Paste\"))\n    31\t\teditMenu.AddCommand(Lbl(\"Delete\"))\n    32\t\teditMenu.AddCommand(Lbl(\"Select All\"))\n    33\t\tmenubar.AddCascade(Lbl(\"Edit\"), Underline(0), Mnu(editMenu))\n    34\t\n    35\t\thelpMenu := menubar.Menu()\n    36\t\thelpMenu.AddCommand(Lbl(\"Help Index\"))\n    37\t\thelpMenu.AddCommand(Lbl(\"About...\"))\n    38\t\tmenubar.AddCascade(Lbl(\"Help\"), Underline(0), Mnu(helpMenu))\n    39\t\n    40\t\tApp.WmTitle(fmt.Sprintf(\"%s on %s\", App.WmTitle(\"\"), runtime.GOOS))\n    41\t\tActivateTheme(\"azure light\")\n    42\t\tApp.Configure(Mnu(menubar), Width(\"8c\"), Height(\"6c\")).Wait()\n    43\t}\n\nMenus on darwin are now using the system-managed menu bar.    \n\n![text](_examples/text.png \"text\")\n\nRich text using markup (_examples/text.go).\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\tfunc main() {\n     7\t\tActivateTheme(\"azure light\")\n     8\t\tvar scroll *TScrollbarWidget\n     9\t\tt := Text(Font(\"helvetica\", 10), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }), Setgrid(true), Wrap(\"word\"), Padx(\"2m\"), Pady(\"2m\"))\n    10\t\tscroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))\n    11\t\tGrid(t, Sticky(\"news\"), Pady(\"2m\"))\n    12\t\tGrid(scroll, Row(0), Column(1), Sticky(\"nes\"), Pady(\"2m\"))\n    13\t\tGridRowConfigure(App, 0, Weight(1))\n    14\t\tGridColumnConfigure(App, 0, Weight(1))\n    15\t\tGrid(TExit(), Padx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    16\t\tt.TagConfigure(\"bgstipple\", Background(Black), Borderwidth(0), Bgstipple(Gray12))\n    17\t\tt.TagConfigure(\"big\", Font(\"helvetica\", 12, \"bold\"))\n    18\t\tt.TagConfigure(\"bold\", Font(\"helvetica\", 10, \"bold\", \"italic\"))\n    19\t\tt.TagConfigure(\"center\", Justify(\"center\"))\n    20\t\tt.TagConfigure(\"color1\", Background(\"#a0b7ce\"))\n    21\t\tt.TagConfigure(\"color2\", Foreground(Red))\n    22\t\tt.TagConfigure(\"margins\", Lmargin1(\"12m\"), Lmargin2(\"6m\"), Rmargin(\"10m\"))\n    23\t\tt.TagConfigure(\"overstrike\", Overstrike(1))\n    24\t\tt.TagConfigure(\"raised\", Relief(\"raised\"), Borderwidth(1))\n    25\t\tt.TagConfigure(\"right\", Justify(\"right\"))\n    26\t\tt.TagConfigure(\"spacing\", Spacing1(\"10p\"), Spacing2(\"2p\"), Lmargin1(\"12m\"), Lmargin2(\"6m\"), Rmargin(\"10m\"))\n    27\t\tt.TagConfigure(\"sub\", Offset(\"-2p\"), Font(\"helvetica\", 8))\n    28\t\tt.TagConfigure(\"sunken\", Relief(\"sunken\"), Borderwidth(1))\n    29\t\tt.TagConfigure(\"super\", Offset(\"4p\"), Font(\"helvetica\", 8))\n    30\t\tt.TagConfigure(\"tiny\", Font(\"times\", 8, \"bold\"))\n    31\t\tt.TagConfigure(\"underline\", Underline(1))\n    32\t\tt.TagConfigure(\"verybig\", Font(CourierFont(), 22, \"bold\"))\n    33\t\tt.InsertML(`Text widgets like this one allow you to display information in a variety of styles. Display styles are controlled\n    34\tusing a mechanism called \u003cbold\u003etags\u003c/bold\u003e. Tags are just textual names that you can apply to one or more ranges of characters within a\n    35\ttext widget. You can configure tags with various display styles. If you do this, then the tagged characters will be displayed with the\n    36\tstyles you chose. The available display styles are:\n    37\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e1. Font.\u003c/big\u003e You can choose any system font, \u003cverybig\u003elarge\u003c/verybig\u003e or \u003ctiny\u003esmall\u003c/tiny\u003e.\n    38\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e2. Color.\u003c/big\u003e You can change either the \u003ccolor1\u003ebackground\u003c/color1\u003e or \u003ccolor2\u003eforeground\u003c/color2\u003e color, or\n    39\t\u003ccolor1\u003e\u003ccolor2\u003eboth\u003c/color2\u003e\u003c/color1\u003e.\n    40\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e3. Stippling.\u003c/big\u003e You can cause the \u003cbgstipple\u003ebackground\u003c/bgstipple\u003e information to be drawn with a stipple fill instead\n    41\tof a solid fill.\n    42\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e4. Underlining.\u003c/big\u003e You can \u003cunderline\u003eunderline\u003c/underline\u003e ranges of text.\n    43\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e5. Overstrikes.\u003c/big\u003e You can \u003coverstrike\u003edraw lines through\u003c/overstrike\u003e ranges of text.\n    44\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e6. 3-D effects.\u003c/big\u003e You can arrange for the background to be drawn with a border that makes characters appear either\n    45\t\u003craised\u003eraised\u003c/raised\u003e or \u003csunken\u003esunken\u003c/sunken\u003e.\n    46\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e7. Justification.\u003c/big\u003e You can arrange for lines to be displayed \u003cbr\u003eleft-justified \u003cbr\u003e\u003cright\u003eright-justified, or\u003c/right\u003e\n    47\t\u003cbr\u003e\u003ccenter\u003ecentered.\u003c/center\u003e\n    48\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e8. Superscripts and subscripts.\u003c/big\u003e You can control the vertical position of text to generate superscript effects like\n    49\t10\u003csuper\u003en\u003c/super\u003e or subscript effects like X\u003csub\u003ei\u003c/sub\u003e.\n    50\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e9. Margins.\u003c/big\u003e You can control the amount of extra space left on each side of the text\n    51\t\u003cbr\u003e\u003cbr\u003e\u003cmargins\u003eThis paragraph is an example of the use of margins. It consists of a single line of text that wraps around on the\n    52\tscreen.  There are two separate left margin values, one for the first display line associated with the text line, and one for the\n    53\tsubsequent display lines, which occur because of wrapping. There is also a separate specification for the right margin, which is used to\n    54\tchoose wrap points for lines.\u003c/margins\u003e\n    55\t\u003cbr\u003e\u003cbr\u003e\u003cbig\u003e10. Spacing.\u003c/big\u003e You can control the spacing of lines with three separate parameters. \"Spacing1\" tells how much extra\n    56\tspace to leave above a line, \"spacing3\" tells how much space to leave below a line, and if a text line wraps, \"spacing2\" tells how much\n    57\tspace to leave between the display lines that make up the text line.\n    58\t\u003cbr\u003e\u003cspacing\u003eThese indented paragraphs illustrate how spacing can be used. Each paragraph is actually a single line in the text widget,\n    59\twhich is word-wrapped by the widget.\u003c/spacing\u003e\n    60\t\u003cbr\u003e\u003cspacing\u003eSpacing1 is set to 10 points for this text, which results in relatively large gaps between the paragraphs. Spacing2 is set\n    61\tto 2 points, which results in just a bit of extra space within a pararaph. Spacing3 isn't used in this example.\u003c/spacing\u003e\n    62\t\u003cbr\u003e\u003cspacing\u003eTo see where the space is, select ranges of text within these paragraphs. The selection highlight will cover the extra\n    63\tspace.\u003c/spacing\u003e`)\n    64\t\tApp.Center().Wait()\n    65\t}\n\n![svg](_examples/svg.png \"svg\")\n\nUsing svg (_examples/svg.go).\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\t// https://en.wikipedia.org/wiki/SVG\n     7\tconst svg = `\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?\u003e\n     8\t\u003c!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"\u003e\n     9\t\u003csvg width=\"391\" height=\"391\" viewBox=\"-70.5 -70.5 391 391\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\u003e\n    10\t\u003crect fill=\"#fff\" stroke=\"#000\" x=\"-70\" y=\"-70\" width=\"390\" height=\"390\"/\u003e\n    11\t\u003cg opacity=\"0.8\"\u003e\n    12\t\t\u003crect x=\"25\" y=\"25\" width=\"200\" height=\"200\" fill=\"lime\" stroke-width=\"4\" stroke=\"pink\" /\u003e\n    13\t\t\u003ccircle cx=\"125\" cy=\"125\" r=\"75\" fill=\"orange\" /\u003e\n    14\t\t\u003cpolyline points=\"50,150 50,200 200,200 200,100\" stroke=\"red\" stroke-width=\"4\" fill=\"none\" /\u003e\n    15\t\t\u003cline x1=\"50\" y1=\"50\" x2=\"200\" y2=\"200\" stroke=\"blue\" stroke-width=\"4\" /\u003e\n    16\t\u003c/g\u003e\n    17\t\u003c/svg\u003e`\n    18\t\n    19\tfunc main() {\n    20\t\tActivateTheme(\"azure light\")\n    21\t\tPack(Label(Image(NewPhoto(Data(svg)))),\n    22\t\t\tTExit(),\n    23\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    24\t\tApp.Center().Wait()\n    25\t}\n\n![calc](_examples/calc.png \"calc\")\n\nA simple calculator (_examples/calc.go).\n\n     1\tpackage main\n     2\t\n     3\timport \"github.com/expr-lang/expr\"\n     4\timport . \"modernc.org/tk9.0\"\n     5\timport _ \"modernc.org/tk9.0/themes/azure\"\n     6\t\n     7\tfunc main() {\n     8\t\tActivateTheme(\"azure light\")\n     9\t\tout := Label(Height(2), Anchor(\"e\"), Txt(\"(123+232)/(123-10)\"))\n    10\t\tGrid(out, Columnspan(4), Sticky(\"e\"))\n    11\t\tvar b *TButtonWidget\n    12\t\tfor i, c := range \"C()/789*456-123+0.=\" {\n    13\t\t\tb = TButton(Txt(string(c)),\n    14\t\t\t\tCommand(\n    15\t\t\t\t\tfunc() {\n    16\t\t\t\t\t\tswitch c {\n    17\t\t\t\t\t\tcase 'C':\n    18\t\t\t\t\t\t\tout.Configure(Txt(\"\"))\n    19\t\t\t\t\t\tcase '=':\n    20\t\t\t\t\t\t\tx, err := expr.Eval(out.Txt(), nil)\n    21\t\t\t\t\t\t\tif err != nil {\n    22\t\t\t\t\t\t\t\tMessageBox(Icon(\"error\"), Msg(err.Error()), Title(\"Error\"))\n    23\t\t\t\t\t\t\t\tx = \"\"\n    24\t\t\t\t\t\t\t}\n    25\t\t\t\t\t\t\tout.Configure(Txt(x))\n    26\t\t\t\t\t\tdefault:\n    27\t\t\t\t\t\t\tout.Configure(Txt(out.Txt() + string(c)))\n    28\t\t\t\t\t\t}\n    29\t\t\t\t\t},\n    30\t\t\t\t),\n    31\t\t\t\tWidth(-4))\n    32\t\t\tGrid(b, Row(i/4+1), Column(i%4), Sticky(\"news\"), Ipady(\"2.6m\"), Padx(\"0.5m\"), Pady(\"0.5m\"))\n    33\t\t}\n    34\t\tGrid(b, Columnspan(2))\n    35\t\tb.Configure(Style(\"Accent.TButton\"))\n    36\t\tApp.Configure(Padx(0), Pady(0)).Wait()\n    37\t}\n\n![font](_examples/font.png \"font\")\n\nA font previewer (_examples/font.go).\n\n     1\tpackage main\n     2\t\n     3\timport \"fmt\"\n     4\timport \"slices\"\n     5\timport . \"modernc.org/tk9.0\"\n     6\timport _ \"modernc.org/tk9.0/themes/azure\"\n     7\t\n     8\tfunc main() {\n     9\t\tActivateTheme(\"azure light\")\n    10\t\tvar scroll *TScrollbarWidget\n    11\t\tt := Text(Wrap(\"none\"), Setgrid(true), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }))\n    12\t\tscroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))\n    13\t\tfonts := FontFamilies()\n    14\t\tslices.Sort(fonts)\n    15\t\tGrid(t, Sticky(\"news\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    16\t\tGrid(scroll, Row(0), Column(1), Sticky(\"nes\"), Pady(\"2m\"))\n    17\t\tGridRowConfigure(App, 0, Weight(1))\n    18\t\tGridColumnConfigure(App, 0, Weight(1))\n    19\t\tGrid(TExit(), Padx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    20\t\tm := map[string]bool{}\n    21\t\tfor i, font := range fonts {\n    22\t\t\tif m[font] {\n    23\t\t\t\tcontinue\n    24\t\t\t}\n    25\t\t\tm[font] = true\n    26\t\t\ttag := fmt.Sprintf(\"t%v\", i)\n    27\t\t\tt.TagConfigure(tag, Font(NewFont(Family(font))))\n    28\t\t\tt.Insert(\"end\", font+\": \", \"\", \"Lorem ipsum dolor sit amet, consectetur adipiscing elit...\\n\", tag)\n    29\t\t}\n    30\t\tApp.Center().Wait()\n    31\t}\n\n![splot](_examples/splot.png \"surface plot\")\n\nSurface plot (_examples/splot.go). This example requires Gnuplot 5.4+ installation.\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\tvar cm = int(TkScaling()*72/2.54 + 0.5)\n     7\t\n     8\tfunc main() {\n     9\t\tActivateTheme(\"azure light\")\n    10\t\tPack(Label(Image(NewPhoto(Width(20*cm), Height(15*cm)).Graph(\"set grid; splot x**2+y**2, x**2-y**2\"))),\n    11\t\t\tTExit(),\n    12\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    13\t\tApp.Center().Wait()\n    14\t}\n\n![tori](_examples/tori.png \"interlocked tori\")\n\nInterlocked tori plot (_examples/tori.go). This example requires Gnuplot 5.4+ installation.\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\t// https://gnuplot.sourceforge.net/demo_5.4/hidden2.html\n     7\tconst script = `\n     8\tset multiplot title \"Interlocking Tori\"\n     9\tset title \"PM3D surface\\nno depth sorting\"\n    10\tset parametric\n    11\tset urange [-pi:pi]\n    12\tset vrange [-pi:pi]\n    13\tset isosamples 50,20\n    14\tset origin -0.02,0.0\n    15\tset size 0.55, 0.9\n    16\tunset key\n    17\tunset xtics\n    18\tunset ytics\n    19\tunset ztics\n    20\tset border 0\n    21\tset view 60, 30, 1.5, 0.9\n    22\tunset colorbox\n    23\tset pm3d scansbackward\n    24\tsplot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d\n    25\tset title \"PM3D surface\\ndepth sorting\"\n    26\tset origin 0.40,0.0\n    27\tset size 0.55, 0.9\n    28\tset colorbox vertical user origin 0.9, 0.15 size 0.02, 0.50\n    29\tset format cb \"%.1f\"\n    30\tset pm3d depthorder\n    31\tsplot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d\n    32\tunset multiplot`\n    33\t\n    34\tvar cm = int(TkScaling()*72/2.54 + 0.5)\n    35\t\n    36\tfunc main() {\n    37\t\tActivateTheme(\"azure light\")\n    38\t\tPack(Label(Image(NewPhoto(Width(20*cm), Height(15*cm)).Graph(script))),\n    39\t\t\tTExit(),\n    40\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    41\t\tApp.Center().Wait()\n    42\t}\n\n![tori-canvas](_examples/tori_canvas.png \"interlocked tori on canvas\")\n\nInterlocked tori plot on canvas (_examples/tori_canvas.go). This example requires Gnuplot 5.4+ installation.\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\t// https://gnuplot.sourceforge.net/demo_5.4/surface2.9.gnu\n     7\tconst script = `\n     8\tset dummy u, v\n     9\tset key bmargin center horizontal Right noreverse enhanced autotitle nobox\n    10\tset parametric\n    11\tset view 50, 30, 1, 1\n    12\tset isosamples 50, 20\n    13\tset hidden3d back offset 1 trianglepattern 3 undefined 1 altdiagonal bentover\n    14\tset style data lines\n    15\tset xyplane relative 0\n    16\tset title \"Interlocking Tori\" \n    17\tset grid\n    18\tset urange [ -3.14159 : 3.14159 ] noreverse nowriteback\n    19\tset vrange [ -3.14159 : 3.14159 ] noreverse nowriteback\n    20\tset xrange [ * : * ] noreverse writeback\n    21\tset x2range [ * : * ] noreverse writeback\n    22\tset yrange [ * : * ] noreverse writeback\n    23\tset y2range [ * : * ] noreverse writeback\n    24\tset zrange [ * : * ] noreverse writeback\n    25\tset cbrange [ * : * ] noreverse writeback\n    26\tset rrange [ * : * ] noreverse writeback\n    27\tset colorbox vertical origin screen 0.9, 0.2 size screen 0.05, 0.6 front  noinvert bdefault\n    28\tNO_ANIMATION = 1\n    29\tsplot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with lines,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with lines`\n    30\t\n    31\tvar cm = int(TkScaling()*72/2.54 + 0.5)\n    32\t\n    33\tfunc main() {\n    34\t\tPack(Canvas(Width(20*cm), Height(15*cm), Background(White)).Graph(script),\n    35\t\t\tTExit(),\n    36\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    37\t\tActivateTheme(\"azure light\")\n    38\t\tApp.Center().Wait()\n    39\t}\n\n![tex](_examples/tex.png \"TeX\")\n\nRendering plain TeX (_examples/tex.go). No runtime dependencies required.\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\tfunc main() {\n     7\t\ttex := `$$\\int _0 ^\\infty {{\\sin ax \\sin bx}\\over{x^2}}\\,dx = {\\pi a\\over 2}$$`\n     8\t\tPack(Label(Relief(\"sunken\"), Image(NewPhoto(Data(TeX(tex, 2*TkScaling()*72/600))))),\n     9\t\t\tTExit(),\n    10\t\t\tPadx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\"))\n    11\t\tActivateTheme(\"azure light\")\n    12\t\tApp.Center().Wait()\n    13\t}\n\n![embed](_examples/embed.png \"embed\")\n\nEmbedding pictures, TeX and other widgets in Text (_examples/embed.go).\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"embed\"\n     5\timport _ \"modernc.org/tk9.0/themes/azure\"\n     6\t\n     7\t//go:embed gotk.png\n     8\tvar icon []byte\n     9\t\n    10\tfunc main() {\n    11\t\tfontSize := int(10*TkScaling()/NativeScaling + 0.5)\n    12\t\tfont := Font(\"helvetica\", fontSize)\n    13\t\tvar scroll *TScrollbarWidget\n    14\t\tt := Text(font, Height(22), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }), Setgrid(true), Wrap(\"word\"),\n    15\t\t\tPadx(\"4p\"), Pady(\"12p\"))\n    16\t\tscroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))\n    17\t\tGrid(t, Sticky(\"news\"), Pady(\"2m\"))\n    18\t\tGrid(scroll, Row(0), Column(1), Sticky(\"nes\"), Pady(\"2m\"))\n    19\t\tGridRowConfigure(App, 0, Weight(1))\n    20\t\tGridColumnConfigure(App, 0, Weight(1))\n    21\t\tGrid(TExit())\n    22\t\tt.TagConfigure(\"c\", Justify(\"center\"))\n    23\t\tt.TagConfigure(\"e\", Offset(\"-2p\"))\n    24\t\tt.TagConfigure(\"t\", Font(\"times\", fontSize))\n    25\t\tsym := \" \u003ct\u003eT\u003ce\u003eE\u003c/e\u003eX\u003c/t\u003e \"\n    26\t\ttex := `$Q(\\xi) = \\lambda_1 y_1^2 \\sum_{i=2}^n \\sum_{j=2}^n y_i b_{ij} y_j$`\n    27\t\tt.InsertML(`\u003cc\u003eHello Go + Tk`, NewPhoto(Data(icon)), Padx(\"4p\"), `users!\n    28\t\u003cbr\u003e\u003cbr\u003eHello Go + Tk +`, sym, tex, ` users! (\\$inline math\\$)\n    29\t\u003cbr\u003e\u003cbr\u003eHello Go + Tk +`, sym, `$`+tex+`$`, ` users! (\\$\\$display math\\$\\$)\u003c/c\u003e\n    30\t\u003cbr\u003e\u003cbr\u003eThe above exemplifies embeding pictures and`, sym, `scripts. A text widget can also embed other widgets. For example,\n    31\twhen a`, TButton(Txt(\"\u003cTbutton\u003e\")), Padx(\"4p\"), Pady(\"2p\"), Align(\"center\"), `and\n    32\ta`, TEntry(Textvariable(\"\u003cTEntry\u003e\"), Background(White), Width(8)), Padx(\"4p\"), Pady(\"2p\"), Align(\"center\"), `are part of\n    33\tthe markup, they will reflow when their containing text widget is resized.`)\n    34\t\tActivateTheme(\"azure light\")\n    35\t\tApp.Center().Wait()\n    36\t}\n\nThe above screen shot is from '$ TK9_SCALE=1.2 go run _examples/embed.go'.\n\n![tbutton](_examples/tbutton.png \"tbutton\")\n\nStyling a button (_examples/tbutton.go). See the discussion at [Tutorial: Modifying a ttk button's style]\n\n     1\tpackage main\n     2\t\n     3\timport _ \"embed\"\n     4\timport . \"modernc.org/tk9.0\"\n     5\t\n     6\t//go:embed red_corner.png\n     7\tvar red []byte\n     8\t\n     9\t//go:embed green_corner.png\n    10\tvar green []byte\n    11\t\n    12\tfunc main() {\n    13\t\tStyleElementCreate(\"Red.Corner.TButton.indicator\", \"image\", NewPhoto(Data(red)))\n    14\t\tStyleElementCreate(\"Green.Corner.TButton.indicator\", \"image\", NewPhoto(Data(green)))\n    15\t\tStyleLayout(\"Red.Corner.TButton\",\n    16\t\t\t\"Button.border\", Sticky(\"nswe\"), Border(1), Children(\n    17\t\t\t\t\"Button.focus\", Sticky(\"nswe\"), Children(\n    18\t\t\t\t\t\"Button.padding\", Sticky(\"nswe\"), Children(\n    19\t\t\t\t\t\t\"Button.label\", Sticky(\"nswe\"),\n    20\t\t\t\t\t\t\"Red.Corner.TButton.indicator\", Side(\"right\"), Sticky(\"ne\")))))\n    21\t\tStyleLayout(\"Green.Corner.TButton\",\n    22\t\t\t\"Button.border\", Sticky(\"nswe\"), Border(1), Children(\n    23\t\t\t\t\"Button.focus\", Sticky(\"nswe\"), Children(\n    24\t\t\t\t\t\"Button.padding\", Sticky(\"nswe\"), Children(\n    25\t\t\t\t\t\t\"Button.label\", Sticky(\"nswe\"),\n    26\t\t\t\t\t\t\"Green.Corner.TButton.indicator\", Side(\"right\"), Sticky(\"ne\")))))\n    27\t\topts := Opts{Padx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\")}\n    28\t\trb := TButton(Txt(\"Red\"))\n    29\t\tgb := TButton(Txt(\"Green\"))\n    30\t\tGrid(rb, gb, opts)\n    31\t\tGrid(TButton(Txt(\"Use style\"), Command(func() {\n    32\t\t\trb.Configure(Style(\"Red.Corner.TButton\"))\n    33\t\t\tgb.Configure(Style(\"Green.Corner.TButton\"))\n    34\t\t})), TExit(), opts)\n    35\t\tApp.Wait()\n    36\t}\n\n\n![azure](_examples/azure.png \"azure\")\n\nExample usage of the theme register. (_examples/azure.go)\n\n     1\tpackage main\n     2\t\n     3\timport . \"modernc.org/tk9.0\"\n     4\timport _ \"modernc.org/tk9.0/themes/azure\"\n     5\t\n     6\tfunc main() {\n     7\t\tPack(TButton(Txt(\"Light\"), Command(func() { ActivateTheme(\"azure light\") })),\n     8\t\t\tTButton(Txt(\"Dark\"), Command(func() { ActivateTheme(\"azure dark\") })),\n     9\t\t\tTExit(),\n    10\t\t\tPady(\"2m\"), Ipady(\"1m\"))\n    11\t\tApp.Wait()\n    12\t}\n\n![b5](_examples/b5.png \"b5\")\n\nTechnology preview of a Bootstrap 5-like theme buttons (_examples/b5.go). Only\na partial prototype/problem study/work in progress at the moment. But it may\nget there, eventually. (_examples/b5.go)\n\n     1\tpackage main\n     2\t\n     3\timport (\n     4\t\t. \"modernc.org/tk9.0\"\n     5\t\t\"modernc.org/tk9.0/b5\"\n     6\t)\n     7\t\n     8\tfunc main() {\n     9\t\tbackground := White\n    10\t\tprimary := b5.Colors{b5.ButtonText: \"#fff\", b5.ButtonFace: \"#0d6efd\", b5.ButtonFocus: \"#98c1fe\"}\n    11\t\tsecondary := b5.Colors{b5.ButtonText: \"#fff\", b5.ButtonFace: \"#6c757d\", b5.ButtonFocus: \"#c0c4c8\"}\n    12\t\tsuccess := b5.Colors{b5.ButtonText: \"#fff\", b5.ButtonFace: \"#198754\", b5.ButtonFocus: \"#9dccb6\"}\n    13\t\tdanger := b5.Colors{b5.ButtonText: \"#fff\", b5.ButtonFace: \"#dc3545\", b5.ButtonFocus: \"#f0a9b0\"}\n    14\t\twarning := b5.Colors{b5.ButtonText: \"#000\", b5.ButtonFace: \"#ffc107\", b5.ButtonFocus: \"#ecd182\"}\n    15\t\tinfo := b5.Colors{b5.ButtonText: \"#000\", b5.ButtonFace: \"#0dcaf0\", b5.ButtonFocus: \"#85d5e5\"}\n    16\t\tlight := b5.Colors{b5.ButtonText: \"#000\", b5.ButtonFace: \"#f8f9fa\", b5.ButtonFocus: \"#e9e9ea\"}\n    17\t\tdark := b5.Colors{b5.ButtonText: \"#fff\", b5.ButtonFace: \"#212529\", b5.ButtonFocus: \"#a0a2a4\"}\n    18\t\tlink := b5.Colors{b5.ButtonText: \"#1774fd\", b5.ButtonFace: \"#fff\", b5.ButtonFocus: \"#c2dbfe\"}\n    19\t\tStyleThemeUse(\"default\")\n    20\t\topts := Opts{Padx(\"1m\"), Pady(\"2m\"), Ipadx(\"1m\"), Ipady(\"1m\")}\n    21\t\tGrid(TButton(Txt(\"Primary\"), Style(b5.ButtonStyle(\"primary.TButton\", primary, background, false))),\n    22\t\t\tTButton(Txt(\"Secondary\"), Style(b5.ButtonStyle(\"secondary.TButton\", secondary, background, false))),\n    23\t\t\tTButton(Txt(\"Success\"), Style(b5.ButtonStyle(\"success.TButton\", success, background, false))),\n    24\t\t\topts)\n    25\t\tGrid(TButton(Txt(\"Danger\"), Style(b5.ButtonStyle(\"danger.TButton\", danger, background, false))),\n    26\t\t\tTButton(Txt(\"Warning\"), Style(b5.ButtonStyle(\"warning.TButton\", warning, background, false))),\n    27\t\t\tTButton(Txt(\"Info\"), Style(b5.ButtonStyle(\"info.TButton\", info, background, false))),\n    28\t\t\topts)\n    29\t\tGrid(TButton(Txt(\"Light\"), Style(b5.ButtonStyle(\"light.TButton\", light, background, false))),\n    30\t\t\tTButton(Txt(\"Dark\"), Style(b5.ButtonStyle(\"dark.TButton\", dark, background, false))),\n    31\t\t\tTButton(Txt(\"Link\"), Style(b5.ButtonStyle(\"link.TButton\", link, background, false))),\n    32\t\t\topts)\n    33\t\tGrid(TButton(Txt(\"Primary\"), Style(b5.ButtonStyle(\"focused.primary.TButton\", primary, background, true))),\n    34\t\t\tTButton(Txt(\"Secondary\"), Style(b5.ButtonStyle(\"focused.secondary.TButton\", secondary, background, true))),\n    35\t\t\tTButton(Txt(\"Success\"), Style(b5.ButtonStyle(\"focused.success.TButton\", success, background, true))),\n    36\t\t\topts)\n    37\t\tGrid(TButton(Txt(\"Danger\"), Style(b5.ButtonStyle(\"focused.danger.TButton\", danger, background, true))),\n    38\t\t\tTButton(Txt(\"Warning\"), Style(b5.ButtonStyle(\"focused.warning.TButton\", warning, background, true))),\n    39\t\t\tTButton(Txt(\"Info\"), Style(b5.ButtonStyle(\"focused.info.TButton\", info, background, true))),\n    40\t\t\topts)\n    41\t\tGrid(TButton(Txt(\"Light\"), Style(b5.ButtonStyle(\"focused.light.TButton\", light, background, true))),\n    42\t\t\tTButton(Txt(\"Dark\"), Style(b5.ButtonStyle(\"focused.dark.TButton\", dark, background, true))),\n    43\t\t\tTButton(Txt(\"Link\"), Style(b5.ButtonStyle(\"focused.link.TButton\", link, background, true))),\n    44\t\t\topts)\n    45\t\tGrid(TExit(), Columnspan(3), opts)\n    46\t\tApp.Configure(Background(background)).Wait()\n    47\t}\n\n----\n\nGallery (_examples/demo.go)\n\nDarwin(macOS) Sequoia 15.0\n\n![darwin](_examples/darwin.png \"darwin\")\n\nFreeBSD Xfce4\n\n![freebsd](_examples/freebsd.png \"freebsd\")\n\nLinux Mate 1.26.0\n\n![linux](_examples/linux.png \"linux\")\n\nWindows 11\n\n![windows11](_examples/windows11.png \"windows11\")\n\n[![Go Reference](https://pkg.go.dev/badge/modernc.org/tk9.0.svg)](https://pkg.go.dev/modernc.org/tk9.0)\n\n[Tutorial: Modifying a ttk button's style]: https://wiki.tcl-lang.org/page/Tutorial%3A+Modifying+a+ttk+button%27s+style\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Ftk9.0","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuce%2Ftk9.0","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Ftk9.0/lists"}