--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M7.5 12.2c-2.3 0-4.2-1.9-4.2-4.2s1.9-4.2 4.2-4.2 4.2 1.9 4.2 4.2c0.1 2.3-1.9 4.2-4.2 4.2zM7.5 5.2c-1.5 0-2.7 1.3-2.7 2.8s1.2 2.8 2.8 2.8 2.8-1.2 2.8-2.8-1.4-2.8-2.9-2.8z"></path>
+<path fill="#dddddd" d="M8 16c-4.4 0-8-3.6-8-8s3.6-8 8-8 8 3.6 8 8c0 1.5-0.4 3-1.2 4.2-0.3 0.5-1.1 1.2-2.3 1.2-0.8 0-1.3-0.3-1.6-0.6-0.7-0.7-0.6-1.8-0.6-1.9v-6.9h1.5v7c0 0.2 0 0.6 0.2 0.8 0 0 0.2 0.2 0.5 0.2 0.7 0 1.1-0.5 1.1-0.5 0.6-1 1-2.2 1-3.4 0-3.6-2.9-6.5-6.5-6.5s-6.6 2.8-6.6 6.4 2.9 6.5 6.5 6.5c0.7 0 1.3-0.1 1.9-0.3l0.4 1.4c-0.7 0.3-1.5 0.4-2.3 0.4z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M14 12c0 1.105-0.895 2-2 2s-2-0.895-2-2c0-1.105 0.895-2 2-2s2 0.895 2 2z"></path>
+<path fill="#dddddd" d="M11.7 16v0c-0.8 0-1.6-0.2-2.3-0.7l-6.2-3.3c-0.5-0.4-0.9-0.6-1.3-1-1.2-1.2-1.9-2.9-1.9-4.6s0.7-3.3 1.9-4.5c1.2-1.2 2.8-1.9 4.5-1.9s3.3 0.7 4.6 1.9c0.4 0.4 0.6 0.7 1 1.2l3.5 6.4c1 1.7 0.7 3.8-0.7 5.2-0.9 0.9-1.9 1.3-3.1 1.3zM6.4 1c-1.4 0-2.8 0.6-3.8 1.6s-1.6 2.4-1.6 3.8c0 1.5 0.6 2.8 1.6 3.8 0.3 0.3 0.6 0.5 1.1 0.8l6.3 3.4c0.6 0.4 1.2 0.5 1.8 0.5v0c0.9 0 1.7-0.3 2.3-1 1.1-1.1 1.3-2.7 0.5-4l-3.5-6.4c-0.3-0.4-0.5-0.7-0.8-1-1.1-0.9-2.4-1.5-3.9-1.5z"></path>
+<path fill="#dddddd" d="M11 7v-1l-1.4-0.5c-0.1-0.2-0.1-0.3-0.2-0.5l0.6-1.3-0.7-0.7-1.3 0.6c-0.2-0.1-0.3-0.1-0.5-0.2l-0.5-1.4h-1l-0.5 1.4c-0.2 0.1-0.3 0.1-0.5 0.2l-1.3-0.6-0.7 0.7 0.6 1.3c-0.1 0.2-0.1 0.3-0.2 0.5l-1.4 0.5v1l1.4 0.5c0.1 0.2 0.1 0.3 0.2 0.5l-0.6 1.3 0.7 0.7 1.3-0.6c0.2 0.1 0.3 0.2 0.5 0.2l0.5 1.4h1l0.5-1.4c0.2-0.1 0.3-0.1 0.5-0.2l1.3 0.6 0.7-0.7-0.6-1.3c0.1-0.2 0.2-0.3 0.2-0.5l1.4-0.5zM6.5 8c-0.8 0-1.5-0.7-1.5-1.5s0.7-1.5 1.5-1.5 1.5 0.7 1.5 1.5-0.7 1.5-1.5 1.5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 0c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zM8 2c1.3 0 2.5 0.4 3.5 1.1l-8.4 8.4c-0.7-1-1.1-2.2-1.1-3.5 0-3.3 2.7-6 6-6zM8 14c-1.3 0-2.5-0.4-3.5-1.1l8.4-8.4c0.7 1 1.1 2.2 1.1 3.5 0 3.3-2.7 6-6 6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M14.9 1.1c-1.4-1.4-3.7-1.4-5.1 0l-4.4 4.3c-1.4 1.5-1.4 3.7 0 5.2 0.1 0.1 0.3 0.2 0.4 0.3l1.5-1.5c-0.1-0.1-0.3-0.2-0.4-0.3-0.6-0.6-0.6-1.6 0-2.2l4.4-4.4c0.6-0.6 1.6-0.6 2.2 0s0.6 1.6 0 2.2l-1.3 1.3c0.4 0.8 0.5 1.7 0.4 2.5l2.3-2.3c1.5-1.4 1.5-3.7 0-5.1z"></path>
+<path fill="#dddddd" d="M10.2 5.1l-1.5 1.5c0 0 0.3 0.2 0.4 0.3 0.6 0.6 0.6 1.6 0 2.2l-4.4 4.4c-0.6 0.6-1.6 0.6-2.2 0s-0.6-1.6 0-2.2l1.3-1.3c-0.4-0.8-0.1-1.3-0.4-2.5l-2.3 2.3c-1.4 1.4-1.4 3.7 0 5.1s3.7 1.4 5.1 0l4.4-4.4c1.4-1.4 1.4-3.7 0-5.1-0.2-0.1-0.4-0.3-0.4-0.3z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M9 0l-7 9.4 6-0.4-5 7 13-10-7 0.5 7-6.5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 6h3c0.6 0 1-0.1 1-0.1 1.3-0.4 2-1.9 2-3.4 0-0.3-0.2-0.5-0.5-0.5s-0.5 0.2-0.5 0.5c0 1-0.5 2.5-1.8 2.5h-0.2c0 0 0.2-2.1-2-2.8v-1.7c0-0.3-0.2-0.5-0.5-0.5s-0.5 0.2-0.5 0.5v1.5c-0.2 0-0.3 0-0.5 0s-0.3 0-0.5 0v-1.5c0-0.3-0.2-0.5-0.5-0.5s-0.5 0.2-0.5 0.5v1.7c-2.2 0.7-2 2.8-2 2.8h-0.2c-1.3 0-1.8-1.5-1.8-2.5 0-0.3-0.2-0.5-0.5-0.5s-0.5 0.2-0.5 0.5c0 1.4 0.7 2.9 2 3.4 0 0 0.3 0.1 1 0.1h4zM8 3h1v1h-1v-1zM6 3h1v1h-1v-1z"></path>
+<path fill="#dddddd" d="M3 7v1c-2.8 0.1-3 1.4-3 3.5 0 0.2 0.2 0.5 0.5 0.5s0.5-0.3 0.5-0.5c0-1.8 0-2.4 2-2.5 0 0 0 1.6 0.6 3.1-0.4 0.1-0.7 0.2-0.9 0.5-0.7 0.6-0.7 1.7-0.7 2.7v0.1c0 0.3 0.2 0.6 0.5 0.6s0.5-0.3 0.5-0.5v-0.1c0-0.8 0-1.7 0.4-2.1 0.1-0.2 0.4-0.3 0.7-0.3 0.5 1 1.5 1.8 2.9 2v-8h-4z"></path>
+<path fill="#dddddd" d="M12 8v-1h-4v8c1.4-0.2 2.4-1 2.9-1.9 0.3 0 0.5 0.1 0.7 0.2 0.4 0.4 0.4 1.2 0.4 2.1v0.1c0 0.3 0.2 0.5 0.5 0.5s0.5-0.2 0.5-0.5v-0.1c0-1 0-2.1-0.7-2.8-0.2-0.2-0.6-0.4-0.9-0.5 0.6-1.5 0.6-3 0.6-3.1 2 0 2 0.7 2 2.5 0 0.3 0.2 0.5 0.5 0.5s0.5-0.2 0.5-0.5c0-2.1-0.2-3.4-3-3.5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 1c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7zM8 0c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8v0z"></path>
+<path fill="#dddddd" d="M12.2 10.8l-2.8-2.8 2.8-2.8-1.4-1.4-2.8 2.8-2.8-2.8-1.4 1.4 2.8 2.8-2.8 2.8 1.4 1.4 2.8-2.8 2.8 2.8z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M14 13l-4 1h-6l-4-1v-1h14z"></path>
+<path fill="#dddddd" d="M14.7 3h-1.7v-1h-12v5c0 1.5 0.8 2.8 2 3.4v0.6h8v-0.6c0.9-0.5 1.6-1.4 1.9-2.4 0 0 0.1 0 0.1 0 2.3 0 2.9-2 3-3.5 0.1-0.8-0.5-1.5-1.3-1.5zM13 7v-3h1.7c0.1 0 0.2 0.1 0.2 0.1s0.1 0.1 0.1 0.3c-0.2 2.6-1.6 2.6-2 2.6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 1c-4.4 0-8 2.5-8 5.5 0 2 2 3.8 4 4.8 0 0 0 0 0 0 0 2.1-2 2.8-2 2.8 2.8 0 4.4-1.3 5.1-2.1 0.3 0 0.6 0 0.9 0 4.4 0 8-2.5 8-5.5s-3.6-5.5-8-5.5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M5.2 14l4.5-12h1.1l-4.5 12z"></path>
+<path fill="#dddddd" d="M11.1 13h1.2l3.7-5-3.7-5h-1.3l3.8 5z"></path>
+<path fill="#dddddd" d="M4.9 13h-1.2l-3.7-5 3.7-5h1.3l-3.8 5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M12 10c-0.8 0-1.4 0.3-2 0.8l-3.2-1.8c0.1-0.3 0.2-0.7 0.2-1s-0.1-0.7-0.2-1l3.2-1.8c0.6 0.5 1.2 0.8 2 0.8 1.7 0 3-1.3 3-3s-1.3-3-3-3-3 1.3-3 3c0 0.2 0 0.3 0 0.5l-3.5 1.9c-0.4-0.2-0.9-0.4-1.5-0.4-1.6 0-3 1.3-3 3v0c0 1.6 1.4 3 3 3 0.6 0 1.1-0.2 1.5-0.4l3.5 1.9c0 0.2 0 0.3 0 0.5 0 1.7 1.3 3 3 3s3-1.3 3-3-1.3-3-3-3z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M11.5 8.2c-0.3-0.1-0.6-0.2-0.8-0.2h-2.7v-1h3c0-0.6-0.4-1-1-1h-4c0 0.6 0.4 1 1 1v1c-0.5 0-1-0.2-1.2-0.6l-1.1-1.8c-0.3-0.4-0.7-0.6-1.1-0.6h-0.6v-0.7c0-0.3-0.1-0.5-0.2-0.8l-0.3-0.7c-0.3-0.5-0.9-0.8-1.5-0.8h-1l5 7c0.4 0.6 1.1 1 1.8 1h1.2v1h-1v2h-0.6c-0.9 0-1.8 0.4-2.4 1v0h-1v1h11v-1h-1c-0.6-0.6-1.5-1-2.4-1h-0.6v-2h-1v-1h1.6c0.2 0 0.5 0.1 0.7 0.2l1.7 0.9c0.9 0.5 2 0.5 2.9 0h0.1l-4.5-2.9z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 0c0 0-5 8.2-5 11s2.2 5 5 5 5-2.2 5-5-5-11-5-11zM8.9 14.9l-0.2-1c1.4-0.3 2.4-1.7 2.4-3.2 0-0.3-0.1-1.1-0.8-2.6l0.9-0.4c0.6 1.4 0.8 2.4 0.8 3 0 2-1.3 3.8-3.1 4.2z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 0c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zM13.2 5.3c0.4 0 0.7 0.3 1.1 0.3-0.3 0.4-1.6 0.4-2-0.1 0.3-0.1 0.5-0.2 0.9-0.2zM1 8c0-0.4 0-0.8 0.1-1.3 0.1 0 0.2 0.1 0.3 0.1 0 0 0.1 0.1 0.1 0.2 0 0.3 0.3 0.5 0.5 0.5 0.8 0.1 1.1 0.8 1.8 1 0.2 0.1 0.1 0.3 0 0.5-0.6 0.8-0.1 1.4 0.4 1.9 0.5 0.4 0.5 0.8 0.6 1.4 0 0.7 0.1 1.5 0.4 2.2-2.5-1.2-4.2-3.6-4.2-6.5zM8 15c-0.7 0-1.5-0.1-2.1-0.3-0.1-0.2-0.1-0.4 0-0.6 0.4-0.8 0.8-1.5 1.3-2.2 0.2-0.2 0.4-0.4 0.4-0.7 0-0.2 0.1-0.5 0.2-0.7 0.3-0.5 0.2-0.8-0.2-0.9-0.8-0.2-1.2-0.9-1.8-1.2s-1.2-0.5-1.7-0.2c-0.2 0.1-0.5 0.2-0.5-0.1 0-0.4-0.5-0.7-0.4-1.1-0.1 0-0.2 0-0.3 0.1s-0.2 0.2-0.4 0.1c-0.2-0.2-0.1-0.4-0.1-0.6 0.1-0.2 0.2-0.3 0.4-0.4 0.4-0.1 0.8-0.1 1 0.4 0.3-0.9 0.9-1.4 1.5-1.8 0 0 0.8-0.7 0.9-0.7s0.2 0.2 0.4 0.3c0.2 0 0.3 0 0.3-0.2 0.1-0.5-0.2-1.1-0.6-1.2 0-0.1 0.1-0.1 0.1-0.1 0.3-0.1 0.7-0.3 0.6-0.6 0-0.4-0.4-0.6-0.8-0.6-0.2 0-0.4 0-0.6 0.1-0.4 0.2-0.9 0.4-1.5 0.4 1.1-0.8 2.5-1.2 3.9-1.2 0.3 0 0.5 0 0.8 0-0.6 0.1-1.2 0.3-1.6 0.5 0.6 0.1 0.7 0.4 0.5 0.9-0.1 0.2 0 0.4 0.2 0.5s0.4 0.1 0.5-0.1c0.2-0.3 0.6-0.4 0.9-0.5 0.4-0.1 0.7-0.3 1-0.7 0-0.1 0.1-0.1 0.2-0.2 0.6 0.2 1.2 0.6 1.8 1-0.1 0-0.1 0.1-0.2 0.1-0.2 0.2-0.5 0.3-0.2 0.7 0.1 0.2 0 0.3-0.1 0.4-0.2 0.1-0.3 0-0.4-0.1s-0.1-0.3-0.4-0.3c-0.1 0.2-0.4 0.3-0.4 0.6 0.5 0 0.4 0.4 0.5 0.7-0.6 0.1-0.8 0.4-0.5 0.9 0.1 0.2-0.1 0.3-0.2 0.4-0.4 0.6-0.8 1-0.8 1.7s0.5 1.4 1.3 1.3c0.9-0.1 0.9-0.1 1.2 0.7 0 0.1 0.1 0.2 0.1 0.3 0.1 0.2 0.2 0.4 0.1 0.6-0.3 0.8 0.1 1.4 0.4 2 0.1 0.2 0.2 0.3 0.3 0.4-1.3 1.4-3 2.2-5 2.2z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 32 32">
+ <path fill="#dddddd" d="M18 13 L26 2 8 13 14 19 6 30 24 19 Z" />
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M7.1 1.7l-1.2 1.1-2.3-2.4c-0.6-0.5-1.6-0.5-2.2 0-0.2 0.3-0.4 0.7-0.4 1.1s0.2 0.8 0.4 1.1l2.4 2.4-3.8 3.7 6.4 6.4 7-7.1-6.3-6.3zM2.1 1.9c0-0.1-0.1-0.3-0.1-0.4s0.1-0.3 0.1-0.4c0.2-0.1 0.6-0.1 0.8 0l2.4 2.4-0.8 0.7-2.4-2.3zM2.1 8l3.8-3.8 1.2 1.2c0.1 0.1 0.2 0.1 0.4 0.1s0.3 0 0.4-0.1c0.1-0.2 0.1-0.5-0.1-0.7l-1.2-1.2 0.4-0.4 5 4.9h-9.9z"></path>
+<path fill="#dddddd" d="M13.5 9c0 0-1.5 4.7-1.5 5.5s0.7 1.5 1.5 1.5 1.5-0.7 1.5-1.5-1.5-5.5-1.5-5.5z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M0 5h3v1h-3v-1z"></path>
+<path fill="#dddddd" d="M5 0h1v3h-1v-3z"></path>
+<path fill="#dddddd" d="M6 11h-1v-2.5l1 1z"></path>
+<path fill="#dddddd" d="M11 6h-1.5l-1-1h2.5z"></path>
+<path fill="#dddddd" d="M3.131 7.161l0.707 0.707-2.97 2.97-0.707-0.707 2.97-2.97z"></path>
+<path fill="#dddddd" d="M10.131 0.161l0.707 0.707-2.97 2.97-0.707-0.707 2.97-2.97z"></path>
+<path fill="#dddddd" d="M0.836 0.199l3.465 3.465-0.707 0.707-3.465-3.465 0.707-0.707z"></path>
+<path fill="#dddddd" d="M6.1 4.1l-2.1 2 9.8 9.9 2.2-2.1-9.9-9.8zM6.1 5.5l2.4 2.5-0.6 0.6-2.5-2.5 0.7-0.6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M12 0h-7v6h0.7l0.2 0.7 0.1 0.1v-5.8h5v4h4v9h-6l0.3 0.5-0.5 0.5h7.2v-11l-4-4zM12 4v-3l3 3h-3z"></path>
+<path fill="#dddddd" d="M5.5 11.5c0 0.552-0.448 1-1 1s-1-0.448-1-1c0-0.552 0.448-1 1-1s1 0.448 1 1z"></path>
+<path fill="#dddddd" d="M7.9 12.4l1.1-0.4v-1l-1.1-0.4c-0.1-0.3-0.2-0.6-0.4-0.9l0.5-1-0.7-0.7-1 0.5c-0.3-0.2-0.6-0.3-0.9-0.4l-0.4-1.1h-1l-0.4 1.1c-0.3 0.1-0.6 0.2-0.9 0.4l-1-0.5-0.7 0.7 0.5 1.1c-0.2 0.3-0.3 0.6-0.4 0.9l-1.1 0.3v1l1.1 0.4c0.1 0.3 0.2 0.6 0.4 0.9l-0.5 1 0.7 0.7 1.1-0.5c0.3 0.2 0.6 0.3 0.9 0.4l0.3 1.1h1l0.4-1.1c0.3-0.1 0.6-0.2 0.9-0.4l1 0.5 0.7-0.7-0.5-1.1c0.2-0.2 0.3-0.5 0.4-0.8zM4.5 13.5c-1.1 0-2-0.9-2-2s0.9-2 2-2 2 0.9 2 2c0 1.1-0.9 2-2 2z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 0l-8 8 8 8 8-8-8-8zM2 8l6-6 6 6-6 6-6-6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M8 3.1l1.4 2.2-1.6 1.1 1.3 0.3 2.8 0.6 0.6-2.7 0.4-1.4-1.8 1.1-2-3.3h-2.2l-2.6 4.3 1.7 1z"></path>
+<path fill="#dddddd" d="M16 12l-2.7-4.3-1.7 1 2 3.3h-2.6v-2l-3 3 3 3v-2h3.7z"></path>
+<path fill="#dddddd" d="M2.4 12v0l1.4-2.3 1.7 1.1-0.9-4.2-2.8 0.7-1.3 0.3 1.6 1-2.1 3.4 1.3 2h5.7v-2z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M0 1v15h16v-15h-16zM5 15h-4v-2h4v2zM5 12h-4v-2h4v2zM5 9h-4v-2h4v2zM5 6h-4v-2h4v2zM10 15h-4v-2h4v2zM10 12h-4v-2h4v2zM10 9h-4v-2h4v2zM10 6h-4v-2h4v2zM15 15h-4v-2h4v2zM15 12h-4v-2h4v2zM15 9h-4v-2h4v2zM15 6h-4v-2h4v2z"></path>
+</svg>
: base (fullPath, editorPath) {
}
protected SyntaxRootNode root;
- public SyntaxRootNode Root => root;
- public bool IsParsed => root != null && Tokens.Length > 0;
- //public SyntaxNode EditedNode { get; protected set; }
+ public Command CMDRefreshSyntaxTree;
+ protected override void initCommands()
+ {
+ base.initCommands();
+ CMDRefreshSyntaxTree = new ActionCommand ("Reparse", parse, "#icons.refresh.svg", true);
+ }
+ public SyntaxRootNode Root => root;
+ public bool IsParsed => root != null && Tokens.Length > 0;
public ReadOnlySpan<Token> Tokens => root.Tokens;
public IEnumerable<SyntaxNode> SyntaxRootChildNodes => root?.children;
+
public Token FindTokenIncludingPosition (int pos) {
if (!IsParsed || pos == 0 || Tokens.Length == 0)
return default;
int idx = Tokens.BinarySearch(new Token () {Start = pos});
return idx == 0 ? 0 : idx < 0 ? ~idx - 1 : idx;
}
-
-
/// <summary>
/// if outermost is true, return oldest ancestor exept root node, useful for folding.
/// </summary>
//Console.WriteLine ($"CurrentToken: idx({currentTokenIndex}) {currentToken} {RootNode.Root.GetTokenStringByIndex(currentTokenIndex)}");
}
- /*static bool tryReplaceNode (SyntaxNode editedNode, SyntaxNode newNode) {
- if (newNode is SyntaxRootNode || editedNode is SyntaxRootNode)
- return false;
- editedNode.Replace (newNode);
- return true;
- }
- */
public virtual Color GetColorForToken (TokenType tokType) {
if (tokType.HasFlag (TokenType.Punctuation))
return Colors.DarkGrey;
+ if (tokType.HasFlag (TokenType.WhiteSpace))
+ return Colors.Gainsboro;
if (tokType.HasFlag (TokenType.Trivia))
return Colors.Silver;
if (tokType == TokenType.Keyword)
void parse () {
SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
root = syntaxAnalyser?.Process ();
- NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
+ NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
+ NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
+ NotifyValueChanged ("SyntaxRootChildNodes", SyntaxRootChildNodes);
+
+ //CurrentNode?.ExpandToTheTop();
+
//CrowEditBase.App.Log (LogType.Low, $"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)");
}
foreach (SyntaxNode node in children)
node.Dump (level + 1);
}
- public override string ToString() => $"l:({StartLine,3},{LineCount,3}) tks:{TokenIndexBase},{TokenCount} {this.GetType().Name}";
+ //public override string ToString() => $"l:({StartLine,3},{LineCount,3}) tks:{TokenIndexBase},{TokenCount} {this.GetType().Name}";
+ public override string ToString() => $"{this.GetType().Name}";
public string AsText() {
return Span.Length < 0 ? "" : Root.GetText(Span).ToString();
}
CurrentEditor?.RegisterForGraphicUpdate ();
}
}
+ public bool ShowWhiteSpace {
+ get => Configuration.Global.Get<bool> ("ShowWhiteSpace", false);
+ set {
+ if (ShowWhiteSpace == value)
+ return;
+ Configuration.Global.Set ("ShowWhiteSpace", value);
+ NotifyValueChanged ("ShowWhiteSpace", ShowWhiteSpace);
+
+ CurrentEditor?.RegisterForGraphicUpdate ();
+ }
+ }
+
public bool IndentWithSpace {
get => Configuration.Global.Get<bool> ("IndentWithSpace", false);
set {
using System.Collections.Generic;
using Drawing2D;
using System.Linq;
-using CrowEditBase;
using System.Threading;
using System.ComponentModel;
using static CrowEditBase.CrowEditBase;
+using Crow;
-namespace Crow
+namespace CrowEditBase
{
public interface IDocumentClient {
ContextCommands = new CommandGroup (CMDCut, CMDCopy, CMDPaste);
}
- public TextDocument Document {
+ public virtual TextDocument Document {
get => document;
set {
if (document == value)
RegisterForRedraw ();
- (IFace as CrowEditBase.CrowEditBase).CurrentEditor = this;
+ (IFace as CrowEditBase).CurrentEditor = this;
}
public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
base.onMouseEnter (sender, e);
--- /dev/null
+using System;
+using System.IO;
+using System.Linq;
+using System.Collections.Generic;
+using System.Text;
+using Crow;
+using Crow.Text;
+using CrowEditBase;
+using System.Reflection;
+
+namespace CrowEdit
+{
+ public static class Extensions
+ {
+ public static Picture GetIcon (this MemberInfo mi)
+ => mi is EventInfo ? new BmpPicture("#Icons.event.png") : new BmpPicture("#Icons.property.png");
+
+ }
+}
using Crow.Text;
using Drawing2D;
using System.Collections;
-using CrowEditBase;
using static CrowEditBase.CrowEditBase;
using System.Collections.Generic;
using System.Linq;
-using System.Collections.Frozen;
+using Crow;
+using System.Text.Unicode;
+using System.Text;
-namespace Crow
+namespace CrowEditBase
{
- public class Suggestion {
- public string Caption;
- public TextChange Change;
- public TextSpan? NextSelection;
-
- public Suggestion(string caption, TextChange change = default, int finalPositionOffset = 0) {
- Caption = caption;
- Change = change;
- NextSelection = finalPositionOffset < 0 ? TextSpan.FromStartAndLength(change.End2 + finalPositionOffset) : null;
- }
- }
public class SourceEditor : Editor {
- int currentTokenIndex = -1;
+ SourceDocument sourceDocument;
+ public override TextDocument Document {
+ get => base.Document;
+ set {
+ base.Document = value;
+ sourceDocument = Document as SourceDocument;
+ }
+ }
+ int currentTokenIndex = -1;
SyntaxNode currentNode;
#if DEBUG_NODE
SyntaxNode _hoverNode;
}
}
- public Token CurrentToken => typeof(SourceDocument).IsAssignableFrom(Document?.GetType()) ?
- (Document as SourceDocument).GetTokenByIndex(currentTokenIndex) : default;
+ public Token CurrentToken => sourceDocument != null && sourceDocument.IsParsed ?
+ sourceDocument.GetTokenByIndex(currentTokenIndex) : default;
+
+#if DEBUG
+ public string CurrentTokenString => sourceDocument != null && sourceDocument.IsParsed ?
+ CurrentToken.AsString(Document.source) : null;
+ public string CurrentTokenType => sourceDocument != null && sourceDocument.IsParsed ?
+ sourceDocument.GetTokenTypeString(CurrentToken.Type) : default;
+#endif
#region suggestions and autocomplete
ListBox overlay;
void showOverlay () {
lock (IFace.UpdateMutex) {
if (overlay == null) {
- overlay = IFace.Load<ListBox>(@"#ui.SuggestionsOverlay.crow");
+ //overlay = IFace.Load<ListBox>(@"#ui.SuggestionsOverlay.crow");
+ overlay = IFace.LoadIMLFragment<ListBox>(@"
+ <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread = 'false'>
+ <ItemTemplate>
+ <ListItem Height='Fit' Margin='2' Focusable='false' HorizontalAlignment='Left' Width='Stretched'
+ Selected = '{Background=${ControlHighlight}}'
+ Unselected = '{Background=Transparent}'>
+ <HorizontalStack Width='Stretched' >
+ <Image Path='{Icon}' Width='12' Height='12'/>
+ <Label Text='{Caption}' HorizontalAlignment='Left' Width='Stretched'/>
+ </HorizontalStack>
+ <!--<Label Text='{Caption}' HorizontalAlignment='Left' Width='Stretched'/>-->
+ </ListItem>
+ </ItemTemplate>
+ <ItemTemplate DataType='CrowEditBase.ColorSuggestion'>
+ <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' Width='Stretched'
+ Selected = '{Background=${ControlHighlight}}'
+ Unselected = '{Background=Transparent}'>
+ <HorizontalStack Width='Stretched' >
+ <Image Margin='6' Path='{Icon}' Width='32' Height='24' Background='{Fill}' CornerRadius='2'/>
+ <Label Text='{Caption}' HorizontalAlignment='Left' Width='Stretched'/>
+ </HorizontalStack>
+ <!--<Label Text='{Caption}' HorizontalAlignment='Left' Width='Stretched'/>-->
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ ");
overlay.DataSource = this;
overlay.Loaded += (sender, arg) => (sender as ListBox).SelectedIndex = 0;
} else
void hideOverlay () {
if (overlay == null)
return;
- overlay.IsVisible = false;
+ lock(App.UpdateMutex)
+ overlay.IsVisible = false;
}
void completeToken () {
+ disableSuggestions = true;
if (Document is SourceDocument srcDoc) {
if (overlay.SelectedItem is Suggestion sug) {
update (sug.Change);
}
}
hideOverlay ();
- tryGetSuggestions ();
+ disableSuggestions = false;
+ //tryGetSuggestions ();
}
#endregion
DbgLogger.EndEvent(DbgEvtType.GOMeasure);
}
}
+
+ #region Mouse & Keyboard overrides
public override void onMouseDown (object sender, MouseButtonEventArgs e) {
hideOverlay ();
if (mouseIsInMargin) {
case Key.KeypadEnter:
//doc.updateCurrentTokAndNode (Selection.Start);
//Console.WriteLine ($"*** Current Token: {doc.CurrentToken} Current Node: {doc.CurrentNode}");
- update (new TextChange (selection.Start, selection.Length, Document.GetLineBreak ()));
+ if (currentLoc.HasValue) {
+ TextLine tl = doc.GetLine(currentLoc.Value.Line);
+ int firstTok = doc.FindTokenIndexIncludingPosition(tl.Start);
+ int i = firstTok;
+ Token tok = doc.GetTokenByIndex(i);
+ StringBuilder sb = new StringBuilder(20);
+ while (tok.End < tl.End && tok.Type.HasFlag(TokenType.WhiteSpace)) {
+ if (tok.Type == TokenType.Tabulation)
+ sb.Append(new string('\t', tok.Length));
+ else if (tok.Type == TokenType.WhiteSpace)
+ sb.Append(new string(' ', tok.Length));
+ else
+ break;
+ tok = doc.GetTokenByIndex(++i);
+ }
+ update (new TextChange (selection.Start, selection.Length, Document.GetLineBreak () + sb.ToString()));
+ } else
+ update (new TextChange (selection.Start, selection.Length, Document.GetLineBreak ()));
autoAdjustScroll = true;
IFace.forceTextCursor();
e.Handled = true;
Document.ExitReadLock ();
}*/
}
-
+ #endregion
SyntaxNode getFoldStartingAt (int line) {
if (!(Document is SourceDocument doc))
Foreground.SetAsSource (IFace, gr);
+ bool showWhiteSpaces = App.ShowWhiteSpace;
+ string tabString = showWhiteSpaces ?
+ $"{new string(' ', (App.TabulationSize - 2) / 2)} \u2192{new string(' ', (App.TabulationSize - 2) / 2)}" : default;
ReadOnlySpan<char> sourceBytes = doc.source;
Span<byte> bytes = stackalloc byte[128];
TextExtents extents;
int tokPtr = doc.FindTokenIndexIncludingPosition(curTxtLine.Start);
Token tok = doc.Tokens[tokPtr];
- while (tok.Start < curTxtLine.End) {
- buff = sourceBytes.Slice (tok.Start, tok.Length);
+ while (tok.Start < (showWhiteSpaces ? curTxtLine.EndIncludingLineBreak : curTxtLine.End)) {
+ if (showWhiteSpaces && tok.Type.HasFlag(TokenType.WhiteSpace)) {
+
+ if(tok.Type == TokenType.WhiteSpace) {
+ buff = new string('·', tok.Length);
+ } if(tok.Type == TokenType.Tabulation) {
+ buff = new StringBuilder(tok.Length*tabString.Length).Insert(0,tabString,tok.Length).ToString() ;
+ } else if (tok.Type == TokenType.LineBreak) {
+ buff = new string('\u204B', tok.Length);
+ }
+ /*gr.MoveTo (pixX, pixY + fe.Ascent);
+ gr.ShowText (buff);*/
+ } else
+ buff = sourceBytes.Slice (tok.Start, tok.Length);
gr.SetSource (doc.GetColorForToken (tok.Type));
int size = buff.Length * 4 + 1;
tryGetSuggestions ();
RegisterForGraphicUpdate();
-
- lock (IFace.UpdateMutex) {
- if (Document is SourceDocument doc) {
- doc.NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
- doc.NotifyValueChanged ("SyntaxRootChildNodes", doc.SyntaxRootChildNodes);
- CurrentNode?.ExpandToTheTop();
- }
- }
- //Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
}
void updateCurrentTokAndNode() {
if (currentLoc.HasValue && Document is SourceDocument srcdoc) {
CurrentNode = srcdoc.Root?.FindNodeIncludingSpan(tok.Span);
NotifyValueChanged("CurrentToken",tok);
+#if DEBUG
+ NotifyValueChanged("CurrentTokenString",CurrentTokenString);
+ NotifyValueChanged("CurrentTokenType",CurrentTokenType);
+#endif
+
+
} else {
currentTokenIndex = -1;
CurrentNode = null;
--- /dev/null
+// Copyright (c) 2013-2025 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
+using Crow.Text;
+using System.Reflection;
+using Crow;
+
+namespace CrowEditBase
+{
+ public class Suggestion {
+ public string Caption;
+ public TextChange Change;
+ public TextSpan? NextSelection;
+ public virtual string Icon => "#icons.property.svg";
+
+ public Suggestion(string caption, TextChange change = default, int finalPositionOffset = 0) {
+ Caption = caption;
+ Change = change;
+ NextSelection = finalPositionOffset < 0 ? TextSpan.FromStartAndLength(change.End2 + finalPositionOffset) : null;
+ }
+ }
+ public class MemberInfoSuggestion : Suggestion {
+ public MemberInfo MemberInfo;
+ public MemberInfoSuggestion(MemberInfo memberInfo, TextChange change = default, int finalPositionOffset = 0)
+ : base(memberInfo.Name, change, finalPositionOffset) {
+ MemberInfo = memberInfo;
+ }
+ }
+ public class WidgetSuggestion : Suggestion {
+ public Type Type;
+ public override string Icon => $"#icons.{Type.FullName}.svg";
+ public WidgetSuggestion(Type type, TextChange change = default, int finalPositionOffset = 0)
+ : base(type.Name, change, finalPositionOffset) {
+ Type = type;
+ }
+ }
+ public class ColorSuggestion : Suggestion {
+ public Fill Fill;
+ public override string Icon => $"#icons.fill.svg";
+ public ColorSuggestion(Fill fill, TextChange change = default, int finalPositionOffset = 0)
+ : base(fill.ToString(), change, finalPositionOffset) {
+ Fill = fill;
+ }
+ }
+}
\ No newline at end of file
Foreground="White";
Margin = "1";
}
+TreeLabel2 {
+ Foreground="Black";
+ Background="LightGrey";
+ Margin = "1";
+ Font = "sans, 9";
+}
+
Splitter {
Thickness="1";
Background="Transparent";
<ScrollBar Name="scrollbar1" Value="{²../ItemsScroller.ScrollY}"
LargeIncrement="{../ItemsScroller.PageHeight}" SmallIncrement="30" CursorSize="{../ItemsScroller.ChildHeightRatio}"
Maximum="{../ItemsScroller.MaxScrollY}" Orientation="Vertical"
- Width="10" />
+ Width="12" />
</HorizontalStack>
</Border>
<Label Text='{Caption}' HorizontalAlignment='Left' Margin="2"/>
</ListItem>
</ItemTemplate>
- <ItemTemplate DataType='System.Reflection.MemberInfo'>
+
+ <ItemTemplate DataType='Crow.MemberInfoSuggestion'>
<ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
Selected = '{Background=${ControlHighlight}}'
Unselected = '{Background=Transparent}'>
<HorizontalStack>
<!--<Image Picture='{GetIcon}' Width='16' Height='16'/>-->
- <Label Text='{Name}' HorizontalAlignment='Left' />
+ <Label Text='{Caption}' HorizontalAlignment='Left' />
</HorizontalStack>
</ListItem>
</ItemTemplate>
- <ItemTemplate DataType='Crow.Colors'>
+ <!--<ItemTemplate DataType='Crow.Colors'>
<ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
Selected = '{Background=${ControlHighlight}}'
Unselected = '{Background=Transparent}'>
<Label Text='{}' HorizontalAlignment='Left' />
</HorizontalStack>
</ListItem>
- </ItemTemplate>
+ </ItemTemplate>-->
</ListBox>
\ No newline at end of file
<?xml version="1.0"?>
<ListItem IsVisible="{IsSelected}" IsSelected="{²IsSelected}" Selected="{/tb.HasFocus='true'}">
<VerticalStack Spacing="0">
- <HorizontalStack Spacing="0" Background="White">
+ <HorizontalStack Spacing="0" Background="WhiteSmoke">
<SourceEditor Name="tb" Font="mono, 14" Margin='0' CurrentNode="{CurrentNode}"
Document="{}" TextChanged="onTextChanged" />
<ScrollBar Value="{²../tb.ScrollY}"
<HorizontalStack Height="Fit" Spacing='3'>
<Widget Width="Stretched"/>
<Label Text="TokType" Foreground="Grey"/>
- <Label Text="{CurrentTokenType}" Margin="3"/>
+ <Label Text="{../../tb.CurrentTokenType}" Margin="3"/>
<Label Text="Tok" Foreground="Grey"/>
- <Label Text="{CurrentTokenString}" Margin="3"/>
+ <Label Text="{../../tb.CurrentTokenString}" Margin="3"/>
<Label Text="Node" Foreground="Grey"/>
- <Label Text="{CurrentNode}" Margin="3"/>
+ <Label Text="{../../tb.CurrentNode}" Margin="3"/>
<Label Text="MouseY:" Foreground="Grey"/>
<Label Text="{../../tb.MouseY}" Margin="3"/>
<Label Text="VisibleLines:" Foreground="Grey"/>
-// Copyright (c) 2013-2021 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+// Copyright (c) 2013-2025 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System.Linq;
using Crow.Text;
using System.Collections.Generic;
-using System.Diagnostics;
using Crow;
using IML = Crow.IML;
-using System.Collections;
using System.Reflection;
using CrowEditBase;
using static CrowEditBase.CrowEditBase;
using CrowEdit.Xml;
-
-using AttributeSyntax = CrowEdit.Xml.AttributeSyntax;
using Drawing2D;
namespace CECrowPlugin
protected override SyntaxAnalyser CreateSyntaxAnalyser() => new ImlSyntaxAnalyser (this);
public override string GetTokenTypeString (TokenType tokenType) => ((ImlTokenType)tokenType).ToString();
- string[] allWidgetNames = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t))
- .Select (s => s.Name).ToArray ();
-
IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
protected override IEnumerable<Suggestion> getElementNameSuggestions(string curName, TextChange change)
{
- IEnumerable<Type> widgetTypes = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t));
+ IEnumerable<Type> widgetTypes = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>
+ typeof(Widget).IsAssignableFrom (t) && !t.IsAbstract);
int curNameLength = 0;
if (!string.IsNullOrEmpty(curName)) {
widgetTypes = widgetTypes.Where(t=>t.Name.StartsWith(curName, StringComparison.OrdinalIgnoreCase));
}
int endPosOffset = change.HasNewText ? -change.ChangedText.Length : 0;
return widgetTypes.Select (t
- => new Suggestion(t.Name,
+ => new WidgetSuggestion(t,
new TextChange(change.Start, change.Length, t.Name + change.ChangedText), endPosOffset));
}
protected override IEnumerable<Suggestion> getAttributeNameSuggestions(string eltName, string curName, TextChange change) {
int endPosOffset = change.HasNewText ? -1 : 0;
- return getAllCrowTypeMembers(eltName).Select(m
- => new Suggestion(m.Name,
+ var members = getAllCrowTypeMembers(eltName);
+ if (!string.IsNullOrEmpty(curName))
+ members = members.Where(m =>
+ m.Name.StartsWith (curName, StringComparison.OrdinalIgnoreCase));
+ return members.Select(m
+ => new MemberInfoSuggestion(m,
new TextChange(change.Start, change.Length, m.Name + change.ChangedText), endPosOffset));
}
+ protected override IEnumerable<Suggestion> getAttributeValueSuggestions(string eltName, string attribName, string attribValue, TextChange change) {
+ MemberInfo mi = getAllCrowTypeMembers(eltName).Where(m=>m.Name.Equals(attribName, StringComparison.Ordinal)).FirstOrDefault();
+ if (mi is PropertyInfo pi) {
+ if (pi.Name == "Style")
+ return App.Styling.Keys
+ .Where (s => s.StartsWith (attribValue, StringComparison.OrdinalIgnoreCase))
+ .Select(s=>new Suggestion(s,
+ new TextChange(change.Start, change.Length, s + change.ChangedText)));
+ if (pi.PropertyType.IsEnum)
+ return Enum.GetNames (pi.PropertyType)
+ .Where (s => s.StartsWith (attribValue, StringComparison.OrdinalIgnoreCase))
+ .Select(s=>new Suggestion(s,
+ new TextChange(change.Start, change.Length, s + change.ChangedText)));
+ if (pi.PropertyType == typeof(bool))
+ return (new string[] {"true", "false"}).
+ Where (s => s.StartsWith (attribValue, StringComparison.OrdinalIgnoreCase))
+ .Select(s=>new Suggestion(s,
+ new TextChange(change.Start, change.Length, s + change.ChangedText)));
+ if (pi.PropertyType == typeof (Measure))
+ return (new string[] {"Stretched", "Fit"}).
+ Where (s => s.StartsWith (attribValue, StringComparison.OrdinalIgnoreCase))
+ .Select(s=>new Suggestion(s,
+ new TextChange(change.Start, change.Length, s + change.ChangedText)));
+ if (pi.PropertyType == typeof (Fill))
+ return EnumsNET.Enums.GetValues<Colors> ()
+ .Where (s => s.ToString().StartsWith (attribValue, StringComparison.OrdinalIgnoreCase))
+ .Select(c=>new ColorSuggestion(c,
+ new TextChange(change.Start, change.Length, c + change.ChangedText)));
+ }
+ return null;
+ }
/*public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) {
IList sugs = base.GetSuggestions (absoluteTextPos, currentTokenIndex, CurrentNode, loc);
if (sugs != null)
public override string GetTokenTypeString (TokenType tokenType) => ((XmlTokenType)tokenType).ToString();
protected virtual IEnumerable<Suggestion> getElementNameSuggestions(string curName, TextChange change) => null;
- protected virtual IEnumerable<Suggestion> getAttributeNameSuggestions(string eltName, string curName, TextChange change) => null;
+ protected virtual IEnumerable<Suggestion> getAttributeNameSuggestions(string eltName, string attribName, TextChange change) => null;
+ protected virtual IEnumerable<Suggestion> getAttributeValueSuggestions(string eltName, string attribName, string attribValue, TextChange change) => null;
public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) {
Token tok = GetTokenByIndex(currentTokenIndex);
if (tok.Start != absoluteTextPos //middle of edited tok
- && tok.End != absoluteTextPos) //occurs when curTok is last tok of text
+ && currentTokenIndex >= CurrentNode?.Root.TokenCount - 1) //occurs when curTok is last tok of text
{
return null;
}
change = new TextChange (prevTok.Start, prevTok.Length);
else if (prevTok.Is(XmlTokenType.ElementOpen))
change = new TextChange (prevTok.End, 0);
- else if (prevTok.Type.HasFlag(TokenType.Trivia) && eltStartTag.name.HasValue) {
- //attribute
- change = new TextChange(tok.Start, 0);
+ else if (eltStartTag.name.HasValue) {
+ string attribName = "";
+ if (prevTok.Type.HasFlag(TokenType.Trivia) ||
+ (tok.Type.HasFlag(TokenType.Trivia) && GetTokenByIndex(currentTokenIndex+1).Type.HasFlag(TokenType.Trivia)))//attribute
+ change = new TextChange(tok.Start, 0);
+ else if (prevTok.Is(XmlTokenType.AttributeName)) {
+ change = new TextChange(prevTok.Start, prevTok.Length);
+ attribName = prevTok.AsString(source);
+ } else
+ return null;
if (!tok.Is(XmlTokenType.EqualSign))
change.ChangedText += "=\"\"";
- return getAttributeNameSuggestions(eltStartTag.Name, null, change).ToList();
-
+ return getAttributeNameSuggestions(eltStartTag.Name, attribName, change).ToList();
} else
return null;
return getElementNameSuggestions(eltStartTag.Name, change).ToList();
}
- } else if (CurrentNode is AttributeSyntax attrib) {
+ } else if (CurrentNode is AttributeSyntax attrib &&
+ attrib.Parent is ElementStartTagSyntax eltStart &&
+ eltStart.name.HasValue) {
+
if (prevTok.Is(XmlTokenType.AttributeName)) {
+ TextChange change = new TextChange(prevTok.Start, prevTok.End);
+ if (!tok.Is(XmlTokenType.EqualSign))
+ change.ChangedText += "=\"\"";
+ return getAttributeNameSuggestions(eltStart.Name, attrib.Name, change).ToList();
+ } else if (attrib.name.HasValue) {
+ if (prevTok.Is(XmlTokenType.AttributeValueOpen)) {
+ return getAttributeValueSuggestions(eltStart.Name, attrib.Name, "",
+ tok.Is(XmlTokenType.AttributeValueClose) ?
+ new TextChange(prevTok.End, 0)
+ : new TextChange(prevTok.End, 0, "\""))?.ToList();
+ } else if (prevTok.Is(XmlTokenType.AttributeValue) && attrib.valueTok.HasValue) {
+ return getAttributeValueSuggestions(eltStart.Name, attrib.Name, attrib.Value,
+ tok.Is(XmlTokenType.AttributeValueClose) ?
+ new TextChange(prevTok.Start, prevTok.Length)
+ : new TextChange(tok.Start, tok.Length, "\""))?.ToList();
+ }
}
XmlTokenType xmlTokType = (XmlTokenType)tokType;
if (xmlTokType.HasFlag (XmlTokenType.Punctuation))
return Colors.DarkGrey;
+ if (tokType.HasFlag (TokenType.WhiteSpace))
+ return Colors.Silver;
if (xmlTokType.HasFlag (XmlTokenType.Trivia))
return Colors.DimGrey;
else if (xmlTokType == XmlTokenType.ElementName)
currentNode.RemoveChild (tag);
currentNode = currentNode.AddChild (new ElementSyntax (tag));
} else if (curTok.GetTokenType() == XmlTokenType.EmptyElementClosing) {
+ tag.close = tokIdx - tag.TokenIndexBase;
finishCurrentNode ();
currentNode.RemoveChild (tag);
currentNode = currentNode.AddChild (new EmptyElementSyntax (tag));
new ActionCommand("Projects", () => LoadWindow ("#CrowEdit.ui.windows.winProjects.crow", this)),
new ActionCommand("Logs", () => LoadWindow ("#CrowEdit.ui.windows.winLogs.crow", this), "#icons.log.svg"),
new ActionCommand("Services", () => LoadWindow ("#CrowEdit.ui.windows.winServices.crow", this), "#icons.services.svg"),
- new ActionCommand("Plugins", () => LoadWindow ("#CrowEdit.ui.windows.winPlugins.crow", this), "#icons.plugins.svg"),
+ new ActionCommand("Plugins", () => LoadWindow ("#CrowEdit.ui.windows.winPlugins.crow", this), "#icons.puzzle-piece.svg"),
new ActionCommand("Syntax Tree", () => LoadWindow ("#CrowEdit.ui.windows.winSyntaxExplorer.crow", this), "#icons.plugins.svg")
);
CMDHelp = new ActionCommand("Help", () => System.Diagnostics.Debug.WriteLine("help"), "#icons.question.svg");
using Crow;
using Crow.Text;
using CrowEditBase;
+using System.Reflection;
namespace CrowEdit
{
public static TreeNode [] GetFileSystemTreeNodeOrdered (this DirectoryInfo di)
=> di.GetFileSystemInfos ().OrderBy (f => f.Attributes).ThenBy (f => f.Name).Cast<TreeNode> ().ToArray ();
-
}
}
<VerticalStack>
<CheckBox Caption="Print line number" IsChecked="{²PrintLineNumbers}"/>
<CheckBox Caption="Reopen last file" IsChecked="{²ReopenLastFile}"/>
- <CheckBox Caption="Indent With Space" IsChecked="{²IndentWithSpace}"/>
+ <CheckBox Caption="Indent With Spaces" IsChecked="{²IndentWithSpace}"/>
+ <CheckBox Caption="Show White Spaces" IsChecked="{²ShowWhiteSpace}"/>
<Spinner Caption="Tabulation Size" Value="{²TabulationSize}"/>
<Slider Template="#ui.slider.tmp" Height="Fit" Background="0.1,0.1,0.2,0.8"
Minimum="1" Maximum="50" SmallIncrement="1" LargeIncrement="10"
--- /dev/null
+<?xml version="1.0"?>
+<DockWindow Caption="Properties" Width="20%" Height="50%">
+
+</DockWindow>
+
+
<Label Style="TreeLabel" Text="{IsFoldable}"/>
</HorizontalStack>
</Border>
+ <!--<Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+ Foreground="Transparent"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Background="{./Background}" Spacing="1" Margin="1">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{HasChilds}"
+ SvgSub="{isExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <VerticalStack Fit="true" Margin="1" >
+ <Label Style="TreeLabel2" Text="{}" />
+ <Label Style="TreeLabel" Text="{./Caption}" Background="DarkGreen"/>
+ </VerticalStack>
+ <VerticalStack Fit="true" Margin="1">
+ <Label Style="TreeLabel2" Text="IsComplete"/>
+ <Label Style="TreeLabel" Text="{IsComplete}" />
+ </VerticalStack>
+ <VerticalStack Fit="true" Margin="1">
+ <Label Style="TreeLabel2" Text="Span" />
+ <Label Style="TreeLabel" Text="{Span}" />
+ </VerticalStack>
+ <VerticalStack Fit="true" Margin="1">
+ <Label Style="TreeLabel2" Text="Foldable" />
+ <Label Style="TreeLabel" Text="{IsFoldable}" />
+ </VerticalStack>
+ </HorizontalStack>
+ </Border>-->
<Container Name="Content" Visible="false"/>
</VerticalStack>
</Template>