Terminal: graphical settings for configuring themes.
Implements #16835: Make colour schemes modular. Implements #15936: Terminal settings should allow to drop a colour. Change-Id: I1071c9285ba887e734af47b724f9de7f6c660581 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5950 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -46,34 +46,6 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
||||
BGroupView(name, B_VERTICAL, 5),
|
||||
fTerminalMessenger(messenger)
|
||||
{
|
||||
const char* kColorTable[] = {
|
||||
B_TRANSLATE_MARK("Text"),
|
||||
B_TRANSLATE_MARK("Background"),
|
||||
B_TRANSLATE_MARK("Cursor"),
|
||||
B_TRANSLATE_MARK("Text under cursor"),
|
||||
B_TRANSLATE_MARK("Selected text"),
|
||||
B_TRANSLATE_MARK("Selected background"),
|
||||
"",
|
||||
B_TRANSLATE_MARK("ANSI black color"),
|
||||
B_TRANSLATE_MARK("ANSI red color"),
|
||||
B_TRANSLATE_MARK("ANSI green color"),
|
||||
B_TRANSLATE_MARK("ANSI yellow color"),
|
||||
B_TRANSLATE_MARK("ANSI blue color"),
|
||||
B_TRANSLATE_MARK("ANSI magenta color"),
|
||||
B_TRANSLATE_MARK("ANSI cyan color"),
|
||||
B_TRANSLATE_MARK("ANSI white color"),
|
||||
"",
|
||||
B_TRANSLATE_MARK("ANSI bright black color"),
|
||||
B_TRANSLATE_MARK("ANSI bright red color"),
|
||||
B_TRANSLATE_MARK("ANSI bright green color"),
|
||||
B_TRANSLATE_MARK("ANSI bright yellow color"),
|
||||
B_TRANSLATE_MARK("ANSI bright blue color"),
|
||||
B_TRANSLATE_MARK("ANSI bright magenta color"),
|
||||
B_TRANSLATE_MARK("ANSI bright cyan color"),
|
||||
B_TRANSLATE_MARK("ANSI bright white color"),
|
||||
NULL
|
||||
};
|
||||
|
||||
fBlinkCursor = new BCheckBox(
|
||||
B_TRANSLATE("Blinking cursor"),
|
||||
new BMessage(MSG_BLINK_CURSOR_CHANGED));
|
||||
@@ -110,16 +82,6 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
||||
}
|
||||
fEncodingField = new BMenuField(B_TRANSLATE("Encoding:"), encodingMenu);
|
||||
|
||||
BPopUpMenu* schemesPopUp = _MakeColorSchemeMenu(MSG_COLOR_SCHEME_CHANGED,
|
||||
gColorSchemes);
|
||||
fColorSchemeField = new BMenuField(B_TRANSLATE("Color scheme:"),
|
||||
schemesPopUp);
|
||||
|
||||
BPopUpMenu* colorsPopUp = _MakeMenu(MSG_COLOR_FIELD_CHANGED, kColorTable,
|
||||
kColorTable[0]);
|
||||
|
||||
fColorField = new BMenuField(B_TRANSLATE("Color:"), colorsPopUp);
|
||||
|
||||
fTabTitle = new BTextControl("tabTitle", B_TRANSLATE("Tab title:"), "",
|
||||
NULL);
|
||||
fTabTitle->SetModificationMessage(
|
||||
@@ -151,14 +113,8 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
||||
.Add(fFontField->CreateMenuBarLayoutItem(), 1, 3)
|
||||
.Add(fEncodingField->CreateLabelLayoutItem(), 0, 4)
|
||||
.Add(fEncodingField->CreateMenuBarLayoutItem(), 1, 4)
|
||||
.Add(fColorSchemeField->CreateLabelLayoutItem(), 0, 5)
|
||||
.Add(fColorSchemeField->CreateMenuBarLayoutItem(), 1, 5)
|
||||
.Add(fColorField->CreateLabelLayoutItem(), 0, 6)
|
||||
.Add(fColorField->CreateMenuBarLayoutItem(), 1, 6)
|
||||
.End()
|
||||
.AddGlue()
|
||||
.Add(fColorControl = new BColorControl(BPoint(10, 10),
|
||||
B_CELLS_32x8, 8.0, "", new BMessage(MSG_COLOR_CHANGED)))
|
||||
.Add(fBlinkCursor)
|
||||
.Add(fAllowBold)
|
||||
.Add(fUseOptionAsMetaKey)
|
||||
@@ -169,18 +125,8 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
||||
fFontField->SetAlignment(B_ALIGN_RIGHT);
|
||||
fWindowSizeField->SetAlignment(B_ALIGN_RIGHT);
|
||||
fEncodingField->SetAlignment(B_ALIGN_RIGHT);
|
||||
fColorField->SetAlignment(B_ALIGN_RIGHT);
|
||||
fColorSchemeField->SetAlignment(B_ALIGN_RIGHT);
|
||||
|
||||
Revert();
|
||||
|
||||
BTextControl* redInput = (BTextControl*)fColorControl->ChildAt(0);
|
||||
BTextControl* greenInput = (BTextControl*)fColorControl->ChildAt(1);
|
||||
BTextControl* blueInput = (BTextControl*)fColorControl->ChildAt(2);
|
||||
|
||||
redInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
greenInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
blueInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,10 +143,8 @@ AppearancePrefView::Revert()
|
||||
fUseOptionAsMetaKey->SetValue(pref->getBool(PREF_USE_OPTION_AS_META));
|
||||
fWarnOnExit->SetValue(pref->getBool(PREF_WARN_ON_EXIT));
|
||||
|
||||
_SetCurrentColorScheme();
|
||||
_SetEncoding(pref->getString(PREF_TEXT_ENCODING));
|
||||
_SetWindowSize(pref->getInt32(PREF_ROWS), pref->getInt32(PREF_COLS));
|
||||
fColorControl->SetValue(pref->getRGB(PREF_TEXT_FORE_COLOR));
|
||||
|
||||
const char* family = pref->getString(PREF_HALF_FONT_FAMILY);
|
||||
const char* style = pref->getString(PREF_HALF_FONT_STYLE);
|
||||
@@ -229,13 +173,8 @@ AppearancePrefView::AttachedToWindow()
|
||||
fontSizeMenu->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
fColorControl->SetTarget(this);
|
||||
fColorField->Menu()->SetTargetForItems(this);
|
||||
fColorSchemeField->Menu()->SetTargetForItems(this);
|
||||
fWindowSizeField->Menu()->SetTargetForItems(this);
|
||||
fEncodingField->Menu()->SetTargetForItems(this);
|
||||
|
||||
_SetCurrentColorScheme();
|
||||
}
|
||||
|
||||
|
||||
@@ -277,55 +216,6 @@ AppearancePrefView::MessageReceived(BMessage* msg)
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_COLOR_CHANGED:
|
||||
{
|
||||
const BMessage* itemMessage
|
||||
= fColorField->Menu()->FindMarked()->Message();
|
||||
const char* label = NULL;
|
||||
if (itemMessage->FindString("label", &label) != B_OK)
|
||||
break;
|
||||
rgb_color oldColor = PrefHandler::Default()->getRGB(label);
|
||||
if (oldColor != fColorControl->ValueAsColor()) {
|
||||
BMenuItem* item = fColorSchemeField->Menu()->FindMarked();
|
||||
if (strcmp(item->Label(), gCustomColorScheme.name) != 0) {
|
||||
item->SetMarked(false);
|
||||
item = fColorSchemeField->Menu()->FindItem(
|
||||
gCustomColorScheme.name);
|
||||
if (item)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
PrefHandler::Default()->setRGB(label,
|
||||
fColorControl->ValueAsColor());
|
||||
modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_COLOR_SCHEME_CHANGED:
|
||||
{
|
||||
color_scheme* newScheme = NULL;
|
||||
if (msg->FindPointer("color_scheme",
|
||||
(void**)&newScheme) == B_OK) {
|
||||
_ChangeColorScheme(newScheme);
|
||||
const char* label = NULL;
|
||||
if (fColorField->Menu()->FindMarked()->Message()->FindString(
|
||||
"label", &label) == B_OK)
|
||||
fColorControl->SetValue(
|
||||
PrefHandler::Default()->getRGB(label));
|
||||
modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_COLOR_FIELD_CHANGED:
|
||||
{
|
||||
const char* label = NULL;
|
||||
if (msg->FindString("label", &label) == B_OK)
|
||||
fColorControl->SetValue(PrefHandler::Default()->getRGB(label));
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_COLS_CHANGED:
|
||||
{
|
||||
int rows = msg->FindInt32("rows");
|
||||
@@ -417,70 +307,6 @@ AppearancePrefView::MessageReceived(BMessage* msg)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppearancePrefView::_ChangeColorScheme(color_scheme* scheme)
|
||||
{
|
||||
PrefHandler* pref = PrefHandler::Default();
|
||||
|
||||
pref->setRGB(PREF_TEXT_FORE_COLOR, scheme->text_fore_color);
|
||||
pref->setRGB(PREF_TEXT_BACK_COLOR, scheme->text_back_color);
|
||||
pref->setRGB(PREF_SELECT_FORE_COLOR, scheme->select_fore_color);
|
||||
pref->setRGB(PREF_SELECT_BACK_COLOR, scheme->select_back_color);
|
||||
pref->setRGB(PREF_CURSOR_FORE_COLOR, scheme->cursor_fore_color);
|
||||
pref->setRGB(PREF_CURSOR_BACK_COLOR, scheme->cursor_back_color);
|
||||
pref->setRGB(PREF_ANSI_BLACK_COLOR, scheme->ansi_colors.black);
|
||||
pref->setRGB(PREF_ANSI_RED_COLOR, scheme->ansi_colors.red);
|
||||
pref->setRGB(PREF_ANSI_GREEN_COLOR, scheme->ansi_colors.green);
|
||||
pref->setRGB(PREF_ANSI_YELLOW_COLOR, scheme->ansi_colors.yellow);
|
||||
pref->setRGB(PREF_ANSI_BLUE_COLOR, scheme->ansi_colors.blue);
|
||||
pref->setRGB(PREF_ANSI_MAGENTA_COLOR, scheme->ansi_colors.magenta);
|
||||
pref->setRGB(PREF_ANSI_CYAN_COLOR, scheme->ansi_colors.cyan);
|
||||
pref->setRGB(PREF_ANSI_WHITE_COLOR, scheme->ansi_colors.white);
|
||||
pref->setRGB(PREF_ANSI_BLACK_HCOLOR, scheme->ansi_colors_h.black);
|
||||
pref->setRGB(PREF_ANSI_RED_HCOLOR, scheme->ansi_colors_h.red);
|
||||
pref->setRGB(PREF_ANSI_GREEN_HCOLOR, scheme->ansi_colors_h.green);
|
||||
pref->setRGB(PREF_ANSI_YELLOW_HCOLOR, scheme->ansi_colors_h.yellow);
|
||||
pref->setRGB(PREF_ANSI_BLUE_HCOLOR, scheme->ansi_colors_h.blue);
|
||||
pref->setRGB(PREF_ANSI_MAGENTA_HCOLOR, scheme->ansi_colors_h.magenta);
|
||||
pref->setRGB(PREF_ANSI_CYAN_HCOLOR, scheme->ansi_colors_h.cyan);
|
||||
pref->setRGB(PREF_ANSI_WHITE_HCOLOR, scheme->ansi_colors_h.white);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppearancePrefView::_SetCurrentColorScheme()
|
||||
{
|
||||
PrefHandler* pref = PrefHandler::Default();
|
||||
|
||||
pref->LoadColorScheme(&gCustomColorScheme);
|
||||
|
||||
const char* currentSchemeName = NULL;
|
||||
|
||||
int32 i = 0;
|
||||
while (i < gColorSchemes->CountItems()) {
|
||||
const color_scheme *item = gColorSchemes->ItemAt(i);
|
||||
i++;
|
||||
|
||||
if (gCustomColorScheme == *item) {
|
||||
currentSchemeName = item->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the scheme is not one of the known ones, assume a custom one.
|
||||
if (currentSchemeName == NULL)
|
||||
currentSchemeName = "Custom";
|
||||
|
||||
for (int32 i = 0; i < fColorSchemeField->Menu()->CountItems(); i++) {
|
||||
BMenuItem* item = fColorSchemeField->Menu()->ItemAt(i);
|
||||
if (strcmp(item->Label(), currentSchemeName) == 0) {
|
||||
item->SetMarked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppearancePrefView::_SetEncoding(const char* name)
|
||||
{
|
||||
@@ -633,51 +459,6 @@ AppearancePrefView::_MakeMenu(uint32 msg, const char** items,
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
AppearancePrefView::_MakeColorSchemeMenuItem(uint32 msg, const color_scheme *item,
|
||||
BPopUpMenu *menu)
|
||||
{
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
BMessage* message = new BMessage(msg);
|
||||
message->AddPointer("color_scheme", (const void*)item);
|
||||
menu->AddItem(new BMenuItem(item->name, message));
|
||||
}
|
||||
|
||||
|
||||
/*static*/ BPopUpMenu*
|
||||
AppearancePrefView::_MakeColorSchemeMenu(uint32 msg, BObjectList<const color_scheme> *items)
|
||||
{
|
||||
BPopUpMenu* menu = new BPopUpMenu("");
|
||||
|
||||
FindColorSchemeByName comparator("Default");
|
||||
|
||||
const color_scheme* defaultItem = items->FindIf(comparator);
|
||||
|
||||
_MakeColorSchemeMenuItem(msg, defaultItem, menu);
|
||||
|
||||
int32 i = 0;
|
||||
while (i < items->CountItems()) {
|
||||
const color_scheme *item = items->ItemAt(i);
|
||||
i++;
|
||||
|
||||
if (strcmp(item->name, "") == 0)
|
||||
menu->AddSeparatorItem();
|
||||
else if (item == defaultItem)
|
||||
continue;
|
||||
else
|
||||
_MakeColorSchemeMenuItem(msg, item, menu);
|
||||
}
|
||||
|
||||
// Add the custom item at the very end
|
||||
menu->AddSeparatorItem();
|
||||
_MakeColorSchemeMenuItem(msg, &gCustomColorScheme, menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppearancePrefView::_MarkSelectedFont(const char* family, const char* style,
|
||||
const char* size)
|
||||
|
||||
@@ -18,9 +18,7 @@ static const uint32 MSG_HALF_FONT_CHANGED = 'mchf';
|
||||
static const uint32 MSG_HALF_SIZE_CHANGED = 'mchs';
|
||||
static const uint32 MSG_FULL_FONT_CHANGED = 'mcff';
|
||||
static const uint32 MSG_FULL_SIZE_CHANGED = 'mcfs';
|
||||
static const uint32 MSG_COLOR_FIELD_CHANGED = 'mccf';
|
||||
static const uint32 MSG_COLOR_CHANGED = 'mcbc';
|
||||
static const uint32 MSG_COLOR_SCHEME_CHANGED = 'mccs';
|
||||
|
||||
static const uint32 MSG_TAB_TITLE_SETTING_CHANGED = 'mtts';
|
||||
static const uint32 MSG_WINDOW_TITLE_SETTING_CHANGED = 'mwts';
|
||||
@@ -54,8 +52,6 @@ public:
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
private:
|
||||
void _ChangeColorScheme(color_scheme* scheme);
|
||||
void _SetCurrentColorScheme();
|
||||
void _SetEncoding(const char* encoding);
|
||||
void _SetWindowSize(int rows, int cols);
|
||||
|
||||
@@ -71,12 +67,6 @@ private:
|
||||
static BPopUpMenu* _MakeMenu(uint32 msg, const char** items,
|
||||
const char* defaultItem);
|
||||
|
||||
static BPopUpMenu* _MakeColorSchemeMenu(uint32 msg,
|
||||
BObjectList<const color_scheme> *items);
|
||||
static void _MakeColorSchemeMenuItem(uint32 msg,
|
||||
const color_scheme *item,
|
||||
BPopUpMenu* menu);
|
||||
|
||||
void _MarkSelectedFont(const char* family,
|
||||
const char* style, const char* size);
|
||||
|
||||
@@ -89,10 +79,6 @@ private:
|
||||
BMenuField* fWindowSizeField;
|
||||
BMenuField* fEncodingField;
|
||||
|
||||
BMenuField* fColorSchemeField;
|
||||
BMenuField* fColorField;
|
||||
BColorControl* fColorControl;
|
||||
|
||||
BTextControl* fTabTitle;
|
||||
BTextControl* fWindowTitle;
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2016-2022 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include "ColorListView.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "ColorItem.h"
|
||||
#include "ThemeView.h"
|
||||
|
||||
|
||||
// golden ratio
|
||||
#ifdef M_PHI
|
||||
# undef M_PHI
|
||||
#endif
|
||||
#define M_PHI 1.61803398874989484820
|
||||
|
||||
|
||||
// #pragma mark - ColorListView
|
||||
|
||||
|
||||
ColorListView::ColorListView(const char* name,
|
||||
list_view_type type, uint32 flags)
|
||||
:
|
||||
BListView(name, type, flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ColorListView::~ColorListView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ColorListView::InitiateDrag(BPoint where, int32 index, bool wasSelected)
|
||||
{
|
||||
ColorItem* colorItem
|
||||
= dynamic_cast<ColorItem*>(ItemAt(index));
|
||||
if (colorItem == NULL)
|
||||
return false;
|
||||
|
||||
rgb_color color = colorItem->Color();
|
||||
|
||||
BString hexStr;
|
||||
hexStr.SetToFormat("#%.2X%.2X%.2X", color.red, color.green, color.blue);
|
||||
|
||||
BMessage message(B_PASTE);
|
||||
message.AddData("text/plain", B_MIME_TYPE, hexStr.String(),
|
||||
hexStr.Length());
|
||||
message.AddData(kRGBColor, B_RGB_COLOR_TYPE, &color, sizeof(color));
|
||||
|
||||
float itemHeight = colorItem->Height() - 5;
|
||||
BRect rect(0.0f, 0.0f, roundf(itemHeight * M_PHI) - 1, itemHeight - 1);
|
||||
|
||||
BBitmap* bitmap = new BBitmap(rect, B_RGB32, true);
|
||||
if (bitmap->Lock()) {
|
||||
BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
bitmap->AddChild(view);
|
||||
|
||||
view->SetHighColor(B_TRANSPARENT_COLOR);
|
||||
view->FillRect(view->Bounds());
|
||||
|
||||
++rect.top;
|
||||
++rect.left;
|
||||
|
||||
view->SetHighColor(0, 0, 0, 100);
|
||||
view->FillRect(rect);
|
||||
rect.OffsetBy(-1.0f, -1.0f);
|
||||
|
||||
view->SetHighColor(std::min(255, (int)(1.2 * color.red + 40)),
|
||||
std::min(255, (int)(1.2 * color.green + 40)),
|
||||
std::min(255, (int)(1.2 * color.blue + 40)));
|
||||
view->StrokeRect(rect);
|
||||
|
||||
++rect.left;
|
||||
++rect.top;
|
||||
|
||||
view->SetHighColor((int32)(0.8 * color.red),
|
||||
(int32)(0.8 * color.green),
|
||||
(int32)(0.8 * color.blue));
|
||||
view->StrokeRect(rect);
|
||||
|
||||
--rect.right;
|
||||
--rect.bottom;
|
||||
|
||||
view->SetHighColor(color.red, color.green, color.blue);
|
||||
view->FillRect(rect);
|
||||
view->Sync();
|
||||
|
||||
bitmap->Unlock();
|
||||
}
|
||||
|
||||
DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(14.0f, 14.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
// if we received a dropped message, see if it contains color data
|
||||
if (message->WasDropped()) {
|
||||
BPoint dropPoint = message->DropPoint();
|
||||
ConvertFromScreen(&dropPoint);
|
||||
int32 index = IndexOf(dropPoint);
|
||||
ColorItem* item = dynamic_cast<ColorItem*>(ItemAt(index));
|
||||
rgb_color* color;
|
||||
ssize_t size;
|
||||
if (item != NULL && message->FindData(kRGBColor, B_RGB_COLOR_TYPE,
|
||||
(const void**)&color, &size) == B_OK) {
|
||||
// build message to send to ThemeView
|
||||
uint32 command = index == CurrentSelection()
|
||||
? MSG_SET_CURRENT_COLOR : MSG_SET_COLOR;
|
||||
BMessage setColorMessage = BMessage(command);
|
||||
setColorMessage.AddData(kRGBColor, B_RGB_COLOR_TYPE, color, size);
|
||||
// if setting different color, add which color to set
|
||||
if (command == MSG_SET_COLOR)
|
||||
setColorMessage.AddString(kName, item->Text());
|
||||
|
||||
// build messenger and send message
|
||||
BMessenger messenger = BMessenger(Parent());
|
||||
if (messenger.IsValid()) {
|
||||
messenger.SendMessage(&setColorMessage);
|
||||
if (command == MSG_SET_COLOR) {
|
||||
// redraw item, MSG_SET_CURRENT_COLOR does this for us
|
||||
item->SetColor(*color);
|
||||
InvalidateItem(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BListView::MessageReceived(message);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016-2022 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#ifndef COLORWHICH_LIST_VIEW_H
|
||||
#define COLORWHICH_LIST_VIEW_H
|
||||
|
||||
|
||||
#include <ListView.h>
|
||||
|
||||
|
||||
class ColorListView : public BListView
|
||||
{
|
||||
public:
|
||||
ColorListView(const char* name,
|
||||
list_view_type type
|
||||
= B_SINGLE_SELECTION_LIST,
|
||||
uint32 flags = B_WILL_DRAW
|
||||
| B_FRAME_EVENTS | B_NAVIGABLE);
|
||||
virtual ~ColorListView();
|
||||
|
||||
virtual bool InitiateDrag(BPoint where, int32 index,
|
||||
bool wasSelected);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
};
|
||||
|
||||
|
||||
#endif // COLORWHICH_LIST_VIEW_H
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2002-2022 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* DarkWyrm, darkwyrm@earthlink.net
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include "ColorPreview.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Message.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <String.h>
|
||||
#include <View.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "ThemeView.h"
|
||||
#include "TermConst.h"
|
||||
|
||||
|
||||
static const int32 kMsgMessageRunner = 'MsgR';
|
||||
|
||||
|
||||
// #pragma mark - ColorPreview
|
||||
|
||||
|
||||
ColorPreview::ColorPreview(BMessage* message, uint32 flags)
|
||||
:
|
||||
BControl("ColorPreview", "", message, flags | B_WILL_DRAW),
|
||||
fColor(ui_color(B_PANEL_BACKGROUND_COLOR)),
|
||||
fDisabledColor((rgb_color){ 128, 128, 128 }),
|
||||
fMessageRunner(NULL),
|
||||
fIsRectangle(true)
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
SetLowColor(0, 0, 0);
|
||||
SetExplicitSize(BSize(StringWidth("M") * 8, StringWidth("M") * 7));
|
||||
}
|
||||
|
||||
|
||||
ColorPreview::~ColorPreview(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::Draw(BRect updateRect)
|
||||
{
|
||||
rgb_color color;
|
||||
if (IsEnabled())
|
||||
color = fColor;
|
||||
else
|
||||
color = fDisabledColor;
|
||||
|
||||
if (fIsRectangle) {
|
||||
if (IsEnabled()) {
|
||||
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
|
||||
rgb_color darkShadow = tint_color(background, B_DARKEN_3_TINT);
|
||||
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
|
||||
|
||||
BRect bounds(Bounds());
|
||||
|
||||
BeginLineArray(4);
|
||||
AddLine(BPoint(bounds.left, bounds.bottom),
|
||||
BPoint(bounds.left, bounds.top), shadow);
|
||||
AddLine(BPoint(bounds.left + 1.0, bounds.top),
|
||||
BPoint(bounds.right, bounds.top), shadow);
|
||||
AddLine(BPoint(bounds.right, bounds.top + 1.0),
|
||||
BPoint(bounds.right, bounds.bottom), light);
|
||||
AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
|
||||
BPoint(bounds.left + 1.0, bounds.bottom), light);
|
||||
EndLineArray();
|
||||
bounds.InsetBy(1.0, 1.0);
|
||||
|
||||
BeginLineArray(4);
|
||||
AddLine(BPoint(bounds.left, bounds.bottom),
|
||||
BPoint(bounds.left, bounds.top), darkShadow);
|
||||
AddLine(BPoint(bounds.left + 1.0, bounds.top),
|
||||
BPoint(bounds.right, bounds.top), darkShadow);
|
||||
AddLine(BPoint(bounds.right, bounds.top + 1.0),
|
||||
BPoint(bounds.right, bounds.bottom), background);
|
||||
AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
|
||||
BPoint(bounds.left + 1.0, bounds.bottom), background);
|
||||
EndLineArray();
|
||||
bounds.InsetBy(1.0, 1.0);
|
||||
|
||||
SetHighColor(color);
|
||||
FillRect(bounds);
|
||||
} else {
|
||||
SetHighColor(color);
|
||||
FillRect(Bounds());
|
||||
}
|
||||
} else {
|
||||
// fill background
|
||||
SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
FillRect(updateRect);
|
||||
|
||||
SetHighColor(color);
|
||||
FillEllipse(Bounds());
|
||||
|
||||
if (IsEnabled())
|
||||
StrokeEllipse(Bounds(), B_SOLID_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::MessageReceived(BMessage* message)
|
||||
{
|
||||
// If we received a dropped message, see if it contains color data
|
||||
if (message->WasDropped()) {
|
||||
rgb_color* color;
|
||||
ssize_t size;
|
||||
if (message->FindData(kRGBColor, B_RGB_COLOR_TYPE,
|
||||
(const void**)&color, &size) == B_OK) {
|
||||
BMessage setColorMessage(MSG_SET_CURRENT_COLOR);
|
||||
setColorMessage.AddData(kRGBColor, B_RGB_COLOR_TYPE, color,
|
||||
sizeof(rgb_color));
|
||||
Invoke(&setColorMessage);
|
||||
}
|
||||
} else if ((int32)message->what == kMsgMessageRunner) {
|
||||
BPoint where;
|
||||
uint32 buttons;
|
||||
GetMouse(&where, &buttons);
|
||||
|
||||
_DragColor(where);
|
||||
}
|
||||
|
||||
BControl::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::MouseDown(BPoint where)
|
||||
{
|
||||
BWindow* window = Window();
|
||||
if (window != NULL)
|
||||
window->Activate();
|
||||
|
||||
fMessageRunner = new BMessageRunner(this, new BMessage(kMsgMessageRunner),
|
||||
300000, 1);
|
||||
|
||||
SetMouseEventMask(B_POINTER_EVENTS,
|
||||
B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
|
||||
|
||||
BRect rect = Bounds().InsetByCopy(2.0f, 2.0f);
|
||||
rect.top = roundf(rect.bottom / 2.0f + 1);
|
||||
|
||||
if (rect.Contains(where)) {
|
||||
Invalidate();
|
||||
Invoke();
|
||||
}
|
||||
|
||||
BControl::MouseDown(where);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
|
||||
{
|
||||
if (fMessageRunner != NULL)
|
||||
_DragColor(where);
|
||||
|
||||
BControl::MouseMoved(where, transit, message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::MouseUp(BPoint where)
|
||||
{
|
||||
delete fMessageRunner;
|
||||
fMessageRunner = NULL;
|
||||
|
||||
BControl::MouseUp(where);
|
||||
}
|
||||
|
||||
|
||||
rgb_color
|
||||
ColorPreview::Color(void) const
|
||||
{
|
||||
return fColor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::SetColor(rgb_color color)
|
||||
{
|
||||
color.alpha = 255;
|
||||
|
||||
SetHighColor(color);
|
||||
fColor = color;
|
||||
|
||||
Invalidate();
|
||||
Invoke();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::SetColor(uint8 red, uint8 green, uint8 blue)
|
||||
{
|
||||
SetHighColor(red, green, blue);
|
||||
fColor.red = red;
|
||||
fColor.green = green;
|
||||
fColor.blue = blue;
|
||||
fColor.alpha = 255;
|
||||
|
||||
Invalidate();
|
||||
Invoke();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::SetMode(bool rectangle)
|
||||
{
|
||||
fIsRectangle = rectangle;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ColorPreview private methods
|
||||
|
||||
|
||||
void
|
||||
ColorPreview::_DragColor(BPoint where)
|
||||
{
|
||||
BString hexStr;
|
||||
hexStr.SetToFormat("#%.2X%.2X%.2X", fColor.red, fColor.green, fColor.blue);
|
||||
|
||||
BMessage message(B_PASTE);
|
||||
message.AddData("text/plain", B_MIME_TYPE, hexStr.String(),
|
||||
hexStr.Length());
|
||||
message.AddData(kRGBColor, B_RGB_COLOR_TYPE, &fColor, sizeof(fColor));
|
||||
|
||||
BRect rect(0.0f, 0.0f, 20.0f, 20.0f);
|
||||
|
||||
BBitmap* bitmap = new BBitmap(rect, B_RGB32, true);
|
||||
if (bitmap->Lock()) {
|
||||
BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
bitmap->AddChild(view);
|
||||
|
||||
view->SetHighColor(B_TRANSPARENT_COLOR);
|
||||
view->FillRect(view->Bounds());
|
||||
|
||||
++rect.top;
|
||||
++rect.left;
|
||||
|
||||
view->SetHighColor(0, 0, 0, 100);
|
||||
view->FillRect(rect);
|
||||
rect.OffsetBy(-1.0f, -1.0f);
|
||||
|
||||
view->SetHighColor(std::min(255, (int)(1.2 * fColor.red + 40)),
|
||||
std::min(255, (int)(1.2 * fColor.green + 40)),
|
||||
std::min(255, (int)(1.2 * fColor.blue + 40)));
|
||||
view->StrokeRect(rect);
|
||||
|
||||
++rect.left;
|
||||
++rect.top;
|
||||
|
||||
view->SetHighColor((int32)(0.8 * fColor.red),
|
||||
(int32)(0.8 * fColor.green),
|
||||
(int32)(0.8 * fColor.blue));
|
||||
view->StrokeRect(rect);
|
||||
|
||||
--rect.right;
|
||||
--rect.bottom;
|
||||
|
||||
view->SetHighColor(fColor.red, fColor.green, fColor.blue);
|
||||
view->FillRect(rect);
|
||||
view->Sync();
|
||||
|
||||
bitmap->Unlock();
|
||||
}
|
||||
|
||||
DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(14.0f, 14.0f));
|
||||
|
||||
MouseUp(where);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2022 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* DarkWyrm, darkwyrm@earthlink.net
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*/
|
||||
#ifndef COLOR_PREVIEW_H_
|
||||
#define COLOR_PREVIEW_H_
|
||||
|
||||
|
||||
#include <Control.h>
|
||||
|
||||
|
||||
class BMessage;
|
||||
class BMessageRunner;
|
||||
|
||||
|
||||
class ColorPreview : public BControl
|
||||
{
|
||||
public:
|
||||
ColorPreview(BMessage* message,
|
||||
uint32 flags = B_WILL_DRAW);
|
||||
~ColorPreview(void);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* message);
|
||||
virtual void MouseUp(BPoint where);
|
||||
|
||||
rgb_color Color(void) const;
|
||||
void SetColor(rgb_color color);
|
||||
void SetColor(uint8 r, uint8 g, uint8 b);
|
||||
|
||||
void SetMode(bool rectangle);
|
||||
|
||||
private:
|
||||
void _DragColor(BPoint where);
|
||||
|
||||
rgb_color fColor;
|
||||
rgb_color fDisabledColor;
|
||||
|
||||
BMessageRunner* fMessageRunner;
|
||||
|
||||
bool fIsRectangle;
|
||||
};
|
||||
|
||||
#endif // COLOR_PREVIEW_H_
|
||||
@@ -11,6 +11,8 @@ Application Terminal :
|
||||
Arguments.cpp
|
||||
BasicTerminalBuffer.cpp
|
||||
Colors.cpp
|
||||
ColorListView.cpp
|
||||
ColorPreview.cpp
|
||||
FindWindow.cpp
|
||||
Globals.cpp
|
||||
HistoryBuffer.cpp
|
||||
@@ -35,6 +37,8 @@ Application Terminal :
|
||||
TermViewHighlight.cpp
|
||||
TermViewStates.cpp
|
||||
TermWindow.cpp
|
||||
ThemeView.cpp
|
||||
ThemeWindow.cpp
|
||||
TitlePlaceholderMapper.cpp
|
||||
VTKeyTbl.c
|
||||
VTPrsTbl.c
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
#include <Window.h>
|
||||
|
||||
// local messages
|
||||
const ulong MSG_DEFAULTS_PRESSED = 'defl';
|
||||
const ulong MSG_SAVEAS_PRESSED = 'canl';
|
||||
const ulong MSG_REVERT_PRESSED = 'revt';
|
||||
const ulong MSG_PREF_CLOSED = 'mspc';
|
||||
const uint32 MSG_DEFAULTS_PRESSED = 'defl';
|
||||
const uint32 MSG_SAVEAS_PRESSED = 'canl';
|
||||
const uint32 MSG_REVERT_PRESSED = 'revt';
|
||||
const uint32 MSG_PREF_CLOSED = 'mspc';
|
||||
|
||||
class BButton;
|
||||
class BFilePanel;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// Application signature (Must same in Terminal.rdef)
|
||||
#define TERM_SIGNATURE "application/x-vnd.Haiku-Terminal"
|
||||
#define PREFFILE_MIMETYPE "text/x-terminal-pref"
|
||||
#define THEMEFILE_MIMETYPE "text/x-terminal-theme"
|
||||
|
||||
// Signature of R5's Terminal. Needed for proper drop-in window count support
|
||||
#define R5_TERM_SIGNATURE "application/x-vnd.Be-SHEL"
|
||||
@@ -52,6 +53,7 @@ static const uint32 MENU_FIND_STRING = 'Mfpr';
|
||||
static const uint32 MENU_FIND_NEXT = 'Mfnx';
|
||||
static const uint32 MENU_FIND_PREVIOUS = 'Mfbw';
|
||||
static const uint32 MENU_SHOW_COLOR = 'Mcol';
|
||||
static const uint32 MENU_THEME_OPEN = 'Mthm';
|
||||
|
||||
static const uint32 M_GET_DEVICE_NUM = 'Mgdn';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2015, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2007-2022, Haiku, Inc. All rights reserved.
|
||||
* Copyright (c) 2004 Daniel Furrer <assimil8or@users.sourceforge.net>
|
||||
* Copyright (c) 2003-2004 Kian Duffy <myob@users.sourceforge.net>
|
||||
* Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
|
||||
@@ -67,6 +67,8 @@
|
||||
#include "ShellParameters.h"
|
||||
#include "TermConst.h"
|
||||
#include "TermScrollView.h"
|
||||
#include "ThemeWindow.h"
|
||||
#include "ThemeView.h"
|
||||
#include "TitlePlaceholderMapper.h"
|
||||
|
||||
|
||||
@@ -541,6 +543,7 @@ TermWindow::_SetupMenu()
|
||||
.AddSeparator()
|
||||
.AddItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS), MENU_PREF_OPEN,
|
||||
',')
|
||||
.AddItem(B_TRANSLATE("Theme settings" B_UTF8_ELLIPSIS), MENU_THEME_OPEN)
|
||||
.End();
|
||||
|
||||
AddChild(fMenuBar);
|
||||
@@ -768,6 +771,17 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
fPrefWindow = NULL;
|
||||
break;
|
||||
|
||||
case MENU_THEME_OPEN:
|
||||
if (!fThemeWindow)
|
||||
fThemeWindow = new ThemeWindow(this);
|
||||
else
|
||||
fThemeWindow->Activate();
|
||||
break;
|
||||
|
||||
case MSG_THEME_CLOSED:
|
||||
fThemeWindow = NULL;
|
||||
break;
|
||||
|
||||
case MSG_WINDOW_TITLE_SETTING_CHANGED:
|
||||
case MSG_TAB_TITLE_SETTING_CHANGED:
|
||||
_TitleSettingsChanged();
|
||||
@@ -987,8 +1001,10 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
PostMessage(MSG_HALF_FONT_CHANGED);
|
||||
break;
|
||||
|
||||
case MSG_COLOR_CHANGED:
|
||||
case MSG_COLOR_SCHEME_CHANGED:
|
||||
case MSG_SET_CURRENT_COLOR:
|
||||
case MSG_SET_COLOR:
|
||||
case MSG_UPDATE_COLOR:
|
||||
{
|
||||
for (int32 i = fTabView->CountTabs() - 1; i >= 0; i--) {
|
||||
TermViewContainerView* container = _TermViewContainerViewAt(i);
|
||||
|
||||
@@ -51,6 +51,7 @@ class BMenuBar;
|
||||
class FindWindow;
|
||||
class PrefWindow;
|
||||
class TermViewContainerView;
|
||||
class ThemeWindow;
|
||||
|
||||
|
||||
class TermWindow : public BWindow, private SmartTabView::Listener,
|
||||
@@ -211,6 +212,7 @@ private:
|
||||
|
||||
BMessage* fPrintSettings;
|
||||
PrefWindow* fPrefWindow;
|
||||
ThemeWindow* fThemeWindow;
|
||||
FindWindow* fFindPanel;
|
||||
BRect fSavedFrame;
|
||||
window_look fSavedLook;
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* Copyright 2022 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ThemeView.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Catalog.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <Font.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Locale.h>
|
||||
#include <Messenger.h>
|
||||
#include <Path.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
|
||||
#include "ThemeWindow.h"
|
||||
#include "Colors.h"
|
||||
#include "ColorPreview.h"
|
||||
#include "ColorListView.h"
|
||||
#include "ColorItem.h"
|
||||
#include "TermConst.h"
|
||||
#include "PrefHandler.h"
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Terminal ThemeView"
|
||||
|
||||
#define COLOR_DROPPED 'cldp'
|
||||
#define DECORATOR_CHANGED 'dcch'
|
||||
|
||||
|
||||
/* static */ const char*
|
||||
ThemeView::kColorTable[] = {
|
||||
B_TRANSLATE_MARK("Text"),
|
||||
B_TRANSLATE_MARK("Background"),
|
||||
B_TRANSLATE_MARK("Cursor"),
|
||||
B_TRANSLATE_MARK("Text under cursor"),
|
||||
B_TRANSLATE_MARK("Selected text"),
|
||||
B_TRANSLATE_MARK("Selected background"),
|
||||
B_TRANSLATE_MARK("ANSI black color"),
|
||||
B_TRANSLATE_MARK("ANSI red color"),
|
||||
B_TRANSLATE_MARK("ANSI green color"),
|
||||
B_TRANSLATE_MARK("ANSI yellow color"),
|
||||
B_TRANSLATE_MARK("ANSI blue color"),
|
||||
B_TRANSLATE_MARK("ANSI magenta color"),
|
||||
B_TRANSLATE_MARK("ANSI cyan color"),
|
||||
B_TRANSLATE_MARK("ANSI white color"),
|
||||
B_TRANSLATE_MARK("ANSI bright black color"),
|
||||
B_TRANSLATE_MARK("ANSI bright red color"),
|
||||
B_TRANSLATE_MARK("ANSI bright green color"),
|
||||
B_TRANSLATE_MARK("ANSI bright yellow color"),
|
||||
B_TRANSLATE_MARK("ANSI bright blue color"),
|
||||
B_TRANSLATE_MARK("ANSI bright magenta color"),
|
||||
B_TRANSLATE_MARK("ANSI bright cyan color"),
|
||||
B_TRANSLATE_MARK("ANSI bright white color"),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
ThemeView::ThemeView(const char* name, const BMessenger& messenger)
|
||||
:
|
||||
BGroupView(name, B_VERTICAL, 5),
|
||||
fTerminalMessenger(messenger)
|
||||
{
|
||||
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
|
||||
// Set up list of color attributes
|
||||
fAttrList = new ColorListView("AttributeList");
|
||||
|
||||
fScrollView = new BScrollView("ScrollView", fAttrList, 0, false, true);
|
||||
fScrollView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
|
||||
PrefHandler* prefHandler = PrefHandler::Default();
|
||||
|
||||
for (const char** table = kColorTable; *table != NULL; ++table) {
|
||||
fAttrList->AddItem(new ColorItem(B_TRANSLATE_NOCOLLECT(*table),
|
||||
prefHandler->getRGB(*table)));
|
||||
}
|
||||
|
||||
fColorSchemeMenu = new BPopUpMenu("");
|
||||
fColorSchemeField = new BMenuField(B_TRANSLATE("Color scheme:"),
|
||||
fColorSchemeMenu);
|
||||
|
||||
fColorPreview = new ColorPreview(new BMessage(COLOR_DROPPED), 0);
|
||||
fColorPreview->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
|
||||
B_ALIGN_VERTICAL_CENTER));
|
||||
|
||||
fPicker = new BColorControl(B_ORIGIN, B_CELLS_32x8, 8.0,
|
||||
"picker", new BMessage(MSG_UPDATE_COLOR));
|
||||
|
||||
fPreview = new BTextView("preview");
|
||||
|
||||
BLayoutBuilder::Group<>(this)
|
||||
.AddGrid()
|
||||
.Add(fColorSchemeField->CreateLabelLayoutItem(), 0, 5)
|
||||
.Add(fColorSchemeField->CreateMenuBarLayoutItem(), 1, 5)
|
||||
.End()
|
||||
.Add(fScrollView, 10.0)
|
||||
.Add(fPreview)
|
||||
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
|
||||
.Add(fColorPreview)
|
||||
.AddGlue()
|
||||
.Add(fPicker);
|
||||
|
||||
fColorPreview->Parent()->SetExplicitMaxSize(
|
||||
BSize(B_SIZE_UNSET, fPicker->Bounds().Height()));
|
||||
fAttrList->SetSelectionMessage(new BMessage(MSG_COLOR_ATTRIBUTE_CHOSEN));
|
||||
fScrollView->SetExplicitMinSize(BSize(B_SIZE_UNSET, 22 * 16));
|
||||
fColorSchemeField->SetAlignment(B_ALIGN_RIGHT);
|
||||
|
||||
_MakeColorSchemeMenu();
|
||||
|
||||
_UpdateStyle();
|
||||
|
||||
InvalidateLayout(true);
|
||||
}
|
||||
|
||||
|
||||
ThemeView::~ThemeView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_UpdateStyle()
|
||||
{
|
||||
PrefHandler* prefHandler = PrefHandler::Default();
|
||||
|
||||
const char* colours[] = {
|
||||
B_TRANSLATE("black"),
|
||||
B_TRANSLATE("red"),
|
||||
B_TRANSLATE("green"),
|
||||
B_TRANSLATE("yellow"),
|
||||
B_TRANSLATE("blue"),
|
||||
B_TRANSLATE("magenta"),
|
||||
B_TRANSLATE("cyan"),
|
||||
B_TRANSLATE("white"),
|
||||
};
|
||||
|
||||
text_run_array *array = (text_run_array*)malloc(sizeof(text_run_array)
|
||||
+ sizeof(text_run) * 16);
|
||||
int offset = 1;
|
||||
int index = 0;
|
||||
array->count = 16;
|
||||
array->runs[0].offset = offset;
|
||||
array->runs[0].font = *be_fixed_font;
|
||||
array->runs[0].color = prefHandler->getRGB(PREF_ANSI_BLACK_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[1].offset = offset;
|
||||
array->runs[1].font = *be_fixed_font;
|
||||
array->runs[1].color = prefHandler->getRGB(PREF_ANSI_RED_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[2].offset = offset;
|
||||
array->runs[2].font = *be_fixed_font;
|
||||
array->runs[2].color = prefHandler->getRGB(PREF_ANSI_GREEN_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[3].offset = offset;
|
||||
array->runs[3].font = *be_fixed_font;
|
||||
array->runs[3].color = prefHandler->getRGB(PREF_ANSI_YELLOW_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[4].offset = offset;
|
||||
array->runs[4].font = *be_fixed_font;
|
||||
array->runs[4].color = prefHandler->getRGB(PREF_ANSI_BLUE_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[5].offset = offset;
|
||||
array->runs[5].font = *be_fixed_font;
|
||||
array->runs[5].color = prefHandler->getRGB(PREF_ANSI_MAGENTA_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[6].offset = offset;
|
||||
array->runs[6].font = *be_fixed_font;
|
||||
array->runs[6].color = prefHandler->getRGB(PREF_ANSI_CYAN_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[7].offset = offset;
|
||||
array->runs[7].font = *be_fixed_font;
|
||||
array->runs[7].color = prefHandler->getRGB(PREF_ANSI_WHITE_COLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
index = 0;
|
||||
offset++;
|
||||
array->runs[8].offset = offset;
|
||||
array->runs[8].font = *be_fixed_font;
|
||||
array->runs[8].color = prefHandler->getRGB(PREF_ANSI_BLACK_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[9].offset = offset;
|
||||
array->runs[9].font = *be_fixed_font;
|
||||
array->runs[9].color = prefHandler->getRGB(PREF_ANSI_RED_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[10].offset = offset;
|
||||
array->runs[10].font = *be_fixed_font;
|
||||
array->runs[10].color = prefHandler->getRGB(PREF_ANSI_GREEN_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[11].offset = offset;
|
||||
array->runs[11].font = *be_fixed_font;
|
||||
array->runs[11].color = prefHandler->getRGB(PREF_ANSI_YELLOW_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[12].offset = offset;
|
||||
array->runs[12].font = *be_fixed_font;
|
||||
array->runs[12].color = prefHandler->getRGB(PREF_ANSI_BLUE_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[13].offset = offset;
|
||||
array->runs[13].font = *be_fixed_font;
|
||||
array->runs[13].color = prefHandler->getRGB(PREF_ANSI_MAGENTA_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[14].offset = offset;
|
||||
array->runs[14].font = *be_fixed_font;
|
||||
array->runs[14].color = prefHandler->getRGB(PREF_ANSI_CYAN_HCOLOR);
|
||||
offset += strlen(colours[index++]) + 1;
|
||||
array->runs[15].offset = offset;
|
||||
array->runs[15].font = *be_fixed_font;
|
||||
array->runs[15].color = prefHandler->getRGB(PREF_ANSI_WHITE_HCOLOR);
|
||||
|
||||
fPreview->SetStylable(true);
|
||||
fPreview->MakeEditable(false);
|
||||
fPreview->MakeSelectable(false);
|
||||
fPreview->SetViewColor(prefHandler->getRGB(PREF_TEXT_BACK_COLOR));
|
||||
|
||||
BString previewText;
|
||||
previewText << '\n';
|
||||
for (int ix = 0; ix < 8; ++ix)
|
||||
{
|
||||
previewText << ' ' << colours[ix];
|
||||
}
|
||||
previewText << '\n';
|
||||
for (int ix = 0; ix < 8; ++ix)
|
||||
{
|
||||
previewText << ' ' << colours[ix];
|
||||
}
|
||||
previewText << '\n';
|
||||
|
||||
fPreview->SetAlignment(B_ALIGN_CENTER);
|
||||
fPreview->SetText(previewText.String(), array);
|
||||
font_height height;
|
||||
be_fixed_font->GetHeight(&height);
|
||||
fPreview->SetExplicitMinSize(BSize(B_SIZE_UNSET, (height.ascent + height.descent) * 5));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::AttachedToWindow()
|
||||
{
|
||||
fPicker->SetTarget(this);
|
||||
fAttrList->SetTarget(this);
|
||||
fColorPreview->SetTarget(this);
|
||||
fColorSchemeField->Menu()->SetTargetForItems(this);
|
||||
|
||||
fAttrList->Select(0);
|
||||
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
|
||||
_SetCurrentColorScheme();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::WindowActivated(bool active)
|
||||
{
|
||||
if (!active)
|
||||
return;
|
||||
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::UpdateMenu()
|
||||
{
|
||||
PrefHandler::Default()->LoadThemes();
|
||||
|
||||
_MakeColorSchemeMenu();
|
||||
_SetCurrentColorScheme();
|
||||
|
||||
fColorSchemeField->Menu()->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
switch (msg->what) {
|
||||
case MSG_COLOR_SCHEME_CHANGED:
|
||||
{
|
||||
color_scheme* newScheme = NULL;
|
||||
if (msg->FindPointer("color_scheme",
|
||||
(void**)&newScheme) == B_OK) {
|
||||
_ChangeColorScheme(newScheme);
|
||||
modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SET_COLOR:
|
||||
{
|
||||
rgb_color* color;
|
||||
ssize_t size;
|
||||
const char* name;
|
||||
|
||||
if (msg->FindData(kRGBColor, B_RGB_COLOR_TYPE,
|
||||
(const void**)&color, &size) == B_OK
|
||||
&& msg->FindString(kName, &name) == B_OK) {
|
||||
_SetColor(name, *color);
|
||||
modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SET_CURRENT_COLOR:
|
||||
{
|
||||
rgb_color* color;
|
||||
ssize_t size;
|
||||
|
||||
if (msg->FindData(kRGBColor, B_RGB_COLOR_TYPE,
|
||||
(const void**)&color, &size) == B_OK) {
|
||||
_SetCurrentColor(*color);
|
||||
modified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_UPDATE_COLOR:
|
||||
{
|
||||
// Received from the color fPicker when its color changes
|
||||
rgb_color color = fPicker->ValueAsColor();
|
||||
_SetCurrentColor(color);
|
||||
modified = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_COLOR_ATTRIBUTE_CHOSEN:
|
||||
{
|
||||
// Received when the user chooses a GUI fAttribute from the list
|
||||
ColorItem* item = (ColorItem*)
|
||||
fAttrList->ItemAt(fAttrList->CurrentSelection());
|
||||
if (item == NULL)
|
||||
break;
|
||||
|
||||
const char* label = item->Text();
|
||||
rgb_color color = PrefHandler::Default()->getRGB(label);
|
||||
_SetCurrentColor(color);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_THEME_MODIFIED:
|
||||
_SetCurrentColorScheme();
|
||||
BView::MessageReceived(msg);
|
||||
return;
|
||||
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
_UpdateStyle();
|
||||
fTerminalMessenger.SendMessage(msg);
|
||||
|
||||
BMessenger messenger(this);
|
||||
messenger.SendMessage(MSG_THEME_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::SetDefaults()
|
||||
{
|
||||
PrefHandler* prefHandler = PrefHandler::Default();
|
||||
|
||||
int32 count = fAttrList->CountItems();
|
||||
for (int32 index = 0; index < count; ++index) {
|
||||
ColorItem* item = (ColorItem*)fAttrList->ItemAt(index);
|
||||
item->SetColor(prefHandler->getRGB(item->Text()));
|
||||
fAttrList->InvalidateItem(index);
|
||||
}
|
||||
|
||||
int32 currentIndex = fAttrList->CurrentSelection();
|
||||
ColorItem* item = (ColorItem*)fAttrList->ItemAt(currentIndex);
|
||||
if (item != NULL) {
|
||||
rgb_color color = item->Color();
|
||||
fPicker->SetValue(color);
|
||||
fColorPreview->SetColor(color);
|
||||
fColorPreview->Invalidate();
|
||||
}
|
||||
|
||||
_UpdateStyle();
|
||||
|
||||
BMessage message(MSG_COLOR_SCHEME_CHANGED);
|
||||
fTerminalMessenger.SendMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::Revert()
|
||||
{
|
||||
_SetCurrentColorScheme();
|
||||
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_ChangeColorScheme(color_scheme* scheme)
|
||||
{
|
||||
PrefHandler* pref = PrefHandler::Default();
|
||||
|
||||
pref->setRGB(PREF_TEXT_FORE_COLOR, scheme->text_fore_color);
|
||||
pref->setRGB(PREF_TEXT_BACK_COLOR, scheme->text_back_color);
|
||||
pref->setRGB(PREF_SELECT_FORE_COLOR, scheme->select_fore_color);
|
||||
pref->setRGB(PREF_SELECT_BACK_COLOR, scheme->select_back_color);
|
||||
pref->setRGB(PREF_CURSOR_FORE_COLOR, scheme->cursor_fore_color);
|
||||
pref->setRGB(PREF_CURSOR_BACK_COLOR, scheme->cursor_back_color);
|
||||
pref->setRGB(PREF_ANSI_BLACK_COLOR, scheme->ansi_colors.black);
|
||||
pref->setRGB(PREF_ANSI_RED_COLOR, scheme->ansi_colors.red);
|
||||
pref->setRGB(PREF_ANSI_GREEN_COLOR, scheme->ansi_colors.green);
|
||||
pref->setRGB(PREF_ANSI_YELLOW_COLOR, scheme->ansi_colors.yellow);
|
||||
pref->setRGB(PREF_ANSI_BLUE_COLOR, scheme->ansi_colors.blue);
|
||||
pref->setRGB(PREF_ANSI_MAGENTA_COLOR, scheme->ansi_colors.magenta);
|
||||
pref->setRGB(PREF_ANSI_CYAN_COLOR, scheme->ansi_colors.cyan);
|
||||
pref->setRGB(PREF_ANSI_WHITE_COLOR, scheme->ansi_colors.white);
|
||||
pref->setRGB(PREF_ANSI_BLACK_HCOLOR, scheme->ansi_colors_h.black);
|
||||
pref->setRGB(PREF_ANSI_RED_HCOLOR, scheme->ansi_colors_h.red);
|
||||
pref->setRGB(PREF_ANSI_GREEN_HCOLOR, scheme->ansi_colors_h.green);
|
||||
pref->setRGB(PREF_ANSI_YELLOW_HCOLOR, scheme->ansi_colors_h.yellow);
|
||||
pref->setRGB(PREF_ANSI_BLUE_HCOLOR, scheme->ansi_colors_h.blue);
|
||||
pref->setRGB(PREF_ANSI_MAGENTA_HCOLOR, scheme->ansi_colors_h.magenta);
|
||||
pref->setRGB(PREF_ANSI_CYAN_HCOLOR, scheme->ansi_colors_h.cyan);
|
||||
pref->setRGB(PREF_ANSI_WHITE_HCOLOR, scheme->ansi_colors_h.white);
|
||||
|
||||
int32 count = fAttrList->CountItems();
|
||||
for (int32 index = 0; index < count; ++index)
|
||||
{
|
||||
ColorItem* item = static_cast<ColorItem*>(fAttrList->ItemAt(index));
|
||||
rgb_color color = pref->getRGB(item->Text());
|
||||
item->SetColor(color);
|
||||
|
||||
if (item->IsSelected()) {
|
||||
fPicker->SetValue(color);
|
||||
fColorPreview->SetColor(color);
|
||||
fColorPreview->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
fAttrList->Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_SetCurrentColorScheme()
|
||||
{
|
||||
PrefHandler* pref = PrefHandler::Default();
|
||||
|
||||
pref->LoadColorScheme(&gCustomColorScheme);
|
||||
|
||||
const char* currentSchemeName = NULL;
|
||||
|
||||
int32 i = 0;
|
||||
while (i < gColorSchemes->CountItems()) {
|
||||
const color_scheme *item = gColorSchemes->ItemAt(i);
|
||||
i++;
|
||||
|
||||
if (gCustomColorScheme == *item) {
|
||||
currentSchemeName = item->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the scheme is not one of the known ones, assume a custom one.
|
||||
if (currentSchemeName == NULL)
|
||||
currentSchemeName = "Custom";
|
||||
|
||||
for (int32 i = 0; i < fColorSchemeField->Menu()->CountItems(); i++) {
|
||||
BMenuItem* item = fColorSchemeField->Menu()->ItemAt(i);
|
||||
if (strcmp(item->Label(), currentSchemeName) == 0) {
|
||||
item->SetMarked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_MakeColorSchemeMenuItem(const color_scheme *item)
|
||||
{
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
BMessage* message = new BMessage(MSG_COLOR_SCHEME_CHANGED);
|
||||
message->AddPointer("color_scheme", (const void*)item);
|
||||
fColorSchemeMenu->AddItem(new BMenuItem(item->name, message));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_MakeColorSchemeMenu()
|
||||
{
|
||||
while (fColorSchemeMenu->CountItems() > 0)
|
||||
delete(fColorSchemeMenu->RemoveItem((int32)0));
|
||||
|
||||
FindColorSchemeByName comparator("Default");
|
||||
|
||||
const color_scheme* defaultItem = gColorSchemes->FindIf(comparator);
|
||||
|
||||
_MakeColorSchemeMenuItem(defaultItem);
|
||||
|
||||
int32 index = 0;
|
||||
while (index < gColorSchemes->CountItems()) {
|
||||
const color_scheme *item = gColorSchemes->ItemAt(index);
|
||||
index++;
|
||||
|
||||
if (strcmp(item->name, "") == 0)
|
||||
fColorSchemeMenu->AddSeparatorItem();
|
||||
else if (item == defaultItem)
|
||||
continue;
|
||||
else
|
||||
_MakeColorSchemeMenuItem(item);
|
||||
}
|
||||
|
||||
// Add the custom item at the very end
|
||||
fColorSchemeMenu->AddSeparatorItem();
|
||||
_MakeColorSchemeMenuItem(&gCustomColorScheme);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_SetCurrentColor(rgb_color color)
|
||||
{
|
||||
int32 currentIndex = fAttrList->CurrentSelection();
|
||||
ColorItem* item = (ColorItem*)fAttrList->ItemAt(currentIndex);
|
||||
if (item != NULL) {
|
||||
item->SetColor(color);
|
||||
fAttrList->InvalidateItem(currentIndex);
|
||||
|
||||
PrefHandler::Default()->setRGB(item->Text(), color);
|
||||
}
|
||||
|
||||
fPicker->SetValue(color);
|
||||
fColorPreview->SetColor(color);
|
||||
fColorPreview->Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeView::_SetColor(const char* name, rgb_color color)
|
||||
{
|
||||
PrefHandler::Default()->setRGB(name, color);
|
||||
|
||||
_UpdateStyle();
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2022, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef THEME_VIEW_H
|
||||
#define THEME_VIEW_H
|
||||
|
||||
|
||||
#include <Button.h>
|
||||
#include <ColorControl.h>
|
||||
#include <GroupView.h>
|
||||
#include <ListItem.h>
|
||||
#include <ListView.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <ObjectList.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
#include <StringView.h>
|
||||
#include <View.h>
|
||||
|
||||
#include "Colors.h"
|
||||
|
||||
|
||||
static const uint32 MSG_COLOR_SCHEME_CHANGED = 'mccs';
|
||||
static const uint32 MSG_SET_CURRENT_COLOR = 'sccl';
|
||||
static const uint32 MSG_UPDATE_COLOR = 'upcl';
|
||||
static const uint32 MSG_COLOR_ATTRIBUTE_CHOSEN = 'atch';
|
||||
static const uint32 MSG_THEME_MODIFIED = 'tmdf';
|
||||
static const uint32 MSG_SET_COLOR = 'sclr';
|
||||
|
||||
static const char* const kRGBColor = "RGBColor";
|
||||
static const char* const kName = "name";
|
||||
|
||||
class ThemeWindow;
|
||||
class ColorPreview;
|
||||
class BMenu;
|
||||
class BMenuField;
|
||||
class BPopUpMenu;
|
||||
class BTextView;
|
||||
|
||||
class ThemeView : public BGroupView {
|
||||
public:
|
||||
ThemeView(const char *name,
|
||||
const BMessenger &messenger);
|
||||
virtual ~ThemeView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void WindowActivated(bool active);
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
|
||||
void SetDefaults();
|
||||
void Revert();
|
||||
void UpdateMenu();
|
||||
|
||||
private:
|
||||
void _UpdateStyle();
|
||||
void _ChangeColorScheme(color_scheme* scheme);
|
||||
void _SetCurrentColorScheme();
|
||||
void _SetCurrentColor(rgb_color color);
|
||||
void _SetColor(const char* name, rgb_color color);
|
||||
|
||||
void _MakeColorSchemeMenu();
|
||||
void _MakeColorSchemeMenuItem(const color_scheme *item);
|
||||
|
||||
private:
|
||||
BColorControl* fPicker;
|
||||
BListView* fAttrList;
|
||||
const char* fName;
|
||||
BScrollView* fScrollView;
|
||||
ColorPreview* fColorPreview;
|
||||
BMenuField* fColorSchemeField;
|
||||
BPopUpMenu* fColorSchemeMenu;
|
||||
BTextView* fPreview;
|
||||
|
||||
BMessage fPrevColors;
|
||||
BMessage fDefaultColors;
|
||||
BMessage fCurrentColors;
|
||||
|
||||
BMessenger fTerminalMessenger;
|
||||
|
||||
public:
|
||||
static const char* kColorTable[];
|
||||
};
|
||||
|
||||
#endif // THEME_VIEW_H
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2022, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ThemeWindow.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <Directory.h>
|
||||
#include <File.h>
|
||||
#include <FilePanel.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Locale.h>
|
||||
#include <Messenger.h>
|
||||
#include <Path.h>
|
||||
#include <SeparatorView.h>
|
||||
|
||||
#include "PrefHandler.h"
|
||||
#include "TermConst.h"
|
||||
#include "ThemeView.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Terminal ThemeWindow"
|
||||
|
||||
// local messages
|
||||
const uint32 MSG_DEFAULTS_PRESSED = 'defl';
|
||||
const uint32 MSG_SAVEAS_PRESSED = 'canl';
|
||||
const uint32 MSG_REVERT_PRESSED = 'revt';
|
||||
|
||||
|
||||
ThemeWindow::ThemeWindow(const BMessenger& messenger)
|
||||
:
|
||||
BWindow(BRect(0, 0, 0, 0), B_TRANSLATE_SYSTEM_NAME("Theme settings"), B_TITLED_WINDOW,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fPreviousPref(new PrefHandler(PrefHandler::Default())),
|
||||
fSavePanel(NULL),
|
||||
fDirty(false),
|
||||
fTerminalMessenger(messenger)
|
||||
{
|
||||
fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"),
|
||||
new BMessage(MSG_DEFAULTS_PRESSED), B_WILL_DRAW);
|
||||
|
||||
fRevertButton = new BButton("revert", B_TRANSLATE("Revert"),
|
||||
new BMessage(MSG_REVERT_PRESSED), B_WILL_DRAW);
|
||||
|
||||
fSaveAsFileButton = new BButton("savebutton",
|
||||
B_TRANSLATE("Save to file" B_UTF8_ELLIPSIS),
|
||||
new BMessage(MSG_SAVEAS_PRESSED), B_WILL_DRAW);
|
||||
|
||||
fThemeView = new ThemeView(B_TRANSLATE("Theme"), fTerminalMessenger);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||
.SetInsets(B_USE_WINDOW_SPACING)
|
||||
.Add(fThemeView)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(fDefaultsButton)
|
||||
.Add(fRevertButton)
|
||||
.AddGlue()
|
||||
.Add(fSaveAsFileButton)
|
||||
.SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0);
|
||||
|
||||
fRevertButton->SetEnabled(fDirty);
|
||||
|
||||
AddShortcut('Q', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
|
||||
AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
|
||||
|
||||
CenterOnScreen();
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::Quit()
|
||||
{
|
||||
fTerminalMessenger.SendMessage(MSG_THEME_CLOSED);
|
||||
delete fPreviousPref;
|
||||
delete fSavePanel;
|
||||
BWindow::Quit();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ThemeWindow::QuitRequested()
|
||||
{
|
||||
if (fDirty)
|
||||
_Save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::_SaveAs()
|
||||
{
|
||||
if (!fSavePanel) {
|
||||
BMessenger messenger(this);
|
||||
fSavePanel = new BFilePanel(B_SAVE_PANEL, &messenger);
|
||||
}
|
||||
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
|
||||
path.Append("Terminal/Themes");
|
||||
create_directory(path.Path(), 0755);
|
||||
fSavePanel->SetPanelDirectory(path.Path());
|
||||
}
|
||||
|
||||
fSavePanel->Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::_SaveRequested(BMessage *msg)
|
||||
{
|
||||
entry_ref dirref;
|
||||
const char* filename;
|
||||
|
||||
msg->FindRef("directory", &dirref);
|
||||
msg->FindString("name", &filename);
|
||||
|
||||
BDirectory dir(&dirref);
|
||||
BPath path(&dir, filename);
|
||||
|
||||
PrefHandler *prefHandler = PrefHandler::Default();
|
||||
|
||||
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
|
||||
char buffer[512];
|
||||
|
||||
for (const char** table = ThemeView::kColorTable; *table != NULL; ++table) {
|
||||
int len = snprintf(buffer, sizeof(buffer), "\"%s\" , \"%s\"\n",
|
||||
*table, prefHandler->getString(*table));
|
||||
file.Write(buffer, len);
|
||||
}
|
||||
|
||||
// Name the theme after the filename
|
||||
int len = snprintf(buffer, sizeof(buffer), "\"%s\" , \"%s\"\n",
|
||||
PREF_THEME_NAME, filename);
|
||||
file.Write(buffer, len);
|
||||
|
||||
fThemeView->UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::_Save()
|
||||
{
|
||||
delete fPreviousPref;
|
||||
fPreviousPref = new PrefHandler(PrefHandler::Default());
|
||||
|
||||
PrefHandler::Default()->SaveDefaultAsText();
|
||||
fDirty = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::_Revert()
|
||||
{
|
||||
if (fDirty) {
|
||||
PrefHandler::SetDefault(new PrefHandler(fPreviousPref));
|
||||
|
||||
fThemeView->Revert();
|
||||
|
||||
fDirty = false;
|
||||
fRevertButton->SetEnabled(fDirty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThemeWindow::MessageReceived(BMessage *message)
|
||||
{
|
||||
switch (message->what) {
|
||||
|
||||
case MSG_SAVEAS_PRESSED:
|
||||
_SaveAs();
|
||||
break;
|
||||
|
||||
case MSG_REVERT_PRESSED:
|
||||
_Revert();
|
||||
break;
|
||||
|
||||
case MSG_DEFAULTS_PRESSED:
|
||||
PrefHandler::SetDefault(new PrefHandler(false));
|
||||
fThemeView->SetDefaults();
|
||||
// fallthrough
|
||||
|
||||
case MSG_THEME_MODIFIED:
|
||||
fDirty = true;
|
||||
fRevertButton->SetEnabled(fDirty);
|
||||
break;
|
||||
|
||||
case B_SAVE_REQUESTED:
|
||||
_SaveRequested(message);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2022, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef THEME_WINDOW_H
|
||||
#define THEME_WINDOW_H
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
#include <Button.h>
|
||||
#include <Window.h>
|
||||
#include <Message.h>
|
||||
|
||||
// local messages
|
||||
const uint32 MSG_THEME_CLOSED = 'mstc';
|
||||
|
||||
class BFilePanel;
|
||||
class PrefHandler;
|
||||
class ThemeView;
|
||||
|
||||
|
||||
class ThemeWindow : public BWindow {
|
||||
public:
|
||||
ThemeWindow(const BMessenger &messenger);
|
||||
virtual ~ThemeWindow() {};
|
||||
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
virtual void Quit();
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
void _Save();
|
||||
void _SaveAs();
|
||||
void _Revert();
|
||||
void _SaveRequested(BMessage *message);
|
||||
|
||||
PrefHandler* fPreviousPref;
|
||||
BFilePanel* fSavePanel;
|
||||
|
||||
ThemeView* fThemeView;
|
||||
BButton* fDefaultsButton;
|
||||
BButton* fRevertButton;
|
||||
BButton* fSaveAsFileButton;
|
||||
|
||||
bool fDirty;
|
||||
BMessenger fTerminalMessenger;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user