All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mini2Dx.ui.style.UiTheme Maven / Gradle / Ivy

There is a newer version: 2.0.0-alpha.32
Show newest version
/*******************************************************************************
 * Copyright 2019 See AUTHORS file
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.mini2Dx.ui.style;

import org.mini2Dx.core.Mdx;
import org.mini2Dx.core.assets.AssetDescriptor;
import org.mini2Dx.core.assets.AssetManager;
import org.mini2Dx.core.exception.MdxException;
import org.mini2Dx.core.files.FileHandleResolver;
import org.mini2Dx.core.graphics.TextureAtlas;
import org.mini2Dx.core.serialization.annotation.Field;
import org.mini2Dx.gdx.utils.Array;
import org.mini2Dx.gdx.utils.ObjectMap;
import org.mini2Dx.ui.UiContainer;
import org.mini2Dx.ui.element.*;
import org.mini2Dx.ui.layout.ScreenSize;
import org.mini2Dx.ui.style.ruleset.*;

/**
 * Represents a user interface theme applied to a {@link UiContainer}
 */
public class UiTheme {
	private static final String LOGGING_TAG = UiTheme.class.getSimpleName();
	
	public static final String DEFAULT_THEME_FILENAME = "default-mdx-theme.json";
	public static final String DEFAULT_THEME_ATLAS = "default-mdx-theme.atlas";
	public static final String DEFAULT_STYLE_ID = "default";

	@Field
	private String id;
	@Field
	private String atlas;
	@Field
	private ObjectMap buttons;
	@Field
	private ObjectMap checkboxes;
	@Field
	private ObjectMap columns;
	@Field
	private ObjectMap containers;
	@Field
	private ObjectMap fonts;
	@Field
	private ObjectMap images;
	@Field
	private ObjectMap labels;
	@Field
	private ObjectMap progressBars;
	@Field
	private ObjectMap radioButtons;
	@Field
	private ObjectMap selects;
	@Field
	private ObjectMap scrollBoxes;
	@Field
	private ObjectMap sliders;
	@Field
	private ObjectMap tabs;
	@Field
	private ObjectMap textboxes;
	
	private TextureAtlas textureAtlas;
	private boolean headless;

	public void validate() {
		if (!buttons.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for buttons");
		}
		if (!checkboxes.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for checkboxes");
		}
		if (!columns.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for columns");
		}
		if (!containers.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for containers");
		}
		if (!images.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for images");
		}
		if (!labels.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for labels");
		}
		if (!progressBars.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for progressBars");
		}
		if (!selects.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for selects");
		}
		if (!scrollBoxes.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for scrollBoxes");
		}
		if (!sliders.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for sliders");
		}
		if (!tabs.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for tabs");
		}
		if (!textboxes.containsKey(DEFAULT_STYLE_ID)) {
			throw new MdxException("No style with id 'default' for textboxes");
		}

		for (StyleRuleset buttonRuleset : buttons.values()) {
			buttonRuleset.validate(this);
		}
		for (StyleRuleset checkboxRuleset : checkboxes.values()) {
			checkboxRuleset.validate(this);
		}
		for (StyleRuleset columnRuleset : columns.values()) {
			columnRuleset.validate(this);
		}
		for (StyleRuleset containerRuleset : containers.values()) {
			containerRuleset.validate(this);
		}
		for (StyleRuleset imageRuleset : images.values()) {
			imageRuleset.validate(this);
		}
		for (StyleRuleset labelRuleset : labels.values()) {
			labelRuleset.validate(this);
		}
		for (StyleRuleset progressBarRuleset : progressBars.values()) {
			progressBarRuleset.validate(this);
		}
		for (StyleRuleset radioButtonRuleset : radioButtons.values()) {
			radioButtonRuleset.validate(this);
		}
		for (StyleRuleset scrollBoxRuleset : scrollBoxes.values()) {
			scrollBoxRuleset.validate(this);
		}
		for (StyleRuleset selectRuleset : selects.values()) {
			selectRuleset.validate(this);
		}
		for (StyleRuleset sliderRuleset : sliders.values()) {
			sliderRuleset.validate(this);
		}
		for (StyleRuleset tabRuleset : tabs.values()) {
			tabRuleset.validate(this);
		}
		for (StyleRuleset textboxRuleset : textboxes.values()) {
			textboxRuleset.validate(this);
		}
	}

	public void loadDependencies(Array dependencies, FileHandleResolver resolver, boolean headless) {
		this.headless = headless;
		if(!headless) {
			dependencies.add(new AssetDescriptor(atlas, TextureAtlas.class));
		}
		
		Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Atlas: " + atlas + "]");
		for (UiFont font : fonts.values()) {
			font.loadDependencies(this, resolver, dependencies);
		}
		for (String id : buttons.keys()) {
			StyleRuleset buttonRuleset = buttons.get(id);
			buttonRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Button Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : checkboxes.keys()) {
			StyleRuleset columnRuleset = checkboxes.get(id);
			columnRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Checkbox Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : columns.keys()) {
			StyleRuleset columnRuleset = columns.get(id);
			columnRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Div Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : containers.keys()) {
			StyleRuleset containerRuleset = containers.get(id);
			containerRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Container Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : images.keys()) {
			StyleRuleset imageRuleset = images.get(id);
			imageRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Image Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : labels.keys()) {
			StyleRuleset labelRuleset = labels.get(id);
			labelRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Label Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : progressBars.keys()) {
			StyleRuleset progressBarRuleset = progressBars.get(id);
			progressBarRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Progress Bar Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : radioButtons.keys()) {
			StyleRuleset scrollBoxRuleset = radioButtons.get(id);
			scrollBoxRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", RadioButton Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : scrollBoxes.keys()) {
			StyleRuleset scrollBoxRuleset = scrollBoxes.get(id);
			scrollBoxRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", ScrollBox Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : selects.keys()) {
			StyleRuleset selectRuleset = selects.get(id);
			selectRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Select Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : sliders.keys()) {
			StyleRuleset sliderRuleset = sliders.get(id);
			sliderRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Slider Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : tabs.keys()) {
			StyleRuleset tabRuleset = tabs.get(id);
			tabRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", Tab Ruleset: " + id + "] Dependencies loaded");
		}
		for (String id : textboxes.keys()) {
			StyleRuleset textboxRuleset = textboxes.get(id);
			textboxRuleset.loadDependencies(this, dependencies);
			Mdx.log.info(LOGGING_TAG, "[Theme: " + this.id + ", TextBox Ruleset: " + id + "] Dependencies loaded");
		}
	}

	public void prepareAssets(FileHandleResolver fileHandleResolver, AssetManager assetManager) {
		if(!headless) {
			textureAtlas = assetManager.get(atlas, TextureAtlas.class);
		}
		
		for (UiFont font : fonts.values()) {
			font.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset buttonRuleset : buttons.values()) {
			buttonRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset checkboxRuleset : checkboxes.values()) {
			checkboxRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset columnRuleset : columns.values()) {
			columnRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset containerRuleset : containers.values()) {
			containerRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset imageRuleset : images.values()) {
			imageRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset labelRuleset : labels.values()) {
			labelRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset progressBarRuleset : progressBars.values()) {
			progressBarRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset radioButtonRuleset : radioButtons.values()) {
			radioButtonRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset scrollBoxRuleset : scrollBoxes.values()) {
			scrollBoxRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset selectRuleset : selects.values()) {
			selectRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset sliderRuleset : sliders.values()) {
			sliderRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset tabRuleset : tabs.values()) {
			tabRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
		for (StyleRuleset textboxRuleset : textboxes.values()) {
			textboxRuleset.prepareAssets(this, fileHandleResolver, assetManager);
		}
	}
	
	public boolean containsButtonStyleRuleset(String id) {
		return buttons.containsKey(id);
	}
	
	public boolean containsCheckboxStyleRuleset(String id) {
		return checkboxes.containsKey(id);
	}
	
	public boolean containsColumnStyleRuleset(String id) {
		return columns.containsKey(id);
	}
	
	public boolean containsImageStyleRuleset(String id) {
		return images.containsKey(id);
	}
	
	public boolean containsLabelStyleRuleset(String id) {
		return labels.containsKey(id);
	}
	
	public StyleRule getStyleRule(AnimatedImage image, ScreenSize screenSize) {
		return getStyleRule(image, screenSize, images);
	}

	public ButtonStyleRule getStyleRule(Button button, ScreenSize screenSize) {
		return getButtonStyleRule(button.getStyleId(), screenSize);
	}
	
	public CheckboxStyleRule getStyleRule(Checkbox checkbox, ScreenSize screenSize) {
		return getCheckboxStyleRule(checkbox.getStyleId(), screenSize);
	}

	public ParentStyleRule getStyleRule(Div div, ScreenSize screenSize) {
		return getColumnStyleRule(div.getStyleId(), screenSize);
	}

	public ContainerStyleRule getStyleRule(Container container, ScreenSize screenSize) {
		return getContainerStyleRule(container.getStyleId(), screenSize);
	}

	public LabelStyleRule getStyleRule(Label label, ScreenSize screenSize) {
		return getLabelStyleRule(label.getStyleId(), screenSize);
	}

	public StyleRule getStyleRule(Image image, ScreenSize screenSize) {
		return getStyleRule(image, screenSize, images);
	}
	
	public ProgressBarStyleRule getStyleRule(ProgressBar progressBar, ScreenSize screenSize) {
		return getProgressBarStyleRule(progressBar.getStyleId(), screenSize);
	}
	
	public RadioButtonStyleRule getStyleRule(RadioButton radioButton, ScreenSize screenSize) {
		return getRadioButtonStyleRule(radioButton.getStyleId(), screenSize);
	}
	
	public ScrollBoxStyleRule getStyleRule(ScrollBox scrollBox, ScreenSize screenSize) {
		return getScrollBoxStyleRule(scrollBox.getStyleId(), screenSize);
	}

	public SelectStyleRule getStyleRule(Select select, ScreenSize screenSize) {
		return getSelectStyleRule(select.getStyleId(), screenSize);
	}
	
	public SliderStyleRule getStyleRule(Slider slider, ScreenSize screenSize) {
		return getSliderStyleRule(slider.getStyleId(), screenSize);
	}
	
	public TabStyleRule getStyleRule(TabView tabView, ScreenSize screenSize) {
		return getTabStyleRule(tabView.getStyleId(), screenSize);
	}

	public TextBoxStyleRule getStyleRule(TextBox textbox, ScreenSize screenSize) {
		return getTextBoxStyleRule(textbox.getStyleId(), screenSize);
	}

	private StyleRule getStyleRule(UiElement element, ScreenSize screenSize,
			ObjectMap rules) {
		StyleRuleset ruleset = rules.get(element.getStyleId());
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + element.getStyleId());
			ruleset = rules.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public UiFont getFont(String id) {
		return fonts.get(id);
	}
	
	public ButtonStyleRule getButtonStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = buttons.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = buttons.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public CheckboxStyleRule getCheckboxStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = checkboxes.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = checkboxes.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public ParentStyleRule getColumnStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = columns.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = columns.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public ContainerStyleRule getContainerStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = containers.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = containers.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}

	public StyleRule getImageStyleRule(String styleId, ScreenSize screenSize) {
		DefaultStyleRuleset ruleset = images.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = images.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}

	public LabelStyleRule getLabelStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = labels.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = labels.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public ProgressBarStyleRule getProgressBarStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = progressBars.get(styleId);
		if(ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = progressBars.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public RadioButtonStyleRule getRadioButtonStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = radioButtons.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = radioButtons.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public ScrollBoxStyleRule getScrollBoxStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = scrollBoxes.get(styleId);
		if(ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = scrollBoxes.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public SelectStyleRule getSelectStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = selects.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = selects.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public SliderStyleRule getSliderStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = sliders.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = sliders.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public TabStyleRule getTabStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = tabs.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = tabs.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public TextBoxStyleRule getTextBoxStyleRule(String styleId, ScreenSize screenSize) {
		StyleRuleset ruleset = textboxes.get(styleId);
		if (ruleset == null) {
			Mdx.log.error(LOGGING_TAG, "No style found with ID " + styleId);
			ruleset = textboxes.get(DEFAULT_STYLE_ID);
		}
		return ruleset.getStyleRule(screenSize);
	}
	
	public void putButtonStyleRuleset(String rulesetId, ButtonStyleRuleset ruleset) {
		if(buttons == null) {
			buttons = new ObjectMap();
		}
		buttons.put(rulesetId, ruleset);
	}
	
	public void putColumnStyleRuleset(String rulesetId, ColumnStyleRuleset ruleset) {
		if(columns == null) {
			columns = new ObjectMap();
		}
		columns.put(rulesetId, ruleset);
	}
	
	public void putContainerStyleRuleset(String rulesetId, ContainerStyleRuleset ruleset) {
		if(containers == null) {
			containers = new ObjectMap();
		}
		containers.put(rulesetId, ruleset);
	}
	
	public void putImageStyleRuleset(String rulesetId,DefaultStyleRuleset ruleset) {
		if(images == null) {
			images = new ObjectMap();
		}
		images.put(rulesetId, ruleset);
	}
	
	public void putLabelStyleRuleset(String rulesetId, LabelStyleRuleset ruleset) {
		if(labels == null) {
			labels = new ObjectMap();
		}
		labels.put(rulesetId, ruleset);
	}
	
	public void putProgressBarStyleRuleset(String rulesetId, ProgressBarStyleRuleset ruleset) {
		if(progressBars == null) {
			progressBars = new ObjectMap();
		}
		progressBars.put(rulesetId, ruleset);
	}
	
	public void putScrollBoxStyleRuleset(String rulesetId, ScrollBoxStyleRuleset ruleset) {
		if(scrollBoxes == null) {
			scrollBoxes = new ObjectMap();
		}
		scrollBoxes.put(rulesetId, ruleset);
	}
	
	public void putSelectStyleRuleset(String rulesetId, SelectStyleRuleset ruleset) {
		if(selects == null) {
			selects = new ObjectMap();
		}
		selects.put(rulesetId, ruleset);
	}
	
	public void putTabStyleRuleset(String rulesetId, TabStyleRuleset ruleset) {
		if(tabs == null) {
			tabs = new ObjectMap();
		}
		tabs.put(rulesetId, ruleset);
	}
	
	public void putTextBoxStyleRuleset(String rulesetId, TextBoxStyleRuleset ruleset) {
		if(textboxes == null) {
			textboxes = new ObjectMap();
		}
		textboxes.put(rulesetId, ruleset);
	}
	
	public void putFont(String id, String path) {
		if(fonts == null) {
			fonts = new ObjectMap();
		}
		UiFont font = new UiFont();
		font.setPath(path);
		fonts.put(id, font);
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public TextureAtlas getTextureAtlas() {
		return textureAtlas;
	}

	public boolean isHeadless() {
		return headless;
	}

	public ObjectMap getButtonRulesets() {
		return buttons;
	}

	public ObjectMap getCheckboxRulesets() {
		return checkboxes;
	}

	public ObjectMap getColumnRulesets() {
		return columns;
	}

	public ObjectMap getContainerRulesets() {
		return containers;
	}

	public ObjectMap getFonts() {
		return fonts;
	}

	public ObjectMap getImageRulesets() {
		return images;
	}

	public ObjectMap getLabelRulesets() {
		return labels;
	}

	public ObjectMap getProgressBarRulesets() {
		return progressBars;
	}

	public ObjectMap getRadioButtonRulesets() {
		return radioButtons;
	}

	public ObjectMap getSelectRulesets() {
		return selects;
	}

	public ObjectMap getScrollBoxRulesets() {
		return scrollBoxes;
	}

	public ObjectMap getSliderRulesets() {
		return sliders;
	}

	public ObjectMap getTabRulesets() {
		return tabs;
	}

	public ObjectMap getTextBoxRulesets() {
		return textboxes;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy