From 55df09198ce868a1b16f5691ef0eb6e2b78bdadf Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 16:22:59 +0530 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=96=BC=EF=B8=8F=20Windows=20HiDPi=20C?= =?UTF-8?q?ursors=20sizes=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/build.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builder/build.py b/builder/build.py index dbd1118..508c659 100644 --- a/builder/build.py +++ b/builder/build.py @@ -106,6 +106,12 @@ x_out_dir = Path(args.out_dir) / name win_out_dir = Path(args.out_dir) / f"{name}-Windows" +# Windows Canvas & Cursor sizes +win_size: int = args.win_size +win_canvas_size: int = args.win_canvas_size +if win_canvas_size < win_size: + win_canvas_size = win_size + print(f"Getting '{name}' bitmaps ready for build...") config = get_config( From 112449a8eee7e36ee6f2bbb65dd968dffeac6718 Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 17:35:11 +0530 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=A6=20Builder=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/{src => }/gbpkg/__init__.py | 0 builder/{src => }/gbpkg/configure.py | 0 builder/{src => }/gbpkg/constants.py | 0 builder/{src => }/gbpkg/generator.py | 0 builder/{src => }/gbpkg/symlinks.py | 0 builder/gdbuild/__init__.py | 0 builder/gdbuild/configure.py | 101 ++++++++++++++ builder/gdbuild/constants.py | 89 +++++++++++++ builder/gdbuild/generator.py | 131 +++++++++++++++++++ builder/gdbuild/symlinks.py | 188 +++++++++++++++++++++++++++ 10 files changed, 509 insertions(+) rename builder/{src => }/gbpkg/__init__.py (100%) rename builder/{src => }/gbpkg/configure.py (100%) rename builder/{src => }/gbpkg/constants.py (100%) rename builder/{src => }/gbpkg/generator.py (100%) rename builder/{src => }/gbpkg/symlinks.py (100%) create mode 100644 builder/gdbuild/__init__.py create mode 100644 builder/gdbuild/configure.py create mode 100644 builder/gdbuild/constants.py create mode 100644 builder/gdbuild/generator.py create mode 100644 builder/gdbuild/symlinks.py diff --git a/builder/src/gbpkg/__init__.py b/builder/gbpkg/__init__.py similarity index 100% rename from builder/src/gbpkg/__init__.py rename to builder/gbpkg/__init__.py diff --git a/builder/src/gbpkg/configure.py b/builder/gbpkg/configure.py similarity index 100% rename from builder/src/gbpkg/configure.py rename to builder/gbpkg/configure.py diff --git a/builder/src/gbpkg/constants.py b/builder/gbpkg/constants.py similarity index 100% rename from builder/src/gbpkg/constants.py rename to builder/gbpkg/constants.py diff --git a/builder/src/gbpkg/generator.py b/builder/gbpkg/generator.py similarity index 100% rename from builder/src/gbpkg/generator.py rename to builder/gbpkg/generator.py diff --git a/builder/src/gbpkg/symlinks.py b/builder/gbpkg/symlinks.py similarity index 100% rename from builder/src/gbpkg/symlinks.py rename to builder/gbpkg/symlinks.py diff --git a/builder/gdbuild/__init__.py b/builder/gdbuild/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/builder/gdbuild/configure.py b/builder/gdbuild/configure.py new file mode 100644 index 0000000..c1c5c94 --- /dev/null +++ b/builder/gdbuild/configure.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from typing import Any, Dict, Tuple, TypeVar + +from clickgen.util import PNGProvider +from .constants import WIN_CURSORS_CFG, WIN_DELAY, X_CURSORS_CFG, X_DELAY + +X = TypeVar("X") + + +def to_tuple(x: X) -> Tuple[X, X]: + return (x, x) + + +def get_config(bitmaps_dir, **kwargs) -> Dict[str, Any]: + """Return configuration of `GoogleDot` pointers. + + :param bitmaps_dir: Path to .png file's directory. + :type bitmaps_dir: ``str`` or ``pathlib.Path`` + + :param **kwargs: + See below + + :Keyword Arguments: + * *x_sizes* (``List[int]``) -- + List of pixel-sizes for xcursors. + * *win_canvas_size* (``int``) -- + Windows cursor's canvas pixel-size. + * *win_size* (``int``) -- + Pixel-size for Windows cursor. + + Example: + + ```python + get_config( + bitmaps_dir="./bitmaps", + x_sizes=[24, 28, 32], + win_canvas_size=32, + win_size=24, + ) + ``` + """ + + w_size = to_tuple(kwargs.pop("win_size")) + w_canvas_size = to_tuple(kwargs.pop("win_canvas_size")) + raw_x_sizes = kwargs.pop("x_sizes") + + x_sizes = [] + for size in raw_x_sizes: + x_sizes.append(to_tuple(size)) + + png_provider = PNGProvider(bitmaps_dir) + config: Dict[str, Any] = {} + + for key, item in X_CURSORS_CFG.items(): + x_hot: int = int(item.get("xhot", 0)) + y_hot: int = int(item.get("yhot", 0)) + hotspot: Tuple[int, int] = (x_hot, y_hot) + + delay: int = int(item.get("delay", X_DELAY)) + png = png_provider.get(key) + if not png: + raise FileNotFoundError(f"{key} not found") + + data = { + "png": png, + "x_sizes": x_sizes, + "hotspot": hotspot, + "delay": delay, + } + + win_data = WIN_CURSORS_CFG.get(key) + + if win_data: + win_key: str = str(win_data.get("to")) + + position: str = str(win_data.get("position", "center")) + win_delay: int = int(win_data.get("delay", WIN_DELAY)) + + canvas_size = win_data.get("canvas_size", w_canvas_size) + win_size = win_data.get("size", w_size) + + # Because provided cursor size is bigger than cursor's canvas. + # Also, "position" settings will not effect on cursor because the + # cursor's canvas and cursor sizes are equals. + if (win_size[0] > canvas_size[0]) | (win_size[1] > canvas_size[1]): + canvas_size = win_size + + config[key] = { + **data, + "win_key": win_key, + "position": position, + "canvas_size": canvas_size, + "win_size": win_size, + "win_delay": win_delay, + } + else: + config[key] = data + + return config diff --git a/builder/gdbuild/constants.py b/builder/gdbuild/constants.py new file mode 100644 index 0000000..1a8db05 --- /dev/null +++ b/builder/gdbuild/constants.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from typing import Dict + +# Info +AUTHOR = "Kaiz Khatri" +URL = "https://github.com/ful1e5/Google_Cursor" + +# XCursor +X_DELAY: int = 10 + + +# Windows Cursor +WIN_DELAY = 1 + +X_CURSORS_CFG: Dict[str, Dict[str, int]] = { + ########## + # Static # + ########## + "all-scroll.png": {"xhot": 100, "yhot": 100}, + "bottom_left_corner.png": {"xhot": 100, "yhot": 100}, + "bottom_right_corner.png": {"xhot": 100, "yhot": 100}, + "bottom_tee.png": {"xhot": 100, "yhot": 100}, + "context-menu.png": {"xhot": 100, "yhot": 100}, + "copy.png": {"xhot": 100, "yhot": 100}, + "cross.png": {"xhot": 100, "yhot": 100}, + "dnd_no_drop.png": {"xhot": 100, "yhot": 100}, + "dotbox.png": {"xhot": 100, "yhot": 100}, + "hand1.png": {"xhot": 100, "yhot": 100}, + "hand2.png": {"xhot": 100, "yhot": 100}, + "left_ptr.png": {"xhot": 100, "yhot": 100}, + "left_tee.png": {"xhot": 100, "yhot": 100}, + "link.png": {"xhot": 100, "yhot": 100}, + "ll_angle.png": {"xhot": 100, "yhot": 100}, + "lr_angle.png": {"xhot": 100, "yhot": 100}, + "move.png": {"xhot": 100, "yhot": 100}, + "pencil.png": {"xhot": 100, "yhot": 100}, + "plus.png": {"xhot": 100, "yhot": 100}, + "question_arrow.png": {"xhot": 100, "yhot": 100}, + "right_ptr.png": {"xhot": 100, "yhot": 100}, + "right_tee.png": {"xhot": 100, "yhot": 100}, + "sb_down_arrow.png": {"xhot": 100, "yhot": 100}, + "sb_h_double_arrow.png": {"xhot": 100, "yhot": 100}, + "sb_left_arrow.png": {"xhot": 100, "yhot": 100}, + "sb_right_arrow.png": {"xhot": 100, "yhot": 100}, + "sb_up_arrow.png": {"xhot": 100, "yhot": 100}, + "sb_v_double_arrow.png": {"xhot": 100, "yhot": 100}, + "top_tee.png": {"xhot": 100, "yhot": 100}, + "ul_angle.png": {"xhot": 100, "yhot": 100}, + "ur_angle.png": {"xhot": 100, "yhot": 100}, + "vertical-text.png": {"xhot": 100, "yhot": 100}, + "wayland-cursor.png": {"xhot": 100, "yhot": 100}, + "X_cursor.png": {"xhot": 100, "yhot": 100}, + "xterm.png": {"xhot": 100, "yhot": 89}, + "zoom-in.png": {"xhot": 100, "yhot": 100}, + "zoom-out.png": {"xhot": 100, "yhot": 100}, + ############ + # Animated # + ############ + # Note: Animated cursors don't need an extension and frame numbers. + "left_ptr_watch": {"xhot": 100, "yhot": 100}, + "wait": {"xhot": 100, "yhot": 100}, +} + +WIN_CURSORS_CFG: Dict[str, Dict[str, str]] = { + ########## + # Static # + ########## + "right_ptr.png": {"to": "Alternate", "position": "top_right"}, + "cross.png": {"to": "Cross"}, + "left_ptr.png": {"to": "Default", "position": "top_left"}, + "bottom_right_corner.png": {"to": "Diagonal_1"}, + "bottom_left_corner.png": {"to": "Diagonal_2"}, + "pencil.png": {"to": "Handwriting"}, + "question_arrow.png": {"to": "Help", "position.png": "top_left"}, + "sb_h_double_arrow.png": {"to": "Horizontal"}, + "xterm.png": {"to": "IBeam", "position": "top_left"}, + "hand2.png": {"to": "Link", "position": "top_left"}, + "hand1.png": {"to": "Move"}, + "dnd_no_drop.png": {"to": "Unavailiable", "position": "top_left"}, + "sb_v_double_arrow.png": {"to": "Vertical"}, + ############ + # Animated # + ############ + # Note: Animated cursors don't need frame numbers. + "left_ptr_watch": {"to": "Work", "position": "top_left"}, + "wait": {"to": "Busy"}, +} diff --git a/builder/gdbuild/generator.py b/builder/gdbuild/generator.py new file mode 100644 index 0000000..4da150a --- /dev/null +++ b/builder/gdbuild/generator.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pathlib import Path +from typing import Any, Dict, NamedTuple + +from clickgen.builders import WindowsCursor, XCursor +from clickgen.core import CursorAlias +from clickgen.packagers import WindowsPackager, XPackager +from .constants import AUTHOR, URL +from .symlinks import add_missing_xcursor + + +class Info(NamedTuple): + """Theme basic information. + + :param name: Theme title. + :type name: ``str`` + + :param comment: quick information about theme. + :type comment: ``str`` + """ + + name: str + comment: str + + +def xbuild(config: Dict[str, Dict[str, Any]], x_out_dir: Path, info: Info) -> None: + """Build `GoogleDot` cursor theme for only `X11`(UNIX) platform. + + :param config: `GoogleDot` configuration. + :type config: Dict + + :param x_out_dir: Path to the output directory,\ + Where the `X11` cursor theme package will generate.\ + It also creates a directory if not exists. + :type x_out_dir: Path + + :param info: Content theme name & comment + :type info: Info + """ + + for _, item in config.items(): + with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: + x_cfg = alias.create(item["x_sizes"], item["delay"]) + + print(f"Building '{x_cfg.stem}' XCursor...") + XCursor.create(x_cfg, x_out_dir) + + add_missing_xcursor(x_out_dir / "cursors") + XPackager(x_out_dir, info.name, info.comment) + + +def wbuild(config: Dict[str, Dict[str, Any]], win_out_dir: Path, info: Info) -> None: + """Build `GoogleDot` cursor theme for only `Windows` platforms. + + :param config: `GoogleDot` configuration. + :type config: Dict + + :param win_out_dir: Path to the output directory,\ + Where the `Windows` cursor theme package will generate.\ + It also creates a directory if not exists. + :type win_out_dir: Path + + :param info: Content theme name & comment + :type info: Info + """ + + for _, item in config.items(): + with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: + alias.create(item["x_sizes"], item["delay"]) + + if item.get("win_key"): + win_cfg = alias.reproduce( + size=item["win_size"], + canvas_size=item["canvas_size"], + position=item["position"], + delay=item["win_delay"], + ).rename(item["win_key"]) + + print(f"Building '{win_cfg.stem}' Windows Cursor...") + WindowsCursor.create(win_cfg, win_out_dir) + + WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) + + +def build( + config: Dict[str, Dict[str, Any]], x_out_dir: Path, win_out_dir: Path, info: Info +) -> None: + """Build `GoogleDot` cursor theme for `X11` & `Windows` platforms. + + :param config: `GoogleDot` configuration. + :type config: Dict + + :param x_out_dir: Path to the output directory,\ + Where the `X11` cursor theme package will generate.\ + It also creates a directory if not exists. + :type x_out_dir: Path + + :param win_out_dir: Path to the output directory,\ + Where the `Windows` cursor theme package will generate.\ + It also creates a directory if not exists. + :type win_out_dir: Path + + :param info: Content theme name & comment + :type info: Info + """ + + for _, item in config.items(): + + with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: + x_cfg = alias.create(item["x_sizes"], item["delay"]) + + print(f"Building '{x_cfg.stem}' XCursor...") + XCursor.create(x_cfg, x_out_dir) + + if item.get("win_key"): + win_cfg = alias.reproduce( + size=item["win_size"], + canvas_size=item["canvas_size"], + position=item["position"], + delay=item["win_delay"], + ).rename(item["win_key"]) + + print(f"Building '{win_cfg.stem}' Windows Cursor...") + WindowsCursor.create(win_cfg, win_out_dir) + + add_missing_xcursor(x_out_dir / "cursors") + XPackager(x_out_dir, info.name, info.comment) + + WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) diff --git a/builder/gdbuild/symlinks.py b/builder/gdbuild/symlinks.py new file mode 100644 index 0000000..d80480d --- /dev/null +++ b/builder/gdbuild/symlinks.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +from typing import Dict, List, Union + +from clickgen.util import chdir + + +def add_missing_xcursor(directory) -> None: + """Add missing `XCursor` to the Unix cursor package. + + :param directory: directory where XCursors are available. + :type directory: Union[str, Path] + """ + + symlinks: List[Dict[str, Union[str, List[str]]]] = [ + {"src": "all-scroll", "links": ["fleur", "size_all"]}, + { + "src": "bottom_left_corner", + "links": [ + "fcf1c3c7cd4491d801f1e1c78f100000", + "sw-resize", + "ne-resize", + "size_bdiag", + "nesw-resize", + "top_right_corner", + "fd_double_arrow", + ], + }, + { + "src": "bottom_right_corner", + "links": [ + "c7088f0f3e6c8088236ef8e1e3e70000", + "top_left_corner", + "se-resize", + "nw-resize", + "size_fdiag", + "nwse-resize", + "bd_double_arrow", + ], + }, + { + "src": "copy", + "links": [ + "1081e37283d90000800003c07f3ef6bf", + "6407b0e94181790501fd1e167b474872", + "b66166c04f8c3109214a4fbd64a50fc8", + "dnd-copy", + ], + }, + { + "src": "cross", + "links": [ + "cross_reverse", + "diamond_cross", + "tcross", + "color-picker", + "crosshair", + ], + }, + { + "src": "dnd_no_drop", + "links": [ + "no-drop", + # crossed_circle symlinks + "crossed_circle", + "03b6e0fcb3499374a867c041f52298f0", + "not-allowed", + "forbidden", + "circle", + ], + }, + {"src": "dotbox", "links": ["dot_box_mask", "draped_box", "icon", "target"]}, + {"src": "hand1", "links": ["grab", "openhand"]}, + { + "src": "hand2", + "links": [ + "9d800788f1b08800ae810202380a0822", + "e29285e634086352946a0e7090d73106", + "pointer", + "pointing_hand", + ], + }, + { + "src": "left_ptr", + "links": [ + "arrow", + "default", + "center_ptr", + ], + }, + { + "src": "left_ptr_watch", + "links": [ + "00000000000000020006000e7e9ffc3f", + "08e8e1c95fe2fc01f976f1e063a24ccd", + "3ecb610c1bf2410f44200f48c40d3599", + "progress", + ], + }, + { + "src": "link", + "links": [ + "3085a0e285430894940527032f8b26df", + "640fb0e74195791501fd1ed57b41487f", + "a2a266d0498c3104214a47bd64ab0fc8", + "alias", + "dnd-link", + ], + }, + { + "src": "move", + "links": [ + "4498f0e0c1937ffe01fd06f973665830", + "9081237383d90e509aa00f00170e968f", + "fcf21c00b30f7e3f83fe0dfd12e71cff", + "grabbing", + "pointer_move", + "dnd-move", + "closedhand", + "dnd-none", + ], + }, + {"src": "pencil", "links": ["draft"]}, + {"src": "plus", "links": ["cell"]}, + { + "src": "question_arrow", + "links": [ + "5c6cd98b3f3ebcb1f9c7f1c204630408", + "d9ce0ab605698f320427677b458ad60b", + "help", + "left_ptr_help", + "whats_this", + "dnd-ask", + ], + }, + {"src": "right_ptr", "links": ["draft_large", "draft_small"]}, # required + {"src": "sb_down_arrow", "links": ["down-arrow"]}, + { + "src": "sb_h_double_arrow", + "links": [ + "028006030e0e7ebffc7f7070c0600140", + "14fef782d02440884392942c1120523", + "col-resize", + "ew-resize", + "h_double_arrow", + "size-hor", + "size_hor", + "split_h", + "left_side", + "w-resize", + "right_side", + "e-resize", + ], + }, + {"src": "sb_left_arrow", "links": ["left-arrow"]}, + {"src": "sb_right_arrow", "links": ["right-arrow"]}, + {"src": "sb_up_arrow", "links": ["up-arrow"]}, + { + "src": "sb_v_double_arrow", + "links": [ + "00008160000006810000408080010102", + "2870a09082c103050810ffdffffe0204", + "double_arrow", + "ns-resize", + "row-resize", + "size-ver", + "size_ver", + "split_v", + "v_double_arrow", + "top_side", + "s-resize", + "n-resize", + "bottom_side", + ], + }, + {"src": "wait", "links": ["watch"]}, + {"src": "X_cursor", "links": ["pirate", "x-cursor"]}, + {"src": "xterm", "links": ["ibeam", "text"]}, + ] + + with chdir(directory): + for item in symlinks: + src = str(item["src"]) + for link in item.get("links"): + print(f"Creating symlink {src} -> {link}") + os.symlink(src, link) From 4a3b94afe174d34fca511f17eb5f3ceb5aff378e Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 17:35:34 +0530 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=A7=B9=20Clean=20old=20builder=20modu?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/gbpkg/__init__.py | 0 builder/gbpkg/configure.py | 101 -------------------- builder/gbpkg/constants.py | 89 ------------------ builder/gbpkg/generator.py | 131 -------------------------- builder/gbpkg/symlinks.py | 188 ------------------------------------- builder/setup.py | 25 ----- 6 files changed, 534 deletions(-) delete mode 100644 builder/gbpkg/__init__.py delete mode 100644 builder/gbpkg/configure.py delete mode 100644 builder/gbpkg/constants.py delete mode 100644 builder/gbpkg/generator.py delete mode 100644 builder/gbpkg/symlinks.py delete mode 100644 builder/setup.py diff --git a/builder/gbpkg/__init__.py b/builder/gbpkg/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/builder/gbpkg/configure.py b/builder/gbpkg/configure.py deleted file mode 100644 index b073356..0000000 --- a/builder/gbpkg/configure.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from typing import Any, Dict, Tuple, TypeVar - -from clickgen.util import PNGProvider -from gbpkg.constants import WIN_CURSORS_CFG, WIN_DELAY, X_CURSORS_CFG, X_DELAY - -X = TypeVar("X") - - -def to_tuple(x: X) -> Tuple[X, X]: - return (x, x) - - -def get_config(bitmaps_dir, **kwargs) -> Dict[str, Any]: - """Return configuration of `GoogleDot` pointers. - - :param bitmaps_dir: Path to .png file's directory. - :type bitmaps_dir: ``str`` or ``pathlib.Path`` - - :param **kwargs: - See below - - :Keyword Arguments: - * *x_sizes* (``List[int]``) -- - List of pixel-sizes for xcursors. - * *win_canvas_size* (``int``) -- - Windows cursor's canvas pixel-size. - * *win_size* (``int``) -- - Pixel-size for Windows cursor. - - Example: - - ```python - get_config( - bitmaps_dir="./bitmaps", - x_sizes=[24, 28, 32], - win_canvas_size=32, - win_size=24, - ) - ``` - """ - - w_size = to_tuple(kwargs.pop("win_size")) - w_canvas_size = to_tuple(kwargs.pop("win_canvas_size")) - raw_x_sizes = kwargs.pop("x_sizes") - - x_sizes = [] - for size in raw_x_sizes: - x_sizes.append(to_tuple(size)) - - png_provider = PNGProvider(bitmaps_dir) - config: Dict[str, Any] = {} - - for key, item in X_CURSORS_CFG.items(): - x_hot: int = int(item.get("xhot", 0)) - y_hot: int = int(item.get("yhot", 0)) - hotspot: Tuple[int, int] = (x_hot, y_hot) - - delay: int = int(item.get("delay", X_DELAY)) - png = png_provider.get(key) - if not png: - raise FileNotFoundError(f"{key} not found") - - data = { - "png": png, - "x_sizes": x_sizes, - "hotspot": hotspot, - "delay": delay, - } - - win_data = WIN_CURSORS_CFG.get(key) - - if win_data: - win_key: str = str(win_data.get("to")) - - position: str = str(win_data.get("position", "center")) - win_delay: int = int(win_data.get("delay", WIN_DELAY)) - - canvas_size = win_data.get("canvas_size", w_canvas_size) - win_size = win_data.get("size", w_size) - - # Because provided cursor size is bigger than cursor's canvas. - # Also, "position" settings will not effect on cursor because the - # cursor's canvas and cursor sizes are equals. - if (win_size[0] > canvas_size[0]) | (win_size[1] > canvas_size[1]): - canvas_size = win_size - - config[key] = { - **data, - "win_key": win_key, - "position": position, - "canvas_size": canvas_size, - "win_size": win_size, - "win_delay": win_delay, - } - else: - config[key] = data - - return config diff --git a/builder/gbpkg/constants.py b/builder/gbpkg/constants.py deleted file mode 100644 index 1a8db05..0000000 --- a/builder/gbpkg/constants.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from typing import Dict - -# Info -AUTHOR = "Kaiz Khatri" -URL = "https://github.com/ful1e5/Google_Cursor" - -# XCursor -X_DELAY: int = 10 - - -# Windows Cursor -WIN_DELAY = 1 - -X_CURSORS_CFG: Dict[str, Dict[str, int]] = { - ########## - # Static # - ########## - "all-scroll.png": {"xhot": 100, "yhot": 100}, - "bottom_left_corner.png": {"xhot": 100, "yhot": 100}, - "bottom_right_corner.png": {"xhot": 100, "yhot": 100}, - "bottom_tee.png": {"xhot": 100, "yhot": 100}, - "context-menu.png": {"xhot": 100, "yhot": 100}, - "copy.png": {"xhot": 100, "yhot": 100}, - "cross.png": {"xhot": 100, "yhot": 100}, - "dnd_no_drop.png": {"xhot": 100, "yhot": 100}, - "dotbox.png": {"xhot": 100, "yhot": 100}, - "hand1.png": {"xhot": 100, "yhot": 100}, - "hand2.png": {"xhot": 100, "yhot": 100}, - "left_ptr.png": {"xhot": 100, "yhot": 100}, - "left_tee.png": {"xhot": 100, "yhot": 100}, - "link.png": {"xhot": 100, "yhot": 100}, - "ll_angle.png": {"xhot": 100, "yhot": 100}, - "lr_angle.png": {"xhot": 100, "yhot": 100}, - "move.png": {"xhot": 100, "yhot": 100}, - "pencil.png": {"xhot": 100, "yhot": 100}, - "plus.png": {"xhot": 100, "yhot": 100}, - "question_arrow.png": {"xhot": 100, "yhot": 100}, - "right_ptr.png": {"xhot": 100, "yhot": 100}, - "right_tee.png": {"xhot": 100, "yhot": 100}, - "sb_down_arrow.png": {"xhot": 100, "yhot": 100}, - "sb_h_double_arrow.png": {"xhot": 100, "yhot": 100}, - "sb_left_arrow.png": {"xhot": 100, "yhot": 100}, - "sb_right_arrow.png": {"xhot": 100, "yhot": 100}, - "sb_up_arrow.png": {"xhot": 100, "yhot": 100}, - "sb_v_double_arrow.png": {"xhot": 100, "yhot": 100}, - "top_tee.png": {"xhot": 100, "yhot": 100}, - "ul_angle.png": {"xhot": 100, "yhot": 100}, - "ur_angle.png": {"xhot": 100, "yhot": 100}, - "vertical-text.png": {"xhot": 100, "yhot": 100}, - "wayland-cursor.png": {"xhot": 100, "yhot": 100}, - "X_cursor.png": {"xhot": 100, "yhot": 100}, - "xterm.png": {"xhot": 100, "yhot": 89}, - "zoom-in.png": {"xhot": 100, "yhot": 100}, - "zoom-out.png": {"xhot": 100, "yhot": 100}, - ############ - # Animated # - ############ - # Note: Animated cursors don't need an extension and frame numbers. - "left_ptr_watch": {"xhot": 100, "yhot": 100}, - "wait": {"xhot": 100, "yhot": 100}, -} - -WIN_CURSORS_CFG: Dict[str, Dict[str, str]] = { - ########## - # Static # - ########## - "right_ptr.png": {"to": "Alternate", "position": "top_right"}, - "cross.png": {"to": "Cross"}, - "left_ptr.png": {"to": "Default", "position": "top_left"}, - "bottom_right_corner.png": {"to": "Diagonal_1"}, - "bottom_left_corner.png": {"to": "Diagonal_2"}, - "pencil.png": {"to": "Handwriting"}, - "question_arrow.png": {"to": "Help", "position.png": "top_left"}, - "sb_h_double_arrow.png": {"to": "Horizontal"}, - "xterm.png": {"to": "IBeam", "position": "top_left"}, - "hand2.png": {"to": "Link", "position": "top_left"}, - "hand1.png": {"to": "Move"}, - "dnd_no_drop.png": {"to": "Unavailiable", "position": "top_left"}, - "sb_v_double_arrow.png": {"to": "Vertical"}, - ############ - # Animated # - ############ - # Note: Animated cursors don't need frame numbers. - "left_ptr_watch": {"to": "Work", "position": "top_left"}, - "wait": {"to": "Busy"}, -} diff --git a/builder/gbpkg/generator.py b/builder/gbpkg/generator.py deleted file mode 100644 index a1854c6..0000000 --- a/builder/gbpkg/generator.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from pathlib import Path -from typing import Any, Dict, NamedTuple - -from clickgen.builders import WindowsCursor, XCursor -from clickgen.core import CursorAlias -from clickgen.packagers import WindowsPackager, XPackager -from gbpkg.constants import AUTHOR, URL -from gbpkg.symlinks import add_missing_xcursor - - -class Info(NamedTuple): - """Theme basic information. - - :param name: Theme title. - :type name: ``str`` - - :param comment: quick information about theme. - :type comment: ``str`` - """ - - name: str - comment: str - - -def xbuild(config: Dict[str, Dict[str, Any]], x_out_dir: Path, info: Info) -> None: - """Build `GoogleDot` cursor theme for only `X11`(UNIX) platform. - - :param config: `GoogleDot` configuration. - :type config: Dict - - :param x_out_dir: Path to the output directory,\ - Where the `X11` cursor theme package will generate.\ - It also creates a directory if not exists. - :type x_out_dir: Path - - :param info: Content theme name & comment - :type info: Info - """ - - for _, item in config.items(): - with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: - x_cfg = alias.create(item["x_sizes"], item["delay"]) - - print(f"Building '{x_cfg.stem}' XCursor...") - XCursor.create(x_cfg, x_out_dir) - - add_missing_xcursor(x_out_dir / "cursors") - XPackager(x_out_dir, info.name, info.comment) - - -def wbuild(config: Dict[str, Dict[str, Any]], win_out_dir: Path, info: Info) -> None: - """Build `GoogleDot` cursor theme for only `Windows` platforms. - - :param config: `GoogleDot` configuration. - :type config: Dict - - :param win_out_dir: Path to the output directory,\ - Where the `Windows` cursor theme package will generate.\ - It also creates a directory if not exists. - :type win_out_dir: Path - - :param info: Content theme name & comment - :type info: Info - """ - - for _, item in config.items(): - with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: - alias.create(item["x_sizes"], item["delay"]) - - if item.get("win_key"): - win_cfg = alias.reproduce( - size=item["win_size"], - canvas_size=item["canvas_size"], - position=item["position"], - delay=item["win_delay"], - ).rename(item["win_key"]) - - print(f"Building '{win_cfg.stem}' Windows Cursor...") - WindowsCursor.create(win_cfg, win_out_dir) - - WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) - - -def build( - config: Dict[str, Dict[str, Any]], x_out_dir: Path, win_out_dir: Path, info: Info -) -> None: - """Build `GoogleDot` cursor theme for `X11` & `Windows` platforms. - - :param config: `GoogleDot` configuration. - :type config: Dict - - :param x_out_dir: Path to the output directory,\ - Where the `X11` cursor theme package will generate.\ - It also creates a directory if not exists. - :type x_out_dir: Path - - :param win_out_dir: Path to the output directory,\ - Where the `Windows` cursor theme package will generate.\ - It also creates a directory if not exists. - :type win_out_dir: Path - - :param info: Content theme name & comment - :type info: Info - """ - - for _, item in config.items(): - - with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: - x_cfg = alias.create(item["x_sizes"], item["delay"]) - - print(f"Building '{x_cfg.stem}' XCursor...") - XCursor.create(x_cfg, x_out_dir) - - if item.get("win_key"): - win_cfg = alias.reproduce( - size=item["win_size"], - canvas_size=item["canvas_size"], - position=item["position"], - delay=item["win_delay"], - ).rename(item["win_key"]) - - print(f"Building '{win_cfg.stem}' Windows Cursor...") - WindowsCursor.create(win_cfg, win_out_dir) - - add_missing_xcursor(x_out_dir / "cursors") - XPackager(x_out_dir, info.name, info.comment) - - WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) diff --git a/builder/gbpkg/symlinks.py b/builder/gbpkg/symlinks.py deleted file mode 100644 index d80480d..0000000 --- a/builder/gbpkg/symlinks.py +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os -from typing import Dict, List, Union - -from clickgen.util import chdir - - -def add_missing_xcursor(directory) -> None: - """Add missing `XCursor` to the Unix cursor package. - - :param directory: directory where XCursors are available. - :type directory: Union[str, Path] - """ - - symlinks: List[Dict[str, Union[str, List[str]]]] = [ - {"src": "all-scroll", "links": ["fleur", "size_all"]}, - { - "src": "bottom_left_corner", - "links": [ - "fcf1c3c7cd4491d801f1e1c78f100000", - "sw-resize", - "ne-resize", - "size_bdiag", - "nesw-resize", - "top_right_corner", - "fd_double_arrow", - ], - }, - { - "src": "bottom_right_corner", - "links": [ - "c7088f0f3e6c8088236ef8e1e3e70000", - "top_left_corner", - "se-resize", - "nw-resize", - "size_fdiag", - "nwse-resize", - "bd_double_arrow", - ], - }, - { - "src": "copy", - "links": [ - "1081e37283d90000800003c07f3ef6bf", - "6407b0e94181790501fd1e167b474872", - "b66166c04f8c3109214a4fbd64a50fc8", - "dnd-copy", - ], - }, - { - "src": "cross", - "links": [ - "cross_reverse", - "diamond_cross", - "tcross", - "color-picker", - "crosshair", - ], - }, - { - "src": "dnd_no_drop", - "links": [ - "no-drop", - # crossed_circle symlinks - "crossed_circle", - "03b6e0fcb3499374a867c041f52298f0", - "not-allowed", - "forbidden", - "circle", - ], - }, - {"src": "dotbox", "links": ["dot_box_mask", "draped_box", "icon", "target"]}, - {"src": "hand1", "links": ["grab", "openhand"]}, - { - "src": "hand2", - "links": [ - "9d800788f1b08800ae810202380a0822", - "e29285e634086352946a0e7090d73106", - "pointer", - "pointing_hand", - ], - }, - { - "src": "left_ptr", - "links": [ - "arrow", - "default", - "center_ptr", - ], - }, - { - "src": "left_ptr_watch", - "links": [ - "00000000000000020006000e7e9ffc3f", - "08e8e1c95fe2fc01f976f1e063a24ccd", - "3ecb610c1bf2410f44200f48c40d3599", - "progress", - ], - }, - { - "src": "link", - "links": [ - "3085a0e285430894940527032f8b26df", - "640fb0e74195791501fd1ed57b41487f", - "a2a266d0498c3104214a47bd64ab0fc8", - "alias", - "dnd-link", - ], - }, - { - "src": "move", - "links": [ - "4498f0e0c1937ffe01fd06f973665830", - "9081237383d90e509aa00f00170e968f", - "fcf21c00b30f7e3f83fe0dfd12e71cff", - "grabbing", - "pointer_move", - "dnd-move", - "closedhand", - "dnd-none", - ], - }, - {"src": "pencil", "links": ["draft"]}, - {"src": "plus", "links": ["cell"]}, - { - "src": "question_arrow", - "links": [ - "5c6cd98b3f3ebcb1f9c7f1c204630408", - "d9ce0ab605698f320427677b458ad60b", - "help", - "left_ptr_help", - "whats_this", - "dnd-ask", - ], - }, - {"src": "right_ptr", "links": ["draft_large", "draft_small"]}, # required - {"src": "sb_down_arrow", "links": ["down-arrow"]}, - { - "src": "sb_h_double_arrow", - "links": [ - "028006030e0e7ebffc7f7070c0600140", - "14fef782d02440884392942c1120523", - "col-resize", - "ew-resize", - "h_double_arrow", - "size-hor", - "size_hor", - "split_h", - "left_side", - "w-resize", - "right_side", - "e-resize", - ], - }, - {"src": "sb_left_arrow", "links": ["left-arrow"]}, - {"src": "sb_right_arrow", "links": ["right-arrow"]}, - {"src": "sb_up_arrow", "links": ["up-arrow"]}, - { - "src": "sb_v_double_arrow", - "links": [ - "00008160000006810000408080010102", - "2870a09082c103050810ffdffffe0204", - "double_arrow", - "ns-resize", - "row-resize", - "size-ver", - "size_ver", - "split_v", - "v_double_arrow", - "top_side", - "s-resize", - "n-resize", - "bottom_side", - ], - }, - {"src": "wait", "links": ["watch"]}, - {"src": "X_cursor", "links": ["pirate", "x-cursor"]}, - {"src": "xterm", "links": ["ibeam", "text"]}, - ] - - with chdir(directory): - for item in symlinks: - src = str(item["src"]) - for link in item.get("links"): - print(f"Creating symlink {src} -> {link}") - os.symlink(src, link) diff --git a/builder/setup.py b/builder/setup.py deleted file mode 100644 index e6cbac0..0000000 --- a/builder/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from setuptools import setup, find_packages - -setup( - name="gbpkg", - version="1.1.1", - author="Kaiz Khatri", - author_email="kaizmandhu@gamil.com", - description="Generate 'GoogleDot' cursor theme from PNGs file", - package_dir={"": "src"}, - packages=find_packages(where="src"), - install_requires=["clickgen==1.1.9"], - url="https://github.com/ful1e5/Google_Cursor", - project_urls={ - "Bug Tracker": "https://github.com/ful1e5/Google_Cursor/issues", - }, - classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - ], - python_requires=">=3.8", - zip_safe=True, -) From b2b62cbfa123c70530bdba1f68ae9e6dc7bc6ded Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 17:35:54 +0530 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=91=B7=20Import=20new=20builder=20mod?= =?UTF-8?q?ule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/build.py b/builder/build.py index 508c659..674835d 100644 --- a/builder/build.py +++ b/builder/build.py @@ -4,8 +4,8 @@ import argparse from pathlib import Path -from gbpkg.configure import get_config -from gbpkg.generator import Info, build, wbuild, xbuild +from gdbuild.configure import get_config +from gdbuild.generator import Info, build, wbuild, xbuild parser = argparse.ArgumentParser( prog="google_dot_builder", From e9ae135605af884b5bda6c3684c066c6b4da37bb Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 17:36:16 +0530 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=92=BE=20Setup=20without=20setup.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/Makefile | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/builder/Makefile b/builder/Makefile index c2a4b04..dc77a7c 100644 --- a/builder/Makefile +++ b/builder/Makefile @@ -13,17 +13,11 @@ WIN_CANVAS_SIZE ?= 32 WIN_SIZE ?= 24 clean: - @rm -rf src/*.egg-info build dist @find -iname "*.pyc" -delete + @python3 -m pip uninstall -y clickgen - # Removing setup.py package files if installed - @if [ -f "files.txt" ]; then - @xargs rm -rf < files.txt - @rm -rf files.txt - @fi - -setup: setup.py - @python3 setup.py install --user --record files.txt +setup: + @python3 -m pip install clickgen==1.1.9 --user build: setup build.py @$(foreach theme,$(THEMES), python3 build.py -p "$(bitmaps_dir)/GoogleDot-$(theme)" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);) From e97f692ad8ca305a89a9113688f609428e115e22 Mon Sep 17 00:00:00 2001 From: ful1e5 <24286590+ful1e5@users.noreply.github.com> Date: Thu, 22 Apr 2021 17:43:40 +0530 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=93=83=20Changelog=20updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba019b4..1cd848d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Makefile target re-arrange & installation process updated (Merged #10) +- Compact code inside `builder/*` +- Remove `setup.py` +- Builder module renamed to `gdbuild` +- Import `gdbuild` module directly inside `build.py` +- Windows **True HiDPi Supports** inside build.py ## [v1.1.1] - 29 Mar 2021