void TreeItem::draw(ExpandTree* tree, AlloyContext* context,
		const pixel2& offset) {
		box2px bounds = getBounds();
		NVGcontext* nvg = context->nvgContext;
		nvgFontFaceId(nvg, context->getFontHandle(FontType::Icon));
		float spaceWidth = fontSize + PADDING * 2;
		float iconWidth = 0;
		static const std::string rightArrow = CodePointToUTF8(0xf0da);
		static const std::string downArrow = CodePointToUTF8(0xf0d7);
		pixel2 pt = bounds.position + offset;
		bool selected = (tree->getSelectedItem() == this)&&!tree->isOverArrow();
		nvgFontSize(nvg, fontSize);

		if (iconCodeString.length() > 0) {
			iconWidth = nvgTextBounds(nvg, 0, 0, iconCodeString.c_str(), nullptr,
				nullptr) + PADDING * 2;

			if (children.size() > 0 || onExpand) {
				nvgTextAlign(nvg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
				if (tree->isOverArrow()) {
					nvgFillColor(nvg, context->theme.LIGHTEST);
				}
				else {
					nvgFillColor(nvg, context->theme.LIGHTER);
				}
				nvgText(nvg, pt.x + spaceWidth * 0.5f, pt.y + PADDING,
					(expanded) ? downArrow.c_str() : rightArrow.c_str(),
					nullptr);
			}
			if (selected) {
				nvgFillColor(nvg, context->theme.LIGHTEST);
			}
			else {
				nvgFillColor(nvg, context->theme.LIGHTER);
			}
			nvgTextAlign(nvg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
			nvgText(nvg, pt.x + spaceWidth, pt.y + PADDING, iconCodeString.c_str(),
				nullptr);
		}
		if (name.length() > 0) {
			if (selected) {
				nvgFillColor(nvg, context->theme.LIGHTEST);
			}
			else {
				nvgFillColor(nvg, context->theme.LIGHTER);
			}
			nvgTextAlign(nvg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
			nvgFontFaceId(nvg, context->getFontHandle(FontType::Bold));
			nvgText(nvg, pt.x + iconWidth + spaceWidth, pt.y + PADDING,
				name.c_str(), nullptr);
		}
		if (expanded) {
			for (TreeItemPtr& item : children) {
				item->draw(tree, context, offset);
			}
		}
	}
AwesomeGlyph::AwesomeGlyph(int codePoint, AlloyContext* context,
		const FontStyle& style, pixel height) :
		Glyph(CodePointToUTF8(codePoint), GlyphType::Awesome, 0, height), codePoint(
				codePoint), style(style) {
	NVGcontext* nvg = context->nvgContext;
	nvgFontSize(nvg, height);
	nvgFontFaceId(nvg, context->getFontHandle(FontType::Icon));
	width = nvgTextBounds(nvg, 0, 0, name.c_str(), nullptr, nullptr);

}
Esempio n. 3
0
static void
ApplyQuotes ( XMP_VarString * item, UniCodePoint openQuote, UniCodePoint closeQuote, bool allowCommas )
{
	bool	prevSpace	= false;
	size_t	charOffset, charLen;
	UniCharKind		charKind;
	UniCodePoint	uniChar;
	
	// -----------------------------------------------------------------------------------------
	// See if there are any separators in the value. Stop at the first occurrance. This is a bit
	// tricky in order to make typical typing work conveniently. The purpose of applying quotes
	// is to preserve the values when splitting them back apart. That is CatenateContainerItems
	// and SeparateContainerItems must round trip properly. For the most part we only look for
	// separators here. Internal quotes, as in -- Irving "Bud" Jones -- won't cause problems in
	// the separation. An initial quote will though, it will make the value look quoted.

	charOffset = 0;
	ClassifyCharacter ( item->c_str(), charOffset, &charKind, &charLen, &uniChar );
	
	if ( charKind != UCK_quote ) {
	
	for ( charOffset = 0; size_t(charOffset) < item->size(); charOffset += charLen ) {

			ClassifyCharacter ( item->c_str(), charOffset, &charKind, &charLen, &uniChar );

			if ( charKind == UCK_space ) {
				if ( prevSpace ) break; // Multiple spaces are a separator.
				prevSpace = true;
			} else {
				prevSpace = false;
				if ( (charKind == UCK_semicolon) || (charKind == UCK_control) ) break;
				if ( (charKind == UCK_comma) && (! allowCommas) ) break;
			}

		}
	
	}
	
	if ( size_t(charOffset) < item->size() ) {
	
		// --------------------------------------------------------------------------------------
		// Create a quoted copy, doubling any internal quotes that match the outer ones. Internal
		// quotes did not stop the "needs quoting" search, but they do need doubling. So we have
		// to rescan the front of the string for quotes. Handle the special case of U+301D being
		// closed by either U+301E or U+301F.
		
		XMP_VarString	newItem;
		size_t			splitPoint;
		
		for ( splitPoint = 0; splitPoint <= charOffset; ++splitPoint ) {
			ClassifyCharacter ( item->c_str(), splitPoint, &charKind, &charLen, &uniChar );
			if ( charKind == UCK_quote ) break;
		}
		
		CodePointToUTF8 ( openQuote, newItem );
		newItem.append ( *item, 0, splitPoint );	// Copy the leading "normal" portion.

		for ( charOffset = splitPoint; size_t(charOffset) < item->size(); charOffset += charLen ) {
			ClassifyCharacter ( item->c_str(), charOffset, &charKind, &charLen, &uniChar );
			newItem.append ( *item, charOffset, charLen );
			if ( (charKind == UCK_quote) && IsSurroundingQuote ( uniChar, openQuote, closeQuote ) ) {
				newItem.append ( *item, charOffset, charLen );
			}
		}
		
		XMP_VarString closeStr;
		CodePointToUTF8 ( closeQuote, closeStr );
		newItem.append ( closeStr );
		
		*item = newItem;
	
	}
	
}	// ApplyQuotes
	TreeItem::TreeItem(const std::string& name, int iconCode, float fontSize) :
		name(name), fontSize(fontSize),spaceWidth(0.0f), expanded(name.length() == 0) {
		if (iconCode != 0) {
			iconCodeString = CodePointToUTF8(iconCode);
		}
	}