* Added filter control for the Unicode block list.
* The status line now contains the character as well, as suggested by humdinger. * Moved the list view into its own class UnicodeBlockView. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29863 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cdc7175bfd
commit
8f400a127a
@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Button.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
@ -17,15 +18,17 @@
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <Path.h>
|
||||
#include <Roster.h>
|
||||
#include <ScrollView.h>
|
||||
#include <Slider.h>
|
||||
#include <SplitLayoutBuilder.h>
|
||||
#include <StringView.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include "CharacterView.h"
|
||||
#include "UnicodeBlocks.h"
|
||||
#include "UnicodeBlockView.h"
|
||||
|
||||
|
||||
static const uint32 kMsgUnicodeBlockSelected = 'unbs';
|
||||
@ -34,6 +37,9 @@ static const uint32 kMsgFontSelected = 'fnts';
|
||||
static const uint32 kMsgFontSizeChanged = 'fsch';
|
||||
static const uint32 kMsgPrivateBlocks = 'prbl';
|
||||
static const uint32 kMsgContainedBlocks = 'cnbl';
|
||||
static const uint32 kMsgFilterChanged = 'fltr';
|
||||
static const uint32 kMsgFilterEntered = 'flte';
|
||||
static const uint32 kMsgClearFilter = 'clrf';
|
||||
|
||||
static const int32 kMinFontSize = 10;
|
||||
static const int32 kMaxFontSize = 72;
|
||||
@ -59,6 +65,55 @@ private:
|
||||
mutable char fText[32];
|
||||
};
|
||||
|
||||
class MouseMovedFilter : public BMessageFilter {
|
||||
public:
|
||||
MouseMovedFilter()
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_MOUSE_MOVED)
|
||||
{
|
||||
}
|
||||
|
||||
int32 ResetMoved()
|
||||
{
|
||||
int32 old = fMouseMoved;
|
||||
fMouseMoved = 0;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
virtual filter_result Filter(BMessage* message, BHandler** /*_target*/)
|
||||
{
|
||||
fMouseMoved++;
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
int32 fMouseMoved;
|
||||
};
|
||||
|
||||
class EscapeMessageFilter : public BMessageFilter {
|
||||
public:
|
||||
EscapeMessageFilter(uint32 command)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN),
|
||||
fCommand(command)
|
||||
{
|
||||
}
|
||||
|
||||
virtual filter_result Filter(BMessage* message, BHandler** /*_target*/)
|
||||
{
|
||||
const char* bytes;
|
||||
if (message->what != B_KEY_DOWN
|
||||
|| message->FindString("bytes", &bytes) != B_OK
|
||||
|| bytes[0] != B_ESCAPE)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
Looper()->PostMessage(fCommand);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 fCommand;
|
||||
};
|
||||
|
||||
|
||||
CharacterWindow::CharacterWindow()
|
||||
: BWindow(BRect(100, 100, 700, 550), "CharacterMap", B_TITLED_WINDOW,
|
||||
@ -80,7 +135,13 @@ CharacterWindow::CharacterWindow()
|
||||
|
||||
BMenuBar* menuBar = new BMenuBar("menu");
|
||||
|
||||
fUnicodeBlockView = new BListView("unicodeBlocks");
|
||||
fFilterControl = new BTextControl("Filter:", NULL, new BMessage(kMsgFilterEntered));
|
||||
fFilterControl->SetModificationMessage(new BMessage(kMsgFilterChanged));
|
||||
|
||||
BButton* clearButton = new BButton("clear", "Clear",
|
||||
new BMessage(kMsgClearFilter));
|
||||
|
||||
fUnicodeBlockView = new UnicodeBlockView("unicodeBlocks");
|
||||
fUnicodeBlockView->SetSelectionMessage(
|
||||
new BMessage(kMsgUnicodeBlockSelected));
|
||||
|
||||
@ -90,11 +151,16 @@ CharacterWindow::CharacterWindow()
|
||||
fCharacterView = new CharacterView("characters");
|
||||
fCharacterView->SetTarget(this, kMsgCharacterChanged);
|
||||
|
||||
// TODO: have a context object shared by CharacterView/UnicodeBlockView
|
||||
bool show;
|
||||
if (settings.FindBool("show private blocks", &show) == B_OK)
|
||||
if (settings.FindBool("show private blocks", &show) == B_OK) {
|
||||
fCharacterView->ShowPrivateBlocks(show);
|
||||
if (settings.FindBool("show contained blocks only", &show) == B_OK)
|
||||
fUnicodeBlockView->ShowPrivateBlocks(show);
|
||||
}
|
||||
if (settings.FindBool("show contained blocks only", &show) == B_OK) {
|
||||
fCharacterView->ShowContainedBlocksOnly(show);
|
||||
fUnicodeBlockView->ShowPrivateBlocks(show);
|
||||
}
|
||||
|
||||
const char* family;
|
||||
const char* style;
|
||||
@ -130,7 +196,11 @@ CharacterWindow::CharacterWindow()
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL)
|
||||
.Add(menuBar)
|
||||
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)//BSplitLayoutBuilder()
|
||||
.Add(unicodeScroller)
|
||||
.Add(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
||||
.Add(fFilterControl)
|
||||
.Add(clearButton))
|
||||
.Add(unicodeScroller))
|
||||
.Add(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
.Add(characterScroller)
|
||||
.Add(fFontSizeSlider)
|
||||
@ -167,8 +237,14 @@ CharacterWindow::CharacterWindow()
|
||||
|
||||
menuBar->AddItem(_CreateFontMenu());
|
||||
|
||||
_CreateUnicodeBlocks();
|
||||
InvalidateLayout();
|
||||
AddCommonFilter(new EscapeMessageFilter(kMsgClearFilter));
|
||||
fMouseMovedFilter = new MouseMovedFilter();
|
||||
AddCommonFilter(fMouseMovedFilter);
|
||||
|
||||
// TODO: why is this needed?
|
||||
fUnicodeBlockView->SetTarget(this);
|
||||
|
||||
fFilterControl->MakeFocus();
|
||||
}
|
||||
|
||||
|
||||
@ -192,7 +268,13 @@ CharacterWindow::MessageReceived(BMessage* message)
|
||||
|| index < 0)
|
||||
break;
|
||||
|
||||
fCharacterView->ScrollTo(index);
|
||||
BlockListItem* item
|
||||
= static_cast<BlockListItem*>(fUnicodeBlockView->ItemAt(index));
|
||||
fCharacterView->ScrollTo(item->BlockIndex());
|
||||
|
||||
// Give the filter control focus if we got here by mouse action
|
||||
if (fMouseMovedFilter->ResetMoved())
|
||||
fFilterControl->MakeFocus();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -202,13 +284,16 @@ CharacterWindow::MessageReceived(BMessage* message)
|
||||
if (message->FindInt32("character", (int32*)&character) != B_OK)
|
||||
break;
|
||||
|
||||
char utf8[16];
|
||||
CharacterView::UnicodeToUTF8(character, utf8, sizeof(utf8));
|
||||
|
||||
char utf8Hex[32];
|
||||
CharacterView::UnicodeToUTF8Hex(character, utf8Hex,
|
||||
sizeof(utf8Hex));
|
||||
|
||||
char text[128];
|
||||
snprintf(text, sizeof(text), "Code: %#lx (%ld), UTF-8: %s",
|
||||
character, character, utf8Hex);
|
||||
snprintf(text, sizeof(text), "'%s' Code: %#lx (%ld), UTF-8: %s",
|
||||
utf8, character, character, utf8Hex);
|
||||
|
||||
fCodeView->SetText(text);
|
||||
break;
|
||||
@ -259,7 +344,7 @@ CharacterWindow::MessageReceived(BMessage* message)
|
||||
item->SetMarked(!item->IsMarked());
|
||||
|
||||
fCharacterView->ShowPrivateBlocks(item->IsMarked());
|
||||
_UpdateUnicodeBlocks();
|
||||
fUnicodeBlockView->ShowPrivateBlocks(item->IsMarked());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -273,10 +358,25 @@ CharacterWindow::MessageReceived(BMessage* message)
|
||||
item->SetMarked(!item->IsMarked());
|
||||
|
||||
fCharacterView->ShowContainedBlocksOnly(item->IsMarked());
|
||||
_UpdateUnicodeBlocks();
|
||||
fUnicodeBlockView->ShowContainedBlocksOnly(item->IsMarked());
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgFilterChanged:
|
||||
fUnicodeBlockView->SetFilter(fFilterControl->Text());
|
||||
break;
|
||||
|
||||
case kMsgFilterEntered:
|
||||
fUnicodeBlockView->MakeFocus();
|
||||
fUnicodeBlockView->Select(0);
|
||||
fMouseMovedFilter->ResetMoved();
|
||||
break;
|
||||
|
||||
case kMsgClearFilter:
|
||||
fFilterControl->SetText("");
|
||||
fFilterControl->MakeFocus();
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
@ -412,41 +512,3 @@ CharacterWindow::_CreateFontMenu()
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CharacterWindow::_UpdateUnicodeBlocks()
|
||||
{
|
||||
for (int32 i = 0; i < fUnicodeBlockView->CountItems(); i++) {
|
||||
BStringItem* item
|
||||
= static_cast<BStringItem*>(fUnicodeBlockView->ItemAt(i));
|
||||
|
||||
bool enabled = fCharacterView->IsShowingBlock(i);
|
||||
|
||||
if (item->IsEnabled() != enabled) {
|
||||
item->SetEnabled(enabled);
|
||||
fUnicodeBlockView->InvalidateItem(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CharacterWindow::_CreateUnicodeBlocks()
|
||||
{
|
||||
float minWidth = 0;
|
||||
for (uint32 i = 0; i < kNumUnicodeBlocks; i++) {
|
||||
BStringItem* item = new BStringItem(kUnicodeBlocks[i].name);
|
||||
fUnicodeBlockView->AddItem(item);
|
||||
|
||||
float width = fUnicodeBlockView->StringWidth(item->Text());
|
||||
if (minWidth < width)
|
||||
minWidth = width;
|
||||
}
|
||||
|
||||
fUnicodeBlockView->SetExplicitMinSize(BSize(minWidth / 2, 32));
|
||||
fUnicodeBlockView->SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET));
|
||||
|
||||
_UpdateUnicodeBlocks();
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,10 @@ class BMenu;
|
||||
class BMenuItem;
|
||||
class BSlider;
|
||||
class BStringView;
|
||||
class BTextControl;
|
||||
class CharacterView;
|
||||
class MouseMovedFilter;
|
||||
class UnicodeBlockView;
|
||||
|
||||
|
||||
class CharacterWindow : public BWindow {
|
||||
@ -33,15 +36,15 @@ private:
|
||||
|
||||
void _SetFont(const char* family, const char* style);
|
||||
BMenu* _CreateFontMenu();
|
||||
void _UpdateUnicodeBlocks();
|
||||
void _CreateUnicodeBlocks();
|
||||
|
||||
private:
|
||||
BListView* fUnicodeBlockView;
|
||||
BTextControl* fFilterControl;
|
||||
UnicodeBlockView* fUnicodeBlockView;
|
||||
CharacterView* fCharacterView;
|
||||
BMenuItem* fSelectedFontItem;
|
||||
BSlider* fFontSizeSlider;
|
||||
BStringView* fCodeView;
|
||||
MouseMovedFilter* fMouseMovedFilter;
|
||||
};
|
||||
|
||||
#endif // CHARACTER_WINDOW_H
|
||||
|
@ -9,6 +9,7 @@ Application CharacterMap :
|
||||
CharacterView.cpp
|
||||
CharacterWindow.cpp
|
||||
UnicodeBlocks.cpp
|
||||
UnicodeBlockView.cpp
|
||||
|
||||
: be
|
||||
: CharacterMap.rdef
|
||||
|
135
src/apps/charactermap/UnicodeBlockView.cpp
Normal file
135
src/apps/charactermap/UnicodeBlockView.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "UnicodeBlockView.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UnicodeBlockView::~UnicodeBlockView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnicodeBlockView::SetFilter(const char* filter)
|
||||
{
|
||||
fFilter = filter;
|
||||
_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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnicodeBlockView::AttachedToWindow()
|
||||
{
|
||||
// TODO: if we're calling this in the constructor, strange things happen
|
||||
_CreateBlocks();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnicodeBlockView::DetachedFromWindow()
|
||||
{
|
||||
MakeEmpty();
|
||||
fBlocks.MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!IsShowingBlock(i))
|
||||
continue;
|
||||
|
||||
AddItem(fBlocks.ItemAt(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();
|
||||
}
|
||||
|
59
src/apps/charactermap/UnicodeBlockView.h
Normal file
59
src/apps/charactermap/UnicodeBlockView.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef UNICODE_BLOCK_VIEW_H
|
||||
#define UNICODE_BLOCK_VIEW_H
|
||||
|
||||
|
||||
#include <ListView.h>
|
||||
#include <ObjectList.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BlockListItem : public BStringItem {
|
||||
public:
|
||||
BlockListItem(const char* label, uint32 blockIndex);
|
||||
|
||||
uint32 BlockIndex() const { return fBlockIndex; }
|
||||
|
||||
private:
|
||||
uint32 fBlockIndex;
|
||||
};
|
||||
|
||||
|
||||
class UnicodeBlockView : public BListView {
|
||||
public:
|
||||
UnicodeBlockView(const char* name);
|
||||
virtual ~UnicodeBlockView();
|
||||
|
||||
void SetFilter(const char* filter);
|
||||
const char* Filter() const
|
||||
{ return fFilter.String(); }
|
||||
|
||||
void ShowPrivateBlocks(bool show);
|
||||
bool IsShowingPrivateBlocks() const
|
||||
{ return fShowPrivateBlocks; }
|
||||
|
||||
void ShowContainedBlocksOnly(bool show);
|
||||
bool IsShowingContainedBlocksOnly() const
|
||||
{ return fShowContainedBlocksOnly; }
|
||||
|
||||
bool IsShowingBlock(int32 blockIndex) const;
|
||||
|
||||
protected:
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
||||
private:
|
||||
void _UpdateBlocks();
|
||||
void _CreateBlocks();
|
||||
|
||||
private:
|
||||
BObjectList<BlockListItem> fBlocks;
|
||||
BString fFilter;
|
||||
bool fShowPrivateBlocks;
|
||||
bool fShowContainedBlocksOnly;
|
||||
};
|
||||
|
||||
#endif // UNICODE_BLOCK_VIEW_H
|
@ -130,7 +130,7 @@ const struct unicode_block_entry kUnicodeBlocks[] = {
|
||||
{"Vai", 0xa500, 0xa63f, false, kNoBlock},
|
||||
{"Cyrillic Extended B", 0xa640, 0xa69f, false, kNoBlock},
|
||||
{"Modifier Tone Letters", 0xa700, 0xa71f, false, kNoBlock},
|
||||
{"Lating Extended D", 0xa720, 0xa7ff, false, kNoBlock},
|
||||
{"Latin Extended D", 0xa720, 0xa7ff, false, kNoBlock},
|
||||
{"Syloti Nagri", 0xa800, 0xa82f, false, kNoBlock},
|
||||
{"Phags-pa", 0xa840, 0xa87f, false, kNoBlock},
|
||||
{"Saurashtra", 0xa880, 0xa8df, false, kNoBlock},
|
||||
|
Loading…
Reference in New Issue
Block a user