1 /* 2 * Copyright 2014 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * John Scipione, jscipione@gmail.com 7 */ 8 9 10 #include "ColorMenuItem.h" 11 12 #include <math.h> 13 #include <string.h> 14 #include <syslog.h> 15 16 #include <algorithm> 17 18 #include <MenuField.h> 19 #include <MenuPrivate.h> 20 21 22 // golden ratio 23 #ifdef M_PHI 24 # undef M_PHI 25 #endif 26 #define M_PHI 1.61803398874989484820 27 28 29 // #pragma - ColorMenuItem 30 31 32 BColorMenuItem::BColorMenuItem(const char* label, BMessage* message, 33 rgb_color color, char shortcut, uint32 modifiers) 34 : 35 BMenuItem(label, message, shortcut, modifiers), 36 fColor(color) 37 { 38 } 39 40 41 BColorMenuItem::BColorMenuItem(BMenu* menu, rgb_color color, 42 BMessage* message) 43 : 44 BMenuItem(menu, message), 45 fColor(color) 46 { 47 } 48 49 50 BColorMenuItem::BColorMenuItem(BMessage* data) 51 : 52 BMenuItem(data) 53 { 54 if (data->HasColor("_color")) { 55 rgb_color color; 56 57 color = data->GetColor("_color", (rgb_color){ 0, 0, 0 }); 58 fColor = color; 59 } else 60 fColor = (rgb_color){ 0, 0, 0 }; 61 } 62 63 64 BArchivable* 65 BColorMenuItem::Instantiate(BMessage* data) 66 { 67 if (validate_instantiation(data, "BColorMenuItem")) 68 return new BColorMenuItem(data); 69 70 return NULL; 71 } 72 73 74 status_t 75 BColorMenuItem::Archive(BMessage* data, bool deep) const 76 { 77 status_t result = BMenuItem::Archive(data, deep); 78 79 if (result == B_OK) 80 result = data->AddColor("_color", fColor); 81 82 return result; 83 } 84 85 86 void 87 BColorMenuItem::DrawContent() 88 { 89 float leftMargin = _LeftMargin(); 90 float padding = _Padding(); 91 float colorRectWidth = _ColorRectWidth(); 92 93 BRect colorRect(Frame().InsetByCopy(2.0f, 2.0f)); 94 colorRect.left = colorRect.right = leftMargin; 95 colorRect.right += colorRectWidth; 96 97 rgb_color highColor = Menu()->HighColor(); 98 99 Menu()->SetDrawingMode(B_OP_OVER); 100 101 Menu()->SetHighColor(fColor); 102 Menu()->FillRect(colorRect); 103 104 Menu()->SetHighColor(ui_color(B_CONTROL_BORDER_COLOR)); 105 Menu()->StrokeRect(colorRect); 106 107 float width = colorRectWidth + padding; 108 109 Menu()->MovePenBy(width, 0.0f); 110 Menu()->SetHighColor(highColor); 111 112 BMenuItem::DrawContent(); 113 } 114 115 116 void 117 BColorMenuItem::GetContentSize(float* _width, float* _height) 118 { 119 float labelWidth; 120 float height; 121 BMenuItem::GetContentSize(&labelWidth, &height); 122 123 if (_width != NULL) 124 *_width = _LeftMargin() + _ColorRectWidth() + _Padding() + labelWidth; 125 126 if (_height != NULL) 127 *_height = height; 128 } 129 130 131 void 132 BColorMenuItem::SetMarked(bool mark) 133 { 134 BMenuItem::SetMarked(mark); 135 136 if (!mark) 137 return; 138 139 // we are marking the item 140 141 BMenu* menu = Menu(); 142 if (menu == NULL) 143 return; 144 145 // we have a parent menu 146 147 BMenu* _menu = menu; 148 while ((_menu = _menu->Supermenu()) != NULL) 149 menu = _menu; 150 151 // went up the hierarchy to found the topmost menu 152 153 if (menu == NULL || menu->Parent() == NULL) 154 return; 155 156 // our topmost menu has a parent 157 158 if (dynamic_cast<BMenuField*>(menu->Parent()) == NULL) 159 return; 160 161 // our topmost menu's parent is a BMenuField 162 163 BMenuItem* topLevelItem = menu->ItemAt((int32)0); 164 165 if (topLevelItem == NULL) 166 return; 167 168 // our topmost menu has a menu item 169 170 BColorMenuItem* topLevelColorMenuItem 171 = dynamic_cast<BColorMenuItem*>(topLevelItem); 172 if (topLevelColorMenuItem == NULL) 173 return; 174 175 // our topmost menu's item is a BColorMenuItem 176 177 // update the color 178 topLevelColorMenuItem->SetColor(fColor); 179 menu->Invalidate(); 180 } 181 182 183 // #pragma mark - BColorMenuItem private methods 184 185 186 float 187 BColorMenuItem::_LeftMargin() 188 { 189 BPrivate::MenuPrivate menuPrivate(Menu()); 190 float leftMargin; 191 menuPrivate.GetItemMargins(&leftMargin, NULL, NULL, NULL); 192 return leftMargin; 193 } 194 195 196 float 197 BColorMenuItem::_Padding() 198 { 199 return floorf(std::max(14.0f, be_plain_font->Size() + 2) / 2); 200 } 201 202 203 float 204 BColorMenuItem::_ColorRectWidth() 205 { 206 return floorf(std::max(14.0f, be_plain_font->Size() + 2) * M_PHI); 207 } 208 209 210 211 // #pragma mark - BColorMenuItem reserved virtual methods 212 213 214 void BColorMenuItem::_ReservedColorMenuItem1() {} 215 void BColorMenuItem::_ReservedColorMenuItem2() {} 216 void BColorMenuItem::_ReservedColorMenuItem3() {} 217 void BColorMenuItem::_ReservedColorMenuItem4() {} 218 void BColorMenuItem::_ReservedColorMenuItem5() {} 219 void BColorMenuItem::_ReservedColorMenuItem6() {} 220 void BColorMenuItem::_ReservedColorMenuItem7() {} 221 void BColorMenuItem::_ReservedColorMenuItem8() {} 222 void BColorMenuItem::_ReservedColorMenuItem9() {} 223 void BColorMenuItem::_ReservedColorMenuItem10() {} 224 void BColorMenuItem::_ReservedColorMenuItem11() {} 225 void BColorMenuItem::_ReservedColorMenuItem12() {} 226 void BColorMenuItem::_ReservedColorMenuItem13() {} 227 void BColorMenuItem::_ReservedColorMenuItem14() {} 228 void BColorMenuItem::_ReservedColorMenuItem15() {} 229 void BColorMenuItem::_ReservedColorMenuItem16() {} 230 void BColorMenuItem::_ReservedColorMenuItem17() {} 231 void BColorMenuItem::_ReservedColorMenuItem18() {} 232 void BColorMenuItem::_ReservedColorMenuItem19() {} 233 void BColorMenuItem::_ReservedColorMenuItem20() {} 234