1 /* 2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "UnicodeBlockView.h" 8 9 #include <stdio.h> 10 #include <string.h> 11 12 #include "UnicodeBlocks.h" 13 14 15 BlockListItem::BlockListItem(const char* label, uint32 blockIndex) 16 : BStringItem(label), 17 fBlockIndex(blockIndex) 18 { 19 } 20 21 22 // #pragma mark - 23 24 25 UnicodeBlockView::UnicodeBlockView(const char* name) 26 : BListView(name), 27 fBlocks(kNumUnicodeBlocks, true), 28 fShowPrivateBlocks(false), 29 fShowContainedBlocksOnly(false) 30 { 31 _CreateBlocks(); 32 } 33 34 35 UnicodeBlockView::~UnicodeBlockView() 36 { 37 } 38 39 40 void 41 UnicodeBlockView::SetFilter(const char* filter) 42 { 43 fFilter = filter; 44 _UpdateBlocks(); 45 } 46 47 void 48 UnicodeBlockView::SetCharacterFont(const BFont& font) 49 { 50 fCharacterFont = font; 51 fUnicodeBlocks = fCharacterFont.Blocks(); 52 _UpdateBlocks(); 53 } 54 55 56 void 57 UnicodeBlockView::ShowPrivateBlocks(bool show) 58 { 59 if (fShowPrivateBlocks == show) 60 return; 61 62 fShowPrivateBlocks = show; 63 _UpdateBlocks(); 64 } 65 66 67 void 68 UnicodeBlockView::ShowContainedBlocksOnly(bool show) 69 { 70 if (fShowContainedBlocksOnly == show) 71 return; 72 73 fShowContainedBlocksOnly = show; 74 _UpdateBlocks(); 75 } 76 77 78 bool 79 UnicodeBlockView::IsShowingBlock(int32 blockIndex) const 80 { 81 if (blockIndex < 0 || blockIndex >= (int32)kNumUnicodeBlocks) 82 return false; 83 84 if (!fShowPrivateBlocks && kUnicodeBlocks[blockIndex].private_block) 85 return false; 86 87 // The reason for two checks is BeOS compatibility. 88 // The first one checks for unicode blocks as defined by Be, 89 // but there are only 71 such blocks. 90 // The rest of the blocks (denoted by kNoBlock) need to 91 // be queried by searching for the start and end codepoints 92 // via the IncludesBlock method. 93 if (fShowContainedBlocksOnly) { 94 if (kUnicodeBlocks[blockIndex].block != kNoBlock) 95 return (fUnicodeBlocks & kUnicodeBlocks[blockIndex].block) != kNoBlock; 96 97 if (!fCharacterFont.IncludesBlock( 98 kUnicodeBlocks[blockIndex].start, 99 kUnicodeBlocks[blockIndex].end)) 100 return false; 101 } 102 103 return true; 104 } 105 106 107 void 108 UnicodeBlockView::_UpdateBlocks() 109 { 110 MakeEmpty(); 111 112 for (int32 i = 0; i < fBlocks.CountItems(); i++) { 113 if (fFilter.Length() != 0) { 114 if (strcasestr(kUnicodeBlocks[i].name, fFilter.String()) == NULL) 115 continue; 116 } 117 118 AddItem(fBlocks.ItemAt(i)); 119 120 fBlocks.ItemAt(i)->SetEnabled(IsShowingBlock(i)); 121 } 122 } 123 124 125 void 126 UnicodeBlockView::_CreateBlocks() 127 { 128 float minWidth = 0; 129 for (uint32 i = 0; i < kNumUnicodeBlocks; i++) { 130 BlockListItem* item = new BlockListItem(kUnicodeBlocks[i].name, i); 131 fBlocks.AddItem(item); 132 133 float width = StringWidth(item->Text()); 134 if (minWidth < width) 135 minWidth = width; 136 } 137 138 SetExplicitMinSize(BSize(minWidth / 2, 32)); 139 SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET)); 140 141 _UpdateBlocks(); 142 } 143 144 145 void 146 UnicodeBlockView::SelectBlockForCharacter(uint32 character) 147 { 148 // find block containing the character 149 int32 blockNumber = BlockForCharacter(character); 150 151 if (blockNumber > 0) { 152 BlockListItem* block = fBlocks.ItemAt(blockNumber); 153 154 int32 blockIndex = IndexOf(block); 155 156 if (blockIndex >= 0) { 157 Select(blockIndex); 158 ScrollToSelection(); 159 } 160 } 161 } 162