xref: /haiku/src/apps/charactermap/UnicodeBlockView.cpp (revision 8d3f6fce5732411d80949a27ae16aa5c4fb68a15)
18f400a12SAxel Dörfler /*
28f400a12SAxel Dörfler  * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
38f400a12SAxel Dörfler  * Distributed under the terms of the MIT License.
48f400a12SAxel Dörfler  */
58f400a12SAxel Dörfler 
68f400a12SAxel Dörfler 
78f400a12SAxel Dörfler #include "UnicodeBlockView.h"
88f400a12SAxel Dörfler 
98f400a12SAxel Dörfler #include <stdio.h>
108f400a12SAxel Dörfler #include <string.h>
118f400a12SAxel Dörfler 
128f400a12SAxel Dörfler #include "UnicodeBlocks.h"
138f400a12SAxel Dörfler 
148f400a12SAxel Dörfler 
158f400a12SAxel Dörfler BlockListItem::BlockListItem(const char* label, uint32 blockIndex)
168f400a12SAxel Dörfler 	: BStringItem(label),
178f400a12SAxel Dörfler 	fBlockIndex(blockIndex)
188f400a12SAxel Dörfler {
198f400a12SAxel Dörfler }
208f400a12SAxel Dörfler 
218f400a12SAxel Dörfler 
228f400a12SAxel Dörfler //	#pragma mark -
238f400a12SAxel Dörfler 
248f400a12SAxel Dörfler 
258f400a12SAxel Dörfler UnicodeBlockView::UnicodeBlockView(const char* name)
268f400a12SAxel Dörfler 	: BListView(name),
278f400a12SAxel Dörfler 	fBlocks(kNumUnicodeBlocks, true),
288f400a12SAxel Dörfler 	fShowPrivateBlocks(false),
298f400a12SAxel Dörfler 	fShowContainedBlocksOnly(false)
308f400a12SAxel Dörfler {
31ad491b43SAxel Dörfler 	_CreateBlocks();
328f400a12SAxel Dörfler }
338f400a12SAxel Dörfler 
348f400a12SAxel Dörfler 
358f400a12SAxel Dörfler UnicodeBlockView::~UnicodeBlockView()
368f400a12SAxel Dörfler {
378f400a12SAxel Dörfler }
388f400a12SAxel Dörfler 
398f400a12SAxel Dörfler 
408f400a12SAxel Dörfler void
418f400a12SAxel Dörfler UnicodeBlockView::SetFilter(const char* filter)
428f400a12SAxel Dörfler {
438f400a12SAxel Dörfler 	fFilter = filter;
448f400a12SAxel Dörfler 	_UpdateBlocks();
458f400a12SAxel Dörfler }
468f400a12SAxel Dörfler 
47*8d3f6fceSDale Cieslak void
48*8d3f6fceSDale Cieslak UnicodeBlockView::SetCharacterFont(const BFont& font)
49*8d3f6fceSDale Cieslak {
50*8d3f6fceSDale Cieslak 	fCharacterFont = font;
51*8d3f6fceSDale Cieslak 	fUnicodeBlocks = fCharacterFont.Blocks();
52*8d3f6fceSDale Cieslak 	_UpdateBlocks();
53*8d3f6fceSDale Cieslak }
54*8d3f6fceSDale Cieslak 
558f400a12SAxel Dörfler 
568f400a12SAxel Dörfler void
578f400a12SAxel Dörfler UnicodeBlockView::ShowPrivateBlocks(bool show)
588f400a12SAxel Dörfler {
598f400a12SAxel Dörfler 	if (fShowPrivateBlocks == show)
608f400a12SAxel Dörfler 		return;
618f400a12SAxel Dörfler 
628f400a12SAxel Dörfler 	fShowPrivateBlocks = show;
638f400a12SAxel Dörfler 	_UpdateBlocks();
648f400a12SAxel Dörfler }
658f400a12SAxel Dörfler 
668f400a12SAxel Dörfler 
678f400a12SAxel Dörfler void
688f400a12SAxel Dörfler UnicodeBlockView::ShowContainedBlocksOnly(bool show)
698f400a12SAxel Dörfler {
708f400a12SAxel Dörfler 	if (fShowContainedBlocksOnly == show)
718f400a12SAxel Dörfler 		return;
728f400a12SAxel Dörfler 
738f400a12SAxel Dörfler 	fShowContainedBlocksOnly = show;
748f400a12SAxel Dörfler 	_UpdateBlocks();
758f400a12SAxel Dörfler }
768f400a12SAxel Dörfler 
778f400a12SAxel Dörfler 
788f400a12SAxel Dörfler bool
798f400a12SAxel Dörfler UnicodeBlockView::IsShowingBlock(int32 blockIndex) const
808f400a12SAxel Dörfler {
818f400a12SAxel Dörfler 	if (blockIndex < 0 || blockIndex >= (int32)kNumUnicodeBlocks)
828f400a12SAxel Dörfler 		return false;
838f400a12SAxel Dörfler 
848f400a12SAxel Dörfler 	if (!fShowPrivateBlocks && kUnicodeBlocks[blockIndex].private_block)
858f400a12SAxel Dörfler 		return false;
868f400a12SAxel Dörfler 
87*8d3f6fceSDale Cieslak 	// the reason for two checks is BeOS compatibility.
88*8d3f6fceSDale Cieslak 	// The Includes method checks for unicode blocks as
89*8d3f6fceSDale Cieslak 	// defined by Be, but there are only 71 such blocks.
90*8d3f6fceSDale Cieslak 	// The rest of the blocks (denoted by kNoBlock) need to
91*8d3f6fceSDale Cieslak 	// be queried by searching for the start and end codepoints
92*8d3f6fceSDale Cieslak 	// via the IncludesBlock method.
93*8d3f6fceSDale Cieslak 	if (fShowContainedBlocksOnly) {
94*8d3f6fceSDale Cieslak 		if (kUnicodeBlocks[blockIndex].block != kNoBlock
95*8d3f6fceSDale Cieslak 			&& !fUnicodeBlocks.Includes(
96*8d3f6fceSDale Cieslak 				kUnicodeBlocks[blockIndex].block))
97*8d3f6fceSDale Cieslak 			return false;
98*8d3f6fceSDale Cieslak 
99*8d3f6fceSDale Cieslak 		if (!fCharacterFont.IncludesBlock(
100*8d3f6fceSDale Cieslak 				kUnicodeBlocks[blockIndex].start,
101*8d3f6fceSDale Cieslak 				kUnicodeBlocks[blockIndex].end))
102*8d3f6fceSDale Cieslak 			return false;
103*8d3f6fceSDale Cieslak 	}
104*8d3f6fceSDale Cieslak 
1058f400a12SAxel Dörfler 	return true;
1068f400a12SAxel Dörfler }
1078f400a12SAxel Dörfler 
1088f400a12SAxel Dörfler 
1098f400a12SAxel Dörfler void
1108f400a12SAxel Dörfler UnicodeBlockView::_UpdateBlocks()
1118f400a12SAxel Dörfler {
1128f400a12SAxel Dörfler 	MakeEmpty();
1138f400a12SAxel Dörfler 
1148f400a12SAxel Dörfler 	for (int32 i = 0; i < fBlocks.CountItems(); i++) {
1158f400a12SAxel Dörfler 		if (fFilter.Length() != 0) {
1168f400a12SAxel Dörfler 			if (strcasestr(kUnicodeBlocks[i].name, fFilter.String()) == NULL)
1178f400a12SAxel Dörfler 				continue;
1188f400a12SAxel Dörfler 		}
1198f400a12SAxel Dörfler 
1208f400a12SAxel Dörfler 		AddItem(fBlocks.ItemAt(i));
121*8d3f6fceSDale Cieslak 
122*8d3f6fceSDale Cieslak 		fBlocks.ItemAt(i)->SetEnabled(IsShowingBlock(i));
1238f400a12SAxel Dörfler 	}
1248f400a12SAxel Dörfler }
1258f400a12SAxel Dörfler 
1268f400a12SAxel Dörfler 
1278f400a12SAxel Dörfler void
1288f400a12SAxel Dörfler UnicodeBlockView::_CreateBlocks()
1298f400a12SAxel Dörfler {
1308f400a12SAxel Dörfler 	float minWidth = 0;
1318f400a12SAxel Dörfler 	for (uint32 i = 0; i < kNumUnicodeBlocks; i++) {
1328f400a12SAxel Dörfler 		BlockListItem* item = new BlockListItem(kUnicodeBlocks[i].name, i);
1338f400a12SAxel Dörfler 		fBlocks.AddItem(item);
1348f400a12SAxel Dörfler 
1358f400a12SAxel Dörfler 		float width = StringWidth(item->Text());
1368f400a12SAxel Dörfler 		if (minWidth < width)
1378f400a12SAxel Dörfler 			minWidth = width;
1388f400a12SAxel Dörfler 	}
1398f400a12SAxel Dörfler 
1408f400a12SAxel Dörfler 	SetExplicitMinSize(BSize(minWidth / 2, 32));
1418f400a12SAxel Dörfler 	SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET));
1428f400a12SAxel Dörfler 
1438f400a12SAxel Dörfler 	_UpdateBlocks();
1448f400a12SAxel Dörfler }
1458f400a12SAxel Dörfler 
14674d9b875Sdsizzle 
14774d9b875Sdsizzle void
14874d9b875Sdsizzle UnicodeBlockView::SelectBlockForCharacter(uint32 character)
14974d9b875Sdsizzle {
15074d9b875Sdsizzle 	// find block containing the character
15119390213SDale Cieslak 	int32 blockNumber = BlockForCharacter(character);
15274d9b875Sdsizzle 
15319390213SDale Cieslak 	if (blockNumber > 0) {
15419390213SDale Cieslak 		BlockListItem* block = fBlocks.ItemAt(blockNumber);
15574d9b875Sdsizzle 
15619390213SDale Cieslak 		int32 blockIndex = IndexOf(block);
1570340e4b3Sdsizzle 
15819390213SDale Cieslak 		if (blockIndex >= 0) {
15919390213SDale Cieslak 			Select(blockIndex);
16074d9b875Sdsizzle 			ScrollToSelection();
16174d9b875Sdsizzle 		}
16274d9b875Sdsizzle 	}
1630340e4b3Sdsizzle }
164