/* * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #include "UnicodeBlockView.h" #include #include #include "UnicodeBlocks.h" BlockListItem::BlockListItem(const char* label, uint32 blockIndex) : BStringItem(label), fBlockIndex(blockIndex) { } // #pragma mark - UnicodeBlockView::UnicodeBlockView(const char* name) : BListView(name), fBlocks(kNumUnicodeBlocks, true), fShowPrivateBlocks(false), fShowContainedBlocksOnly(false) { _CreateBlocks(); } UnicodeBlockView::~UnicodeBlockView() { } void UnicodeBlockView::SetFilter(const char* filter) { fFilter = filter; _UpdateBlocks(); } void UnicodeBlockView::SetCharacterFont(const BFont& font) { fCharacterFont = font; fUnicodeBlocks = fCharacterFont.Blocks(); _UpdateBlocks(); } void UnicodeBlockView::ShowPrivateBlocks(bool show) { if (fShowPrivateBlocks == show) return; fShowPrivateBlocks = show; _UpdateBlocks(); } void UnicodeBlockView::ShowContainedBlocksOnly(bool show) { if (fShowContainedBlocksOnly == show) return; fShowContainedBlocksOnly = show; _UpdateBlocks(); } bool UnicodeBlockView::IsShowingBlock(int32 blockIndex) const { if (blockIndex < 0 || blockIndex >= (int32)kNumUnicodeBlocks) return false; if (!fShowPrivateBlocks && kUnicodeBlocks[blockIndex].private_block) return false; // The reason for two checks is BeOS compatibility. // The first one checks for unicode blocks as defined by Be, // but there are only 71 such blocks. // The rest of the blocks (denoted by kNoBlock) need to // be queried by searching for the start and end codepoints // via the IncludesBlock method. if (fShowContainedBlocksOnly) { if (kUnicodeBlocks[blockIndex].block != kNoBlock) return (fUnicodeBlocks & kUnicodeBlocks[blockIndex].block) != kNoBlock; if (!fCharacterFont.IncludesBlock( kUnicodeBlocks[blockIndex].start, kUnicodeBlocks[blockIndex].end)) return false; } return true; } void UnicodeBlockView::_UpdateBlocks() { MakeEmpty(); for (int32 i = 0; i < fBlocks.CountItems(); i++) { if (fFilter.Length() != 0) { if (strcasestr(kUnicodeBlocks[i].name, fFilter.String()) == NULL) continue; } AddItem(fBlocks.ItemAt(i)); fBlocks.ItemAt(i)->SetEnabled(IsShowingBlock(i)); } } void UnicodeBlockView::_CreateBlocks() { float minWidth = 0; for (uint32 i = 0; i < kNumUnicodeBlocks; i++) { BlockListItem* item = new BlockListItem(kUnicodeBlocks[i].name, i); fBlocks.AddItem(item); float width = StringWidth(item->Text()); if (minWidth < width) minWidth = width; } SetExplicitMinSize(BSize(minWidth / 2, 32)); SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET)); _UpdateBlocks(); } void UnicodeBlockView::SelectBlockForCharacter(uint32 character) { // find block containing the character int32 blockNumber = BlockForCharacter(character); if (blockNumber > 0) { BlockListItem* block = fBlocks.ItemAt(blockNumber); int32 blockIndex = IndexOf(block); if (blockIndex >= 0) { Select(blockIndex); ScrollToSelection(); } } }