StyledEdit: Rework of the font color system

1) The default font color is now B_DOCUMENT_TEXT_COLOR
2) The font color menu now shows a palette
3) The font color menu now includes a "default" item, set
to B_DOCUMENT_TEXT_COLOR
4) Added a Todo mentionning it would be ideal to not save the default color
itself, but instead saving the fact the default color was used. Maybe allow the
StyleBuffer to use a Null color or something similar.
This commit is contained in:
Philippe Saint-Pierre 2015-06-30 13:26:48 -04:00
parent 8083e779cf
commit e62d9cf8c5
7 changed files with 136 additions and 92 deletions

View File

@ -10,12 +10,16 @@
#include "ColorMenuItem.h"
#include <Message.h>
#include <Rect.h>
ColorMenuItem::ColorMenuItem(const char *label, rgb_color color,
ColorMenuItem::ColorMenuItem(const char* label, rgb_color color,
BMessage *message)
: BMenuItem(label, message, 0, 0),
:
BMenuItem(label, message, 0, 0),
fItemColor(color)
{
message->AddData("color", B_RGB_COLOR_TYPE, &color, sizeof(rgb_color));
}
@ -25,9 +29,24 @@ ColorMenuItem::DrawContent()
BMenu* menu = Menu();
if (menu) {
rgb_color menuColor = menu->HighColor();
BRect colorSquare(Frame());
if (colorSquare.Width() > colorSquare.Height()) {
// large button
colorSquare.left += 8;
colorSquare.top += 2;
colorSquare.bottom -= 2;
}
colorSquare.right = colorSquare.left + colorSquare.Height();
if (IsMarked()) {
menu->SetHighColor(ui_color(B_NAVIGATION_BASE_COLOR));
menu->StrokeRect(colorSquare);
}
colorSquare.InsetBy(1, 1);
menu->SetHighColor(fItemColor);
BMenuItem::DrawContent();
menu->FillRect(colorSquare);
menu->SetHighColor(menuColor);
menu->MovePenBy(colorSquare.right + 5.0f, 4.0f);
BMenuItem::DrawContent();
}
}

View File

@ -17,15 +17,16 @@ class BMessage;
class ColorMenuItem: public BMenuItem {
public:
ColorMenuItem(const char* label, rgb_color color,
BMessage* message);
public:
ColorMenuItem(const char* label, rgb_color color,
BMessage* message);
rgb_color Color() { return fItemColor; };
protected:
virtual void DrawContent();
protected:
virtual void DrawContent();
private:
rgb_color fItemColor;
private:
rgb_color fItemColor;
};
#endif // COLOR_MENU_ITEM_H

View File

@ -53,14 +53,20 @@ const uint32 FONT_COLOR = 'Fcol';
const uint32 kMsgSetItalic = 'Fita';
const uint32 kMsgSetBold = 'Fbld';
// fontcolors
const rgb_color BLACK = {0, 0, 0, 255};
const rgb_color RED = {255, 0, 0, 255};
const rgb_color GREEN = {0, 255, 0, 255};
const rgb_color BLUE = {0, 0, 255, 255};
const rgb_color CYAN = {0, 255, 255, 255};
const rgb_color MAGENTA = {255, 0, 255, 255};
const rgb_color YELLOW = {255, 255, 0, 255};
const rgb_color palette[] = {
{ 220, 0, 0, 255 }, // red
{ 220, 73, 0, 255 }, // orange
{ 220, 220, 0, 255 }, // yellow
{ 59, 177, 0, 255 }, // green
{ 60, 22, 0, 255 }, // brown
{ 36, 71, 106, 255 }, // blue
{ 0, 123, 186, 255 }, // cyan
{ 0, 106, 115, 255 }, // teal
{ 53, 53, 53, 255 }, // charcoal
{ 137, 0, 72, 255 }, // magenta
{ 0, 0, 0, 255 }, //black
{ 255, 255, 255, 255 } // white
};
// "Document"-menu
const uint32 ALIGN_LEFT = 'ALle';

View File

@ -33,8 +33,9 @@ using namespace BPrivate;
StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds,
BHandler* handler)
:
BTextView(viewFrame, "textview", textBounds, B_FOLLOW_ALL,
B_FRAME_EVENTS | B_WILL_DRAW)
BTextView(viewFrame, "textview", textBounds, NULL,
&(fInitialColor = ui_color(B_DOCUMENT_TEXT_COLOR)),
B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW)
{
SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
SetLowColor(ViewColor());

View File

@ -48,6 +48,7 @@ private:
BMessenger* fMessenger;
bool fSuppressChanges;
BString fEncoding;
rgb_color fInitialColor;
};

View File

@ -82,8 +82,10 @@ bs_printf(BString* string, const char* format, ...)
StyledEditWindow::StyledEditWindow(BRect frame, int32 id, uint32 encoding)
: BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
fFindWindow(NULL), fReplaceWindow(NULL)
:
BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
fFindWindow(NULL),
fReplaceWindow(NULL)
{
_InitWindow(encoding);
BString unTitled(B_TRANSLATE("Untitled "));
@ -96,8 +98,10 @@ StyledEditWindow::StyledEditWindow(BRect frame, int32 id, uint32 encoding)
StyledEditWindow::StyledEditWindow(BRect frame, entry_ref* ref, uint32 encoding)
: BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
fFindWindow(NULL), fReplaceWindow(NULL)
:
BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
fFindWindow(NULL),
fReplaceWindow(NULL)
{
_InitWindow(encoding);
OpenFile(ref);
@ -424,22 +428,18 @@ StyledEditWindow::MessageReceived(BMessage* message)
}
case FONT_COLOR:
{
void* ptr;
if (message->FindPointer("source", &ptr) == B_OK) {
if (ptr == fBlackItem)
_SetFontColor(&BLACK);
else if (ptr == fRedItem)
_SetFontColor(&RED);
else if (ptr == fGreenItem)
_SetFontColor(&GREEN);
else if (ptr == fBlueItem)
_SetFontColor(&BLUE);
else if (ptr == fCyanItem)
_SetFontColor(&CYAN);
else if (ptr == fMagentaItem)
_SetFontColor(&MAGENTA);
else if (ptr == fYellowItem)
_SetFontColor(&YELLOW);
ssize_t colorLength;
rgb_color* color;
if (message->FindData("color", B_RGB_COLOR_TYPE,
(const void**)&color, &colorLength) == B_OK
&& colorLength == sizeof(rgb_color)) {
/*
* TODO: Ideally, when selecting the default color,
* you wouldn't naively apply it; it shouldn't lose its nature.
* When reloaded with a different default color, it should
* reflect that different choice.
*/
_SetFontColor(color);
}
break;
}
@ -648,37 +648,21 @@ StyledEditWindow::MenusBeginning()
// find the current font, color, size
BFont font;
uint32 sameProperties;
rgb_color color = BLACK;
rgb_color color = ui_color(B_DOCUMENT_TEXT_COLOR);
bool sameColor;
fTextView->GetFontAndColor(&font, &sameProperties, &color, &sameColor);
color.alpha = 255;
if (sameColor) {
// mark the menu according to the current color
if (color.red == 0) {
if (color.green == 0) {
if (color.blue == 0) {
fBlackItem->SetMarked(true);
} else if (color.blue == 255) {
fBlueItem->SetMarked(true);
}
} else if (color.green == 255) {
if (color.blue == 0) {
fGreenItem->SetMarked(true);
} else if (color.blue == 255) {
fCyanItem->SetMarked(true);
}
}
} else if (color.red == 255) {
if (color.green == 0) {
if (color.blue == 0) {
fRedItem->SetMarked(true);
} else if (color.blue == 255) {
fMagentaItem->SetMarked(true);
}
} else if (color.green == 255) {
if (color.blue == 0) {
fYellowItem->SetMarked(true);
if (fDefaultFontColorItem->Color() == color)
fDefaultFontColorItem->SetMarked(true);
else {
for (int i = 0; i < fFontColorMenu->CountItems(); i++) {
ColorMenuItem* item = dynamic_cast<ColorMenuItem*>
(fFontColorMenu->ItemAt(i));
if (item != NULL && item->Color() == color) {
item->SetMarked(true);
break;
}
}
}
@ -1237,27 +1221,12 @@ StyledEditWindow::_InitWindow(uint32 encoding)
}
// "Color"-subMenu
fFontColorMenu = new BMenu(B_TRANSLATE("Color"));
fFontColorMenu = new BMenu(B_TRANSLATE("Color"), 0, 0);
fFontColorMenu->SetRadioMode(true);
fFontMenu->AddItem(fFontColorMenu);
fFontColorMenu->AddItem(fBlackItem = new ColorMenuItem(B_TRANSLATE("Black"),
BLACK, new BMessage(FONT_COLOR)));
fBlackItem->SetMarked(true);
fFontColorMenu->AddItem(fRedItem = new ColorMenuItem(B_TRANSLATE("Red"),
RED, new BMessage(FONT_COLOR)));
fFontColorMenu->AddItem(fGreenItem = new ColorMenuItem(B_TRANSLATE("Green"),
GREEN, new BMessage(FONT_COLOR)));
fFontColorMenu->AddItem(fBlueItem = new ColorMenuItem(B_TRANSLATE("Blue"),
BLUE, new BMessage(FONT_COLOR)));
fFontColorMenu->AddItem(fCyanItem = new ColorMenuItem(B_TRANSLATE("Cyan"),
CYAN, new BMessage(FONT_COLOR)));
fFontColorMenu->AddItem(fMagentaItem
= new ColorMenuItem(B_TRANSLATE("Magenta"), MAGENTA,
new BMessage(FONT_COLOR)));
fFontColorMenu->AddItem(fYellowItem
= new ColorMenuItem(B_TRANSLATE("Yellow"), YELLOW,
new BMessage(FONT_COLOR)));
_BuildFontColorMenu(fFontColorMenu);
fFontMenu->AddSeparatorItem();
// "Bold" & "Italic" menu items
@ -1340,6 +1309,57 @@ StyledEditWindow::_InitWindow(uint32 encoding)
}
void
StyledEditWindow::_BuildFontColorMenu(BMenu* menu)
{
if (menu == NULL)
return;
BFont font;
menu->GetFont(&font);
font_height fh;
font.GetHeight(&fh);
const float itemHeight = ceilf(fh.ascent + fh.descent + 2 * fh.leading);
const float margin = 8.0;
const int nbColumns = 5;
BMessage msgTemplate(FONT_COLOR);
BRect matrixArea(0, 0, 0, 0);
// we place the color palette, reserving room at the top
for (uint i = 0; i < sizeof(palette) / sizeof(rgb_color); i++) {
BPoint topLeft((i % nbColumns) * (itemHeight + margin),
(i / nbColumns) * (itemHeight + margin));
BRect buttonArea(topLeft.x, topLeft.y, topLeft.x + itemHeight,
topLeft.y + itemHeight);
buttonArea.OffsetBy(margin, itemHeight + margin + margin);
menu->AddItem(
new ColorMenuItem("", palette[i], new BMessage(msgTemplate)),
buttonArea);
buttonArea.OffsetBy(margin, margin);
matrixArea = matrixArea | buttonArea;
}
// separator at the bottom to add spacing in the matrix menu
matrixArea.top = matrixArea.bottom;
menu->AddItem(new BSeparatorItem(), matrixArea);
matrixArea.top = 0;
matrixArea.bottom = itemHeight + 4;
BMessage* msg = new BMessage(msgTemplate);
msg->AddBool("default", true);
fDefaultFontColorItem = new ColorMenuItem(B_TRANSLATE("Default"),
ui_color(B_DOCUMENT_TEXT_COLOR), msg);
menu->AddItem(fDefaultFontColorItem, matrixArea);
matrixArea.top = matrixArea.bottom;
matrixArea.bottom = matrixArea.top + margin;
menu->AddItem(new BSeparatorItem(), matrixArea);
}
void
StyledEditWindow::_LoadAttrs()
{

View File

@ -25,6 +25,7 @@ class BMessage;
class BScrollView;
class StatusView;
class StyledEditView;
class ColorMenuItem;
class StyledEditWindow : public BWindow {
@ -51,6 +52,7 @@ public:
private:
void _InitWindow(uint32 encoding = 0);
void _BuildFontColorMenu(BMenu* menu);
void _LoadAttrs();
void _SaveAttrs();
status_t _LoadFile(entry_ref* ref,
@ -123,14 +125,6 @@ private:
BMenuItem* fReplaceItem;
BMenuItem* fReplaceSameItem;
BMenuItem* fBlackItem;
BMenuItem* fRedItem;
BMenuItem* fGreenItem;
BMenuItem* fBlueItem;
BMenuItem* fCyanItem;
BMenuItem* fMagentaItem;
BMenuItem* fYellowItem;
BMenuItem* fBoldItem;
BMenuItem* fItalicItem;
@ -144,6 +138,8 @@ private:
BString fStringToFind;
BString fReplaceString;
ColorMenuItem* fDefaultFontColorItem;
// undo modes
bool fUndoFlag; // we just did an undo action
bool fCanUndo; // we can do an undo action next