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 Includes method checks for unicode blocks as 89 // defined by Be, 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 && !fUnicodeBlocks.Includes( 96 kUnicodeBlocks[blockIndex].block)) 97 return false; 98 99 if (!fCharacterFont.IncludesBlock( 100 kUnicodeBlocks[blockIndex].start, 101 kUnicodeBlocks[blockIndex].end)) 102 return false; 103 } 104 105 return true; 106 } 107 108 109 void 110 UnicodeBlockView::_UpdateBlocks() 111 { 112 MakeEmpty(); 113 114 for (int32 i = 0; i < fBlocks.CountItems(); i++) { 115 if (fFilter.Length() != 0) { 116 if (strcasestr(kUnicodeBlocks[i].name, fFilter.String()) == NULL) 117 continue; 118 } 119 120 AddItem(fBlocks.ItemAt(i)); 121 122 fBlocks.ItemAt(i)->SetEnabled(IsShowingBlock(i)); 123 } 124 } 125 126 127 void 128 UnicodeBlockView::_CreateBlocks() 129 { 130 float minWidth = 0; 131 for (uint32 i = 0; i < kNumUnicodeBlocks; i++) { 132 BlockListItem* item = new BlockListItem(kUnicodeBlocks[i].name, i); 133 fBlocks.AddItem(item); 134 135 float width = StringWidth(item->Text()); 136 if (minWidth < width) 137 minWidth = width; 138 } 139 140 SetExplicitMinSize(BSize(minWidth / 2, 32)); 141 SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET)); 142 143 _UpdateBlocks(); 144 } 145 146 147 void 148 UnicodeBlockView::SelectBlockForCharacter(uint32 character) 149 { 150 // find block containing the character 151 int32 blockNumber = BlockForCharacter(character); 152 153 if (blockNumber > 0) { 154 BlockListItem* block = fBlocks.ItemAt(blockNumber); 155 156 int32 blockIndex = IndexOf(block); 157 158 if (blockIndex >= 0) { 159 Select(blockIndex); 160 ScrollToSelection(); 161 } 162 } 163 } 164