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
BlockListItem(const char * label,uint32 blockIndex)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
UnicodeBlockView(const char * name)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
~UnicodeBlockView()358f400a12SAxel Dörfler UnicodeBlockView::~UnicodeBlockView()
368f400a12SAxel Dörfler {
378f400a12SAxel Dörfler }
388f400a12SAxel Dörfler
398f400a12SAxel Dörfler
408f400a12SAxel Dörfler void
SetFilter(const char * filter)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
478d3f6fceSDale Cieslak void
SetCharacterFont(const BFont & font)488d3f6fceSDale Cieslak UnicodeBlockView::SetCharacterFont(const BFont& font)
498d3f6fceSDale Cieslak {
508d3f6fceSDale Cieslak fCharacterFont = font;
518d3f6fceSDale Cieslak fUnicodeBlocks = fCharacterFont.Blocks();
528d3f6fceSDale Cieslak _UpdateBlocks();
538d3f6fceSDale Cieslak }
548d3f6fceSDale Cieslak
558f400a12SAxel Dörfler
568f400a12SAxel Dörfler void
ShowPrivateBlocks(bool show)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
ShowContainedBlocksOnly(bool show)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
IsShowingBlock(int32 blockIndex) const798f400a12SAxel 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*36087e77SMáximo Castañeda // The reason for two checks is BeOS compatibility.
88*36087e77SMáximo Castañeda // The first one checks for unicode blocks as defined by Be,
89*36087e77SMáximo Castañeda // but there are only 71 such blocks.
908d3f6fceSDale Cieslak // The rest of the blocks (denoted by kNoBlock) need to
918d3f6fceSDale Cieslak // be queried by searching for the start and end codepoints
928d3f6fceSDale Cieslak // via the IncludesBlock method.
938d3f6fceSDale Cieslak if (fShowContainedBlocksOnly) {
94*36087e77SMáximo Castañeda if (kUnicodeBlocks[blockIndex].block != kNoBlock)
95*36087e77SMáximo Castañeda return (fUnicodeBlocks & kUnicodeBlocks[blockIndex].block) != kNoBlock;
968d3f6fceSDale Cieslak
978d3f6fceSDale Cieslak if (!fCharacterFont.IncludesBlock(
988d3f6fceSDale Cieslak kUnicodeBlocks[blockIndex].start,
998d3f6fceSDale Cieslak kUnicodeBlocks[blockIndex].end))
1008d3f6fceSDale Cieslak return false;
1018d3f6fceSDale Cieslak }
1028d3f6fceSDale Cieslak
1038f400a12SAxel Dörfler return true;
1048f400a12SAxel Dörfler }
1058f400a12SAxel Dörfler
1068f400a12SAxel Dörfler
1078f400a12SAxel Dörfler void
_UpdateBlocks()1088f400a12SAxel Dörfler UnicodeBlockView::_UpdateBlocks()
1098f400a12SAxel Dörfler {
1108f400a12SAxel Dörfler MakeEmpty();
1118f400a12SAxel Dörfler
1128f400a12SAxel Dörfler for (int32 i = 0; i < fBlocks.CountItems(); i++) {
1138f400a12SAxel Dörfler if (fFilter.Length() != 0) {
1148f400a12SAxel Dörfler if (strcasestr(kUnicodeBlocks[i].name, fFilter.String()) == NULL)
1158f400a12SAxel Dörfler continue;
1168f400a12SAxel Dörfler }
1178f400a12SAxel Dörfler
1188f400a12SAxel Dörfler AddItem(fBlocks.ItemAt(i));
1198d3f6fceSDale Cieslak
1208d3f6fceSDale Cieslak fBlocks.ItemAt(i)->SetEnabled(IsShowingBlock(i));
1218f400a12SAxel Dörfler }
1228f400a12SAxel Dörfler }
1238f400a12SAxel Dörfler
1248f400a12SAxel Dörfler
1258f400a12SAxel Dörfler void
_CreateBlocks()1268f400a12SAxel Dörfler UnicodeBlockView::_CreateBlocks()
1278f400a12SAxel Dörfler {
1288f400a12SAxel Dörfler float minWidth = 0;
1298f400a12SAxel Dörfler for (uint32 i = 0; i < kNumUnicodeBlocks; i++) {
1308f400a12SAxel Dörfler BlockListItem* item = new BlockListItem(kUnicodeBlocks[i].name, i);
1318f400a12SAxel Dörfler fBlocks.AddItem(item);
1328f400a12SAxel Dörfler
1338f400a12SAxel Dörfler float width = StringWidth(item->Text());
1348f400a12SAxel Dörfler if (minWidth < width)
1358f400a12SAxel Dörfler minWidth = width;
1368f400a12SAxel Dörfler }
1378f400a12SAxel Dörfler
1388f400a12SAxel Dörfler SetExplicitMinSize(BSize(minWidth / 2, 32));
1398f400a12SAxel Dörfler SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET));
1408f400a12SAxel Dörfler
1418f400a12SAxel Dörfler _UpdateBlocks();
1428f400a12SAxel Dörfler }
1438f400a12SAxel Dörfler
14474d9b875Sdsizzle
14574d9b875Sdsizzle void
SelectBlockForCharacter(uint32 character)14674d9b875Sdsizzle UnicodeBlockView::SelectBlockForCharacter(uint32 character)
14774d9b875Sdsizzle {
14874d9b875Sdsizzle // find block containing the character
14919390213SDale Cieslak int32 blockNumber = BlockForCharacter(character);
15074d9b875Sdsizzle
15119390213SDale Cieslak if (blockNumber > 0) {
15219390213SDale Cieslak BlockListItem* block = fBlocks.ItemAt(blockNumber);
15374d9b875Sdsizzle
15419390213SDale Cieslak int32 blockIndex = IndexOf(block);
1550340e4b3Sdsizzle
15619390213SDale Cieslak if (blockIndex >= 0) {
15719390213SDale Cieslak Select(blockIndex);
15874d9b875Sdsizzle ScrollToSelection();
15974d9b875Sdsizzle }
16074d9b875Sdsizzle }
1610340e4b3Sdsizzle }
162