* Started an application showing the Unicode character map.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29815 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-31 10:45:34 +00:00
parent 0562493379
commit b045287228
11 changed files with 1226 additions and 0 deletions
+1
View File
@@ -7,6 +7,7 @@ SubInclude HAIKU_TOP src apps autoraise ;
SubInclude HAIKU_TOP src apps bsnow ;
SubInclude HAIKU_TOP src apps bootman ;
SubInclude HAIKU_TOP src apps cdplayer ;
SubInclude HAIKU_TOP src apps charactermap ;
SubInclude HAIKU_TOP src apps clock ;
SubInclude HAIKU_TOP src apps codycam ;
SubInclude HAIKU_TOP src apps cortex ;
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright 2009, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "CharacterMap.h"
#include <stdlib.h>
#include <Alert.h>
#include <Application.h>
#include <TextView.h>
#include "CharacterWindow.h"
const char* kSignature = "application/x-vnd.Haiku-CharacterMap";
CharacterMap::CharacterMap()
: BApplication(kSignature)
{
}
CharacterMap::~CharacterMap()
{
}
void
CharacterMap::ReadyToRun()
{
fWindow = new CharacterWindow();
fWindow->Show();
}
void
CharacterMap::RefsReceived(BMessage* message)
{
fWindow->PostMessage(message);
}
void
CharacterMap::MessageReceived(BMessage* message)
{
BApplication::MessageReceived(message);
}
void
CharacterMap::AboutRequested()
{
BAlert *alert = new BAlert("about", "CharacterMap\n"
"\twritten by Axel Dörfler\n"
"\tCopyright 2009, Haiku Inc.\n", "Ok");
BTextView *view = alert->TextView();
BFont font;
view->SetStylable(true);
view->GetFont(&font);
font.SetSize(18);
font.SetFace(B_BOLD_FACE);
view->SetFontAndColor(0, 12, &font);
alert->Go();
}
// #pragma mark -
int
main(int /*argc*/, char** /*argv*/)
{
CharacterMap app;
app.Run();
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright 2009, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef CHARACTER_MAP_H
#define CHARACTER_MAP_H
#include <Application.h>
class BMessage;
class CharacterWindow;
class CharacterMap : public BApplication {
public:
CharacterMap();
virtual ~CharacterMap();
virtual void ReadyToRun();
virtual void RefsReceived(BMessage* message);
virtual void MessageReceived(BMessage* message);
virtual void AboutRequested();
private:
CharacterWindow* fWindow;
};
extern const char* kSignature;
#endif // CHARACTER_MAP_H
+32
View File
@@ -0,0 +1,32 @@
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-CharacterMap";
resource app_version {
major = 1,
middle = 0,
minor = 0,
variety = B_APPV_BETA,
internal = 0,
short_info = "CharacterMap",
long_info = "CharacterMap ©2009 Haiku, Inc."
};
resource app_flags B_MULTIPLE_LAUNCH;
resource vector_icon {
$"6E63696608050004005F020006023D5F39368F62B905F93FFB6B4ACB36BEDE32"
$"00032288FF1944E7020006023AAFCC3BFAA8BF50A93E3D044B460F48AEEC0002"
$"0258FF1919E7020006023BA7EB3CD6E4BF5D013E2A4C4B0DDA478DDF0097C3FF"
$"FF376AFF02000602380D3A384399BEF6CA3EAF9C4B2833C6F2DC00E3ECFFFFAC"
$"C7FF02000602371F7FB98A813FA8F13D3A58C4B8AC48909300CEDEFFFF3778FF"
$"02000602371F7FB98A813FA8F13D3A58C60C5648909300BADAFFFF032E850B0A"
$"0432482C503E543C4B0A0550485452485E565A60500A0A47273D24322A244A2C"
$"4E34C2B0BE5BC408BFBFC94F485C52520A0447273C2D485C52520A08BE5AC40E"
$"4058485CBE3D2D322A244A2C4EB935C20F0A03BC12BB843BC1D3B9EBC0700A03"
$"BC12BB84BCC2BE1AB9EBC0700A03BD75C0B13BC1D3B9EBC0700A03BCC2BE1ABD"
$"75C0B1B9EBC0700A032C4E34C2B0B939C20A0A043D24322A3C2D4727090A0102"
$"0001000A0001021001178400040A020103000A030109000A030106000A060107"
$"000A070108000A04020405000A05010A00"
};
+313
View File
@@ -0,0 +1,313 @@
/*
* Copyright 2009, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "CharacterView.h"
#include <stdio.h>
#include <LayoutUtils.h>
#include <ScrollBar.h>
#include "UnicodeBlocks.h"
void
unicode_to_utf8(uint32 c, char** out)
{
char* s = *out;
if (c < 0x80)
*(s++) = c;
else if (c < 0x800) {
*(s++) = 0xc0 | (c >> 6);
*(s++) = 0x80 | (c & 0x3f);
} else if (c < 0x10000) {
*(s++) = 0xe0 | (c >> 12);
*(s++) = 0x80 | ((c >> 6) & 0x3f);
*(s++) = 0x80 | (c & 0x3f);
} else if (c <= 0x10ffff) {
*(s++) = 0xf0 | (c >> 18);
*(s++) = 0x80 | ((c >> 12) & 0x3f);
*(s++) = 0x80 | ((c >> 6) & 0x3f);
*(s++) = 0x80 | (c & 0x3f);
}
*out = s;
}
// #pragma mark -
CharacterView::CharacterView(const char* name)
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
fShowPrivateBlocks(false),
fShowContainedBlocksOnly(false)
{
fTitleTops = new int32[kNumUnicodeBlocks];
fCharacterFont.SetSize(fCharacterFont.Size() * 1.5f);
}
CharacterView::~CharacterView()
{
delete[] fTitleTops;
}
void
CharacterView::SetCharacterFont(const BFont& font)
{
fCharacterFont = font;
InvalidateLayout();
}
void
CharacterView::ShowPrivateBlocks(bool show)
{
if (fShowPrivateBlocks == show)
return;
fShowPrivateBlocks = show;
InvalidateLayout();
}
void
CharacterView::ShowContainedBlocksOnly(bool show)
{
if (fShowContainedBlocksOnly == show)
return;
fShowContainedBlocksOnly = show;
InvalidateLayout();
}
bool
CharacterView::IsShowingBlock(int32 blockIndex) const
{
if (!fShowPrivateBlocks && kUnicodeBlocks[blockIndex].private_block)
return false;
if (fShowContainedBlocksOnly
&& !fCharacterFont.Blocks().Includes(
kUnicodeBlocks[blockIndex].block)) {
return false;
}
return true;
}
void
CharacterView::ScrollTo(int32 blockIndex)
{
if (blockIndex < 0)
blockIndex = 0;
else if (blockIndex >= (int32)kNumUnicodeBlocks)
blockIndex = kNumUnicodeBlocks - 1;
BView::ScrollTo(0.0f, fTitleTops[blockIndex]);
}
void
CharacterView::AttachedToWindow()
{
}
void
CharacterView::DetachedFromWindow()
{
}
BSize
CharacterView::MinSize()
{
return BLayoutUtils::ComposeSize(ExplicitMinSize(),
BSize(fCharacterHeight, fCharacterHeight + fTitleHeight));
}
void
CharacterView::FrameResized(float width, float height)
{
puts("hey");
_UpdateSize();
}
void
CharacterView::MouseDown(BPoint where)
{
}
void
CharacterView::MouseUp(BPoint where)
{
}
void
CharacterView::MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
}
void
CharacterView::MessageReceived(BMessage* message)
{
}
void
CharacterView::Draw(BRect updateRect)
{
const int32 kStartX = fGap / 2;
BFont font;
GetFont(&font);
int32 y = 2;
// TODO: jump to the correct start
for (uint32 i = 0; i < kNumUnicodeBlocks; i++) {
if (!IsShowingBlock(i))
continue;
if (fTitleTops[i] > updateRect.bottom)
break;
SetHighColor(0, 0, 0);
DrawString(kUnicodeBlocks[i].name, BPoint(3, y + fTitleBase));
y += fTitleHeight;
int32 x = kStartX;
SetFont(&fCharacterFont);
char character[16];
for (uint32 c = kUnicodeBlocks[i].start; c <= kUnicodeBlocks[i].end;
c++) {
if (y + fCharacterHeight > updateRect.top
&& y < updateRect.bottom) {
#if 0
// Stroke frame around the charater
SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
StrokeRect(BRect(x, y, x + fCharacterWidth,
y + fCharacterHeight - fGap));
SetHighColor(0, 0, 0);
#endif
// Draw character
char* end = character;
unicode_to_utf8(c, &end);
end[0] = '\0';
DrawString(character,
BPoint(x + (fCharacterWidth - StringWidth(character)) / 2,
y + fCharacterBase));
}
x += fCharacterWidth + fGap;
if (x + fCharacterWidth + fGap / 2 >= fDataRect.right) {
y += fCharacterHeight;
x = kStartX;
}
}
if (x != kStartX)
y += fCharacterHeight;
y += fTitleGap;
SetFont(&font);
}
}
void
CharacterView::DoLayout()
{
_UpdateSize();
}
void
CharacterView::_UpdateSize()
{
// Compute data rect
BRect bounds = Bounds();
font_height fontHeight;
GetFontHeight(&fontHeight);
fTitleHeight = (int32)ceilf(fontHeight.ascent + fontHeight.descent
+ fontHeight.leading);
fTitleBase = (int32)ceilf(fontHeight.ascent);
// Find widest character
fCharacterWidth = (int32)ceilf(fCharacterFont.StringWidth("W"));
if (fCharacterFont.IsFullAndHalfFixed()) {
// TODO: improve this!
fCharacterWidth *= 2;
}
fCharacterFont.GetHeight(&fontHeight);
fCharacterHeight = (int32)ceilf(fontHeight.ascent + fontHeight.descent
+ fontHeight.leading);
fCharacterBase = (int32)ceilf(fontHeight.ascent);
fGap = (int32)roundf(fCharacterHeight / 8.0);
if (fGap < 3)
fGap = 3;
fCharacterHeight += fGap;
fTitleGap = fGap * 3;
fDataRect.right = bounds.Width();
fDataRect.bottom = 0;
int32 charactersPerLine = int32(bounds.Width() / (fGap + fCharacterWidth));
if (charactersPerLine == 0)
charactersPerLine = 1;
for (uint32 i = 0; i < kNumUnicodeBlocks; i++) {
fTitleTops[i] = (int32)ceilf(fDataRect.bottom);
if (!IsShowingBlock(i))
continue;
int32 lines = (kUnicodeBlocks[i].Count() + charactersPerLine - 1)
/ charactersPerLine;
fDataRect.bottom += lines * fCharacterHeight + fTitleHeight + fTitleGap;
}
// Update scroll bars
BScrollBar* scroller = ScrollBar(B_VERTICAL);
if (scroller == NULL)
return;
if (bounds.Height() > fDataRect.Height()) {
// no scrolling
scroller->SetRange(0.0f, 0.0f);
scroller->SetValue(0.0f);
} else {
scroller->SetRange(0.0f, fDataRect.Height() - bounds.Height() - 1.0f);
scroller->SetProportion(bounds.Height () / fDataRect.Height());
// scroll up if there is empty room on bottom
if (fDataRect.Height() < bounds.bottom) {
ScrollBy(0.0f, bounds.bottom - fDataRect.Height());
}
}
Invalidate();
}
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright 2009, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef CHARACTER_VIEW_H
#define CHARACTER_VIEW_H
#include <View.h>
class CharacterView : public BView {
public:
CharacterView(const char* name);
virtual ~CharacterView();
void SetCharacterFont(const BFont& font);
const BFont& CharacterFont() { return fCharacterFont; }
void ShowPrivateBlocks(bool show);
bool IsShowingPrivateBlocks() const
{ return fShowPrivateBlocks; }
void ShowContainedBlocksOnly(bool show);
bool IsShowingContainedBlocksOnly() const
{ return fShowContainedBlocksOnly; }
bool IsShowingBlock(int32 blockIndex) const;
void ScrollTo(int32 blockIndex);
protected:
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual BSize MinSize();
virtual void FrameResized(float width, float height);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void MessageReceived(BMessage* message);
virtual void Draw(BRect updateRect);
virtual void DoLayout();
private:
bool _IncludeBlock(int32 index);
void _UpdateSize();
private:
bool fShowPrivateBlocks;
bool fShowContainedBlocksOnly;
BRect fDataRect;
BFont fCharacterFont;
int32 fCharacterWidth;
int32 fCharacterHeight;
int32 fCharacterBase;
int32 fTitleHeight;
int32 fTitleBase;
int32 fGap;
int32 fTitleGap;
int32* fTitleTops;
};
#endif // CHARACTER_VIEW_H
+412
View File
@@ -0,0 +1,412 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "CharacterWindow.h"
#include <stdio.h>
#include <Application.h>
#include <File.h>
#include <FindDirectory.h>
#include <GroupLayoutBuilder.h>
#include <ListView.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <Path.h>
#include <Roster.h>
#include <ScrollView.h>
#include <Slider.h>
#include <SplitLayoutBuilder.h>
#include "CharacterView.h"
#include "UnicodeBlocks.h"
static const uint32 kMsgUnicodeBlockSelected = 'unbs';
static const uint32 kMsgFontSelected = 'fnts';
static const uint32 kMsgFontSizeChanged = 'fsch';
static const uint32 kMsgPrivateBlocks = 'prbl';
static const uint32 kMsgContainedBlocks = 'cnbl';
static const int32 kMinFontSize = 10;
static const int32 kMaxFontSize = 72;
class FontSizeSlider : public BSlider {
public:
FontSizeSlider(const char* name, const char* label, BMessage* message,
int32 min, int32 max)
: BSlider(name, label, NULL, min, max, B_HORIZONTAL)
{
SetModificationMessage(message);
}
protected:
const char* UpdateText() const
{
snprintf(fText, sizeof(fText), "%ldpt", Value());
return fText;
}
private:
mutable char fText[32];
};
CharacterWindow::CharacterWindow()
: BWindow(BRect(100, 100, 500, 350), "CharacterMap", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
{
BMessage settings;
_LoadSettings(settings);
BRect frame;
if (settings.FindRect("window frame", &frame) == B_OK) {
MoveTo(frame.LeftTop());
ResizeTo(frame.Width(), frame.Height());
}
// create GUI
SetLayout(new BGroupLayout(B_VERTICAL));
BMenuBar* menuBar = new BMenuBar("menu");
fUnicodeBlockView = new BListView("unicodeBlocks");
fUnicodeBlockView->SetSelectionMessage(
new BMessage(kMsgUnicodeBlockSelected));
BScrollView* unicodeScroller = new BScrollView("unicodeScroller",
fUnicodeBlockView, 0, false, true);
fCharacterView = new CharacterView("characters");
bool show;
if (settings.FindBool("show private blocks", &show) == B_OK)
fCharacterView->ShowPrivateBlocks(show);
if (settings.FindBool("show contained blocks only", &show) == B_OK)
fCharacterView->ShowContainedBlocksOnly(show);
const char* family;
const char* style;
if (settings.FindString("font family", &family) == B_OK
&& settings.FindString("font style", &style) == B_OK) {
_SetFont(family, style);
}
int32 fontSize;
if (settings.FindInt32("font size", &fontSize) == B_OK) {
BFont font = fCharacterView->CharacterFont();
if (fontSize < kMinFontSize)
fontSize = kMinFontSize;
else if (fontSize > kMaxFontSize)
fontSize = kMaxFontSize;
font.SetSize(fontSize);
fCharacterView->SetCharacterFont(font);
} else
fontSize = (int32)fCharacterView->CharacterFont().Size();
BScrollView* characterScroller = new BScrollView("characterScroller",
fCharacterView, 0, false, true);
fFontSizeSlider = new FontSizeSlider("fontSizeSlider", "Font Size:",
new BMessage(kMsgFontSizeChanged), kMinFontSize, kMaxFontSize);
fFontSizeSlider->SetValue(fontSize);
AddChild(BGroupLayoutBuilder(B_VERTICAL)
.Add(menuBar)
.Add(BGroupLayoutBuilder()//BSplitLayoutBuilder()
.Add(unicodeScroller)
.Add(BGroupLayoutBuilder(B_VERTICAL)
.Add(characterScroller)
.Add(fFontSizeSlider))));
// Add menu
// "File" menu
BMenu* menu = new BMenu("File");
BMenuItem* item;
menu->AddItem(item = new BMenuItem("About CharacterMap" B_UTF8_ELLIPSIS,
new BMessage(B_ABOUT_REQUESTED)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
menu->SetTargetForItems(this);
item->SetTarget(be_app);
menuBar->AddItem(menu);
menu = new BMenu("View");
menu->AddItem(item = new BMenuItem("Show Private Blocks",
new BMessage(kMsgPrivateBlocks)));
item->SetMarked(fCharacterView->IsShowingPrivateBlocks());
menu->AddItem(item = new BMenuItem("Only Show Blocks Contained in Font",
new BMessage(kMsgContainedBlocks)));
item->SetMarked(fCharacterView->IsShowingContainedBlocksOnly());
menuBar->AddItem(menu);
menuBar->AddItem(_CreateFontMenu());
_CreateUnicodeBlocks();
InvalidateLayout();
}
CharacterWindow::~CharacterWindow()
{
}
void
CharacterWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgUnicodeBlockSelected:
{
int32 index;
if (message->FindInt32("index", &index) != B_OK
|| index < 0)
break;
fCharacterView->ScrollTo(index);
break;
}
case kMsgFontSelected:
{
BMenuItem* item;
if (message->FindPointer("source", (void**)&item) != B_OK)
break;
fSelectedFontItem->SetMarked(false);
if (item != NULL) {
item->SetMarked(true);
fSelectedFontItem = item;
_SetFont(item->Menu()->Name(), item->Label());
}
break;
}
case kMsgFontSizeChanged:
{
int32 size = fFontSizeSlider->Value();
if (size < kMinFontSize)
size = kMinFontSize;
else if (size > kMaxFontSize)
size = kMaxFontSize;
BFont font = fCharacterView->CharacterFont();
font.SetSize(size);
fCharacterView->SetCharacterFont(font);
break;
}
case kMsgPrivateBlocks:
{
BMenuItem* item;
if (message->FindPointer("source", (void**)&item) != B_OK
|| item == NULL)
break;
item->SetMarked(!item->IsMarked());
fCharacterView->ShowPrivateBlocks(item->IsMarked());
_UpdateUnicodeBlocks();
break;
}
case kMsgContainedBlocks:
{
BMenuItem* item;
if (message->FindPointer("source", (void**)&item) != B_OK
|| item == NULL)
break;
item->SetMarked(!item->IsMarked());
fCharacterView->ShowContainedBlocksOnly(item->IsMarked());
_UpdateUnicodeBlocks();
break;
}
default:
BWindow::MessageReceived(message);
break;
}
}
bool
CharacterWindow::QuitRequested()
{
_SaveSettings();
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
status_t
CharacterWindow::_OpenSettings(BFile& file, uint32 mode)
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
return B_ERROR;
path.Append("CharacterMap settings");
return file.SetTo(path.Path(), mode);
}
status_t
CharacterWindow::_LoadSettings(BMessage& settings)
{
BFile file;
status_t status = _OpenSettings(file, B_READ_ONLY);
if (status < B_OK)
return status;
return settings.Unflatten(&file);
}
status_t
CharacterWindow::_SaveSettings()
{
BFile file;
status_t status = _OpenSettings(file, B_WRITE_ONLY | B_CREATE_FILE
| B_ERASE_FILE);
if (status < B_OK)
return status;
BMessage settings('chrm');
status = settings.AddRect("window frame", Frame());
if (status != B_OK)
return status;
if (status == B_OK) {
status = settings.AddBool("show private blocks",
fCharacterView->IsShowingPrivateBlocks());
}
if (status == B_OK) {
status = settings.AddBool("show contained blocks only",
fCharacterView->IsShowingContainedBlocksOnly());
}
if (status == B_OK) {
BFont font = fCharacterView->CharacterFont();
status = settings.AddInt32("font size", font.Size());
font_family family;
font_style style;
if (status == B_OK)
font.GetFamilyAndStyle(&family, &style);
if (status == B_OK)
status = settings.AddString("font family", family);
if (status == B_OK)
status = settings.AddString("font style", style);
}
if (status == B_OK)
status = settings.Flatten(&file);
return status;
}
void
CharacterWindow::_SetFont(const char* family, const char* style)
{
BFont font = fCharacterView->CharacterFont();
font.SetFamilyAndStyle(family, style);
fCharacterView->SetCharacterFont(font);
}
BMenu*
CharacterWindow::_CreateFontMenu()
{
BMenu* menu = new BMenu("Font");
font_family currentFamily;
font_style currentStyle;
be_plain_font->GetFamilyAndStyle(&currentFamily, &currentStyle);
int32 numFamilies = count_font_families();
for (int32 i = 0; i < numFamilies; i++) {
font_family family;
if (get_font_family(i, &family) == B_OK) {
BMenu* subMenu = new BMenu(family);
menu->AddItem(new BMenuItem(subMenu,
new BMessage(kMsgFontSelected)));
int numStyles = count_font_styles(family);
for (int32 j = 0; j < numStyles; j++) {
font_style style;
uint32 flags;
if (get_font_style(family, j, &style, &flags) == B_OK) {
BMenuItem* item = new BMenuItem(style,
new BMessage(kMsgFontSelected));
subMenu->AddItem(item);
if (!strcmp(family, currentFamily)
&& !strcmp(style, currentStyle)) {
fSelectedFontItem = item;
item->SetMarked(true);
}
}
}
}
}
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));
// TODO: why is this ignored?
fUnicodeBlockView->SetExplicitMaxSize(BSize(minWidth, B_SIZE_UNSET));
_UpdateUnicodeBlocks();
}
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef CHARACTER_WINDOW_H
#define CHARACTER_WINDOW_H
#include <Messenger.h>
#include <Window.h>
class BFile;
class BListView;
class BMenu;
class BMenuItem;
class BSlider;
class CharacterView;
class CharacterWindow : public BWindow {
public:
CharacterWindow();
virtual ~CharacterWindow();
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
private:
status_t _OpenSettings(BFile& file, uint32 mode);
status_t _LoadSettings(BMessage& settings);
status_t _SaveSettings();
void _SetFont(const char* family, const char* style);
BMenu* _CreateFontMenu();
void _UpdateUnicodeBlocks();
void _CreateUnicodeBlocks();
private:
BListView* fUnicodeBlockView;
CharacterView* fCharacterView;
BMenuItem* fSelectedFontItem;
BSlider* fFontSizeSlider;
};
#endif // CHARACTER_WINDOW_H
+15
View File
@@ -0,0 +1,15 @@
SubDir HAIKU_TOP src apps charactermap ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders shared system ;
Application CharacterMap :
CharacterMap.cpp
CharacterView.cpp
CharacterWindow.cpp
UnicodeBlocks.cpp
: be
: CharacterMap.rdef
;
+195
View File
@@ -0,0 +1,195 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "UnicodeBlocks.h"
const unicode_block kNoBlock;
const struct unicode_block_entry kUnicodeBlocks[] = {
{"Basic Latin", 0x0000, 0x007f, false, B_BASIC_LATIN_BLOCK},
{"Latin-1 Supplement", 0x0080, 0x00ff, false, B_LATIN1_SUPPLEMENT_BLOCK},
{"Latin Extended A", 0x0100, 0x017f, false, B_LATIN_EXTENDED_A_BLOCK},
{"Latin Extended B", 0x0180, 0x024f, false, B_LATIN_EXTENDED_B_BLOCK},
{"IPA Extensions", 0x0250, 0x02af, false, B_IPA_EXTENSIONS_BLOCK},
{"Spacing Modifier Letters", 0x02b0, 0x02ff, false,
B_SPACING_MODIFIER_LETTERS_BLOCK},
{"Combining Diacritical Marks", 0x0300, 0x036f, false,
B_COMBINING_DIACRITICAL_MARKS_BLOCK},
{"Greek and Coptic", 0x0370, 0x03ff, false,
B_BASIC_GREEK_BLOCK | B_GREEK_SYMBOLS_AND_COPTIC_BLOCK},
{"Cyrillic", 0x0400, 0x04ff, false, B_CYRILLIC_BLOCK},
{"Cyrillic Supplement", 0x0500, 0x052f, false, B_CYRILLIC_BLOCK},
{"Armenian", 0x0530, 0x058f, false, B_ARMENIAN_BLOCK},
{"Hebrew", 0x0590, 0x05ff, false,
B_BASIC_HEBREW_BLOCK | B_HEBREW_EXTENDED_BLOCK},
{"Arabic", 0x0600, 0x06ff, false,
B_BASIC_ARABIC_BLOCK | B_ARABIC_EXTENDED_BLOCK},
{"Syriac", 0x0700, 0x074f, false, kNoBlock},
{"Arabic Supplement", 0x0750, 0x077f, false, kNoBlock},
{"Thaana", 0x0780, 0x07bf, false, kNoBlock},
{"N'Ko", 0x07c0, 0x07ff, false, kNoBlock},
{"Devanagari", 0x0900, 0x097f, false, B_DEVANAGARI_BLOCK},
{"Bengali", 0x0980, 0x09ff, false, B_BENGALI_BLOCK},
{"Gurmukhi", 0x0a00, 0x0a7f, false, B_GURMUKHI_BLOCK},
{"Gujarati", 0x0a80, 0x0aff, false, B_GUJARATI_BLOCK},
{"Oriya", 0x0b00, 0x0b7f, false, B_ORIYA_BLOCK},
{"Tamil", 0x0b80, 0x0bff, false, B_TAMIL_BLOCK},
{"Telugu", 0x0c00, 0x0c7f, false, B_TELUGU_BLOCK},
{"Kannada", 0x0c80, 0x0cff, false, B_KANNADA_BLOCK},
{"Malayalam", 0x0d00, 0x0d7f, false, B_MALAYALAM_BLOCK},
{"Sinhala", 0x0d80, 0x0dff, false, kNoBlock},
{"Thai", 0x0e00, 0x0e7f, false, B_THAI_BLOCK},
{"Lao", 0x0e80, 0x0eff, false, B_LAO_BLOCK},
{"Tibetan", 0x0f00, 0x0fff, false, kNoBlock},
{"Myanmar", 0x1000, 0x109f, false, kNoBlock},
{"Georgian", 0x10a0, 0x10ff, false, B_BASIC_GEORGIAN_BLOCK},
{"Hangul Jamo", 0x1100, 0x11ff, false, kNoBlock},
// TODO!
{"Ethiopic", 0x1200, 0x137f, false, kNoBlock},
{"Ethiopic Supplement", 0x1380, 0x139f, false, kNoBlock},
{"Cherokee", 0x13a0, 0x13ff, false, kNoBlock},
{"Unified Canadian Aboriginal Syllabics", 0x1400, 0x167f, false, kNoBlock},
{"Ogham", 0x1680, 0x169f, false, kNoBlock},
{"Runic", 0x16a0, 0x16ff, false, kNoBlock},
{"Tagalog", 0x1700, 0x171f, false, kNoBlock},
{"Hanunoo", 0x1720, 0x173f, false, kNoBlock},
{"Buhid", 0x1740, 0x175f, false, kNoBlock},
{"Tagbanwa", 0x1760, 0x177f, false, kNoBlock},
{"Khmer", 0x1780, 0x17ff, false, kNoBlock},
{"Mongolian", 0x1800, 0x18af, false, kNoBlock},
{"Limbu", 0x1900, 0x194f, false, kNoBlock},
{"Tai Le", 0x1950, 0x197f, false, kNoBlock},
{"New Tai Lue", 0x1980, 0x19df, false, kNoBlock},
{"Khmer Symbols", 0x19e0, 0x19ff, false, kNoBlock},
{"Buginese", 0x1a00, 0x1a1f, false, kNoBlock},
{"Balinese", 0x1b00, 0x1b7f, false, kNoBlock},
{"Sundanese", 0x1b80, 0x1bbf, false, kNoBlock},
{"Lepcha", 0x1c00, 0x1c4f, false, kNoBlock},
{"Ol Chiki", 0x1c50, 0x1c7f, false, kNoBlock},
{"Phonetic Extensions", 0x1d00, 0x1d7f, false, kNoBlock},
{"Phonetic Extensions Supplement", 0x1d80, 0x1dbf, false, kNoBlock},
{"Combining Diacritical Marks Supplement", 0x1dc0, 0x1dff, false, kNoBlock},
{"Latin Extended Additional", 0x1e00, 0x1eff, false, kNoBlock},
{"Greek Extended", 0x1f00, 0x1fff, false, kNoBlock},
{"General Punctuation", 0x2000, 0x206f, false, kNoBlock},
{"Superscripts and Subscripts", 0x2070, 0x209f, false, kNoBlock},
{"Currency Symbols", 0x20a0, 0x20cf, false, kNoBlock},
{"Combining Diacritical Marks for Symbols", 0x20d0, 0x20ff, false,
kNoBlock},
{"Letterlike Symbols", 0x2100, 0x214f, false, kNoBlock},
{"Number Forms", 0x2150, 0x218f, false, kNoBlock},
{"Arrows", 0x2190, 0x21ff, false, kNoBlock},
{"Mathematical Operators", 0x2200, 0x22ff, false, kNoBlock},
{"Miscellaneous Technical", 0x2300, 0x23ff, false, kNoBlock},
{"Control Pictures", 0x2400, 0x243f, false, kNoBlock},
{"Optical Character Recognition", 0x2440, 0x245f, false, kNoBlock},
{"Enclosed Alphanumerics", 0x2460, 0x24ff, false, kNoBlock},
{"Box Drawing", 0x2500, 0x257f, false, kNoBlock},
{"Block Elements", 0x2580, 0x259f, false, kNoBlock},
{"Geometric Shapes", 0x25a0, 0x25ff, false, kNoBlock},
{"Miscellaneous Symbols", 0x2600, 0x26ff, false, kNoBlock},
{"Dingbats", 0x2700, 0x27bf, false, kNoBlock},
{"Miscellaneous Mathematical Symbols A", 0x27c0, 0x27ef, false, kNoBlock},
{"Supplemental Arrows A", 0x27f0, 0x27ff, false, kNoBlock},
{"Braille Patterns", 0x2800, 0x28ff, false, kNoBlock},
{"Supplemental Arrows B", 0x2900, 0x297f, false, kNoBlock},
{"Miscellaneous Mathematical Symbols B", 0x2980, 0x29ff, false, kNoBlock},
{"Supplemental Mathematical Operators", 0x2a00, 0x2aff, false, kNoBlock},
{"Miscellaneous Symbols And Arrows", 0x2b00, 0x2bff, false, kNoBlock},
{"Glagotic", 0x2c00, 0x2c5f, false, kNoBlock},
{"Latin Extended C", 0x2c60, 0x2c7f, false, kNoBlock},
{"Coptic", 0x2c80, 0x2cff, false, kNoBlock},
{"Georgian Supplement", 0x2d00, 0x2d2f, false, kNoBlock},
{"Tifinagh", 0x2d30, 0x2d7f, false, kNoBlock},
{"Ethiopic Extended", 0x2d80, 0x2ddf, false, kNoBlock},
{"Cyrillic Extended A", 0x2de0, 0x2dff, false, kNoBlock},
{"Supplement Punctuation", 0x2e00, 0x2e7f, false, kNoBlock},
{"CJK Radicals Supplement", 0x2e80, 0x2eff, false, kNoBlock},
{"Kangxi Radicals", 0x2f00, 0x2fdf, false, kNoBlock},
{"Ideographic Description Characters", 0x2ff0, 0x2fff, false, kNoBlock},
{"CJK Symbols and Punctuation", 0x3000, 0x303f, false, kNoBlock},
{"Hiragana", 0x3040, 0x309f, false, kNoBlock},
{"Katakana", 0x30a0, 0x30ff, false, kNoBlock},
{"Bopomofo", 0x3100, 0x312f, false, kNoBlock},
{"Hangul Compatibility Jamo", 0x3130, 0x318f, false, kNoBlock},
{"Kanbun", 0x3190, 0x319f, false, kNoBlock},
{"Bopomofo Extended", 0x31a0, 0x31bf, false, kNoBlock},
{"CJK Strokes", 0x31c0, 0x31ef, false, kNoBlock},
{"Katakana Phonetic Extensions", 0x31f0, 0x31ff, false, kNoBlock},
{"Enclosed CJK Letters and Months", 0x3200, 0x32ff, false, kNoBlock},
{"CJK Compatibility", 0x3300, 0x33ff, false, kNoBlock},
{"CJK Unified Ideographs Extension A", 0x3400, 0x4dbf, false, kNoBlock},
{"Yijing Hexagram Symbols", 0x4dc0, 0x4dff, false, kNoBlock},
{"CJK Unified Ideographs", 0x4e00, 0x9fff, false, kNoBlock},
{"Yi Syllables", 0xa000, 0xa48f, false, kNoBlock},
{"Yi Radicals", 0xa490, 0xa4cf, false, kNoBlock},
{"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},
{"Syloti Nagri", 0xa800, 0xa82f, false, kNoBlock},
{"Phags-pa", 0xa840, 0xa87f, false, kNoBlock},
{"Saurashtra", 0xa880, 0xa8df, false, kNoBlock},
{"Kayah Li", 0xa900, 0xa92f, false, kNoBlock},
{"Rejang", 0xa930, 0xa95f, false, kNoBlock},
{"Cham", 0xaa00, 0xaa5f, false, kNoBlock},
{"Hangul Syllables", 0xac00, 0xd7af, false, kNoBlock},
// {"High Surrogates", 0xd800, 0xdb7f, false, kNoBlock},
// {"High Private Use Surrogates", 0xdb80, 0xdbff, false, kNoBlock},
// {"Low Surrogates", 0xdc00, 0xdfff, false, kNoBlock},
{"Private Use Area", 0xe000, 0xf8ff, true, kNoBlock},
{"CJK Compatibility Ideographs", 0xf900, 0xfaff, false, kNoBlock},
{"Alphabetic Presentation Forms", 0xfb00, 0xfb4f, false, kNoBlock},
{"Arabic Presentation Forms A", 0xfb50, 0xfdff, false, kNoBlock},
{"Variation Selectors", 0xfe00, 0xfe0f, false, kNoBlock},
{"Vertical Forms", 0xfe10, 0xfe1f, false, kNoBlock},
{"Combining Half Marks", 0xfe20, 0xfe2f, false, kNoBlock},
{"CJK Compatibility Forms", 0xfe30, 0xfe4f, false, kNoBlock},
{"Small Form Variants", 0xfe50, 0xfe6f, false, kNoBlock},
{"Arabic Presentation Forms B", 0xfe70, 0xfeff, false, kNoBlock},
{"Halfwidth and Fullwidth Forms", 0xff00, 0xffef, false, kNoBlock},
{"Specials", 0xfff0, 0xffff, false, kNoBlock},
{"Linear B Syllabary", 0x010000, 0x01007f, false, kNoBlock},
{"Linear B Ideograms", 0x010080, 0x0100ff, false, kNoBlock},
{"Aegean Numbers", 0x010100, 0x01013f, false, kNoBlock},
{"Ancient Greek Numbers", 0x010140, 0x01018f, false, kNoBlock},
{"Ancient Symbols", 0x010190, 0x0101cf, false, kNoBlock},
{"Phaistos Disc", 0x0101d0, 0x0101ff, false, kNoBlock},
{"Lycian", 0x010280, 0x01029f, false, kNoBlock},
{"Carian", 0x0102a0, 0x0102df, false, kNoBlock},
{"Old Italic", 0x010300, 0x01032f, false, kNoBlock},
{"Gothic", 0x010330, 0x01034f, false, kNoBlock},
{"Ugaritic", 0x010380, 0x01039f, false, kNoBlock},
{"Old Persian", 0x0103a0, 0x0103df, false, kNoBlock},
{"Deseret", 0x010400, 0x01044f, false, kNoBlock},
{"Shavian", 0x010450, 0x01047f, false, kNoBlock},
{"Osmanya", 0x010480, 0x0104af, false, kNoBlock},
{"Cypriot Syllabary", 0x010800, 0x01083f, false, kNoBlock},
{"Phoenician", 0x010900, 0x01091f, false, kNoBlock},
{"Lydian", 0x010920, 0x01093f, false, kNoBlock},
{"Kharoshthi", 0x010a00, 0x010a5f, false, kNoBlock},
{"Cuneiform", 0x012000, 0x0123ff, false, kNoBlock},
{"Cuneiform Numbers and Punctuation", 0x012400, 0x01247f, false, kNoBlock},
{"Byzantine Musical Symbols", 0x01d000, 0x01d0ff, false, kNoBlock},
{"Muscial Symbols", 0x01d100, 0x01d1ff, false, kNoBlock},
{"Ancient Greek Musical Notation", 0x01d200, 0x01d24f, false, kNoBlock},
{"Tai Xuan Jing Symbols", 0x01d300, 0x01d35f, false, kNoBlock},
{"Counting Rod Numerals", 0x01d360, 0x01d37f, false, kNoBlock},
{"Mathematical Alphanumeric Symbols", 0x01d400, 0x01d7ff, false, kNoBlock},
{"Mahjong Tiles", 0x01f000, 0x01f02f, false, kNoBlock},
{"Domino Tiles", 0x01f030, 0x01f09f, false, kNoBlock},
{"CJK Unified Ideographs Extension B", 0x020000, 0x02a6df, false, kNoBlock},
{"CJK Compatibility Ideographs Supplement", 0x02f800, 0x02fa1f, false,
kNoBlock},
{"Tags", 0x0e0000, 0x0e007f, false, kNoBlock},
{"Variation Selectors Supplement", 0x0e0100, 0x0e01ef, false, kNoBlock},
{"Supplementary Private Use Area A", 0x0f0000, 0x0fffff, true, kNoBlock},
{"Supplementary Private Use Area B", 0x100000, 0x10ffff, true, kNoBlock},
};
const uint32 kNumUnicodeBlocks
= sizeof(kUnicodeBlocks) / sizeof(kUnicodeBlocks[0]);
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef UNICODE_BLOCKS_H
#define UNICODE_BLOCKS_H
#include <UnicodeBlockObjects.h>
struct unicode_block_entry {
const char* name;
uint32 start;
uint32 end;
bool private_block;
const unicode_block& block;
uint32 Count() const { return end + 1 - start; }
};
extern const unicode_block kNoBlock;
extern const struct unicode_block_entry kUnicodeBlocks[];
extern const uint32 kNumUnicodeBlocks;
#endif // UNICODE_BLOCKS_H