From e62d9cf8c568e4fd2c80e163cbdae5a4376e898f Mon Sep 17 00:00:00 2001 From: Philippe Saint-Pierre Date: Tue, 30 Jun 2015 13:26:48 -0400 Subject: [PATCH] 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. --- src/apps/stylededit/ColorMenuItem.cpp | 25 +++- src/apps/stylededit/ColorMenuItem.h | 15 +-- src/apps/stylededit/Constants.h | 22 ++-- src/apps/stylededit/StyledEditView.cpp | 5 +- src/apps/stylededit/StyledEditView.h | 1 + src/apps/stylededit/StyledEditWindow.cpp | 148 +++++++++++++---------- src/apps/stylededit/StyledEditWindow.h | 12 +- 7 files changed, 136 insertions(+), 92 deletions(-) diff --git a/src/apps/stylededit/ColorMenuItem.cpp b/src/apps/stylededit/ColorMenuItem.cpp index 863a2afcd5..e5baa0e104 100644 --- a/src/apps/stylededit/ColorMenuItem.cpp +++ b/src/apps/stylededit/ColorMenuItem.cpp @@ -10,12 +10,16 @@ #include "ColorMenuItem.h" #include +#include -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(); } } diff --git a/src/apps/stylededit/ColorMenuItem.h b/src/apps/stylededit/ColorMenuItem.h index 45b4715cd6..79a9f7a65f 100644 --- a/src/apps/stylededit/ColorMenuItem.h +++ b/src/apps/stylededit/ColorMenuItem.h @@ -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 diff --git a/src/apps/stylededit/Constants.h b/src/apps/stylededit/Constants.h index 4b9af01153..f72ff04194 100644 --- a/src/apps/stylededit/Constants.h +++ b/src/apps/stylededit/Constants.h @@ -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'; diff --git a/src/apps/stylededit/StyledEditView.cpp b/src/apps/stylededit/StyledEditView.cpp index 883550d5a7..32d0ae4be4 100644 --- a/src/apps/stylededit/StyledEditView.cpp +++ b/src/apps/stylededit/StyledEditView.cpp @@ -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()); diff --git a/src/apps/stylededit/StyledEditView.h b/src/apps/stylededit/StyledEditView.h index a61cc77ba2..2f5ce41903 100644 --- a/src/apps/stylededit/StyledEditView.h +++ b/src/apps/stylededit/StyledEditView.h @@ -48,6 +48,7 @@ private: BMessenger* fMessenger; bool fSuppressChanges; BString fEncoding; + rgb_color fInitialColor; }; diff --git a/src/apps/stylededit/StyledEditWindow.cpp b/src/apps/stylededit/StyledEditWindow.cpp index 0932c90020..fdc0005bde 100644 --- a/src/apps/stylededit/StyledEditWindow.cpp +++ b/src/apps/stylededit/StyledEditWindow.cpp @@ -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 + (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() { diff --git a/src/apps/stylededit/StyledEditWindow.h b/src/apps/stylededit/StyledEditWindow.h index 95e88b6b44..a5547e6f9d 100644 --- a/src/apps/stylededit/StyledEditWindow.h +++ b/src/apps/stylededit/StyledEditWindow.h @@ -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