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