5.5.8.2. Добавление значков из других библиотек шрифтов
Для более тонкой настройки расширенной темы можно создать значки, встроенные в шрифты, либо использовать готовые внешние библиотеки значков.
-
Создайте в модуле web класс
enum
, реализующий интерфейсcom.vaadin.server.FontIcon
, в который поместите новые значки:import com.vaadin.server.FontIcon; import com.vaadin.server.GenericFontIcon; public enum IcoMoon implements FontIcon { HEADPHONES(0XE900), SPINNER(0XE905); public static final String FONT_FAMILY = "IcoMoon"; private int codepoint; IcoMoon(int codepoint) { this.codepoint = codepoint; } @Override public String getFontFamily() { return FONT_FAMILY; } @Override public int getCodepoint() { return codepoint; } @Override public String getHtml() { return GenericFontIcon.getHtml(FONT_FAMILY, codepoint); } @Override public String getMIMEType() { throw new UnsupportedOperationException(FontIcon.class.getSimpleName() + " should not be used where a MIME type is needed."); } public static IcoMoon fromCodepoint(final int codepoint) { for (IcoMoon f : values()) { if (f.getCodepoint() == codepoint) { return f; } } throw new IllegalArgumentException("Codepoint " + codepoint + " not found in IcoMoon"); } }
-
Добавьте новые стили и файлы шрифта в расширение темы. Рекомендуется создать отдельную папку
fonts
в главном каталоге расширения темы, например,modules/web/themes/halo/com.company.demo/fonts
. Поместите в неё стили и файлы шрифтов в своих собственных подпапках, например,fonts/icomoon
.Файлы шрифта включают в себя набор следующих расширений:
-
.eot
, -
.svg
, -
.ttf
, -
.woff
.Использованный в этом примере набор шрифтов
icomoon
из открытой библиотеки представлен в виде 4 файлов:icomoon.eot
,icomoon.svg
,icomoon.ttf
,icomoon.woff
, которые используются совместно.
-
-
Создайте файл стилей, в который включите
@font-face
и CSS класс со стилем для значка. Ниже представлен пример файлаicomoon.scss
, где имя классаIcoMoon
соответствует значению, возвращаемому методомFontIcon#getFontFamily
:@mixin icomoon-style { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomoon' !important; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @font-face { font-family: 'icomoon'; src:url('icomoon.eot?hwgbks'); src:url('icomoon.eot?hwgbks#iefix') format('embedded-opentype'), url('icomoon.ttf?hwgbks') format('truetype'), url('icomoon.woff?hwgbks') format('woff'), url('icomoon.svg?hwgbks#icomoon') format('svg'); font-weight: normal; font-style: normal; } .IcoMoon { @include icomoon-style; }
-
Подключите файл стилей шрифта в
halo-ext.scss
или другой файл расширения данной темы:@import "fonts/icomoon/icomoon";
-
Затем создайте новый набор значков, то есть enum, реализующий интерфейс
Icons.Icon
:import com.haulmont.cuba.gui.icons.Icons; public enum IcoMoonIcon implements Icons.Icon { HEADPHONES("ico-moon:HEADPHONES"), SPINNER("ico-moon:SPINNER"); protected String source; IcoMoonIcon(String source) { this.source = source; } @Override public String source() { return source; } }
-
Создайте новый
IconProvider
.Для работы с наборами значков в платформе есть механизм, основанный на использовании
IconProvider
иIconResolver
.IconProvider
- это интерфейс-маркер, доступный только в веб-модуле, который предоставляет доступ к ресурсу (com.vaadin.server.Resource
) по переданному пути.Бин
IconResolver
проходится по всем бинам, реализующимIconProvider
, в поисках того, кто может предоставить ресурс к данному значку.На самом деле, в платформе есть два интерфейса
IconResolver
и их реализации для модулей desktop и web. Оба они являются бинами-фасадами, которые принимают путь к значку и возвращают ресурс для своего модуля:-
com.vaadin.server.Resource
для модуля web, -
javax.swing.Icon
для модуля desktop.
Чтобы использовать этот механизм, необходимо создать собственную реализацию
IconProvider
, например, так:import com.haulmont.cuba.web.gui.icons.IconProvider; import com.vaadin.server.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Order(10) @Component public class IcoMoonIconProvider implements IconProvider { private final Logger log = LoggerFactory.getLogger(IcoMoonIconProvider.class); @Override public Resource getIconResource(String iconPath) { Resource resource = null; iconPath = iconPath.split(":")[1]; try { resource = ((Resource) IcoMoon.class .getDeclaredField(iconPath) .get(null)); } catch (IllegalAccessException | NoSuchFieldException e) { log.warn("There is no icon with name {} in the FontAwesome icon set", iconPath); } return resource; } @Override public boolean canProvide(String iconPath) { return iconPath.startsWith("ico-moon:"); } }
Здесь мы явно назначаем порядок для этого бина аннотацией
@Order
. -
-
Далее нужно зарегистрировать набор значков в файле свойств приложения:
cuba.iconsConfig = +com.company.demo.gui.icons.IcoMoonIcon
Теперь вы можете использовать значки по прямой ссылке на класс и элемент enum
в XML-дескрипторе экрана:
<button caption="Headphones" icon="ico-moon:HEADPHONES"/>
или в контроллере Java:
spinnerBtn.setIconFromSet("ico-moon:SPINNER");
В результате, новые значки добавились к кнопкам:
- Переопределение значков с помощью наборов
-
Механизм наборов значков позволяет переопределять некоторые значки из других наборов. Для этого необходимо создать и зарегистрировать новый набор значков (enumeration) с теми же именами значков (options), но с другими путями (
source
). В примере ниже создан новый наборMyIcon
, в котором переопределены стандартные значки из набораCubaIcon
.-
Стандартный набор:
public enum CubaIcon implements Icons.Icon { OK("font-icon:CHECK"), CANCEL("font-icon:BAN"), ... }
-
Новый набор:
public enum MyIcon implements Icons.Icon { OK("icons/my-custom-ok.png"), ... }
-
Регистрация нового набора в
web-app.properties
:cuba.iconsConfig = +com.company.demo.gui.icons.MyIcon
Теперь вместо стандартного значка OK будет использовано новое изображение:
Icons icons = AppBeans.get(Icons.NAME); button.setIcon(icons.getIcon(CubaIcon.OK))
При необходимости игнорировать переопределение и использовать стандартные значки, просто используйте путь к значку вместо имени элемента перечисления:
<button caption="Created" icon="icons/create.png"/>
или
button.setIcon(CubaIcon.CREATE_ACTION.source());
-