File: | home/HaikuArchives/ArtPaint/artpaint/controls/ColorPalette.cpp |
Warning: | line 1459, column 34 Potential leak of memory pointed to by 'new_set' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2003, Heikki Suhonen | |||
3 | * Distributed under the terms of the MIT License. | |||
4 | * | |||
5 | * Authors: | |||
6 | * Heikki Suhonen <heikki.suhonen@gmail.com> | |||
7 | * Dale Cieslak <dcieslak@yahoo.com> | |||
8 | * | |||
9 | */ | |||
10 | ||||
11 | #include "ColorPalette.h" | |||
12 | ||||
13 | #include "CMYControl.h" | |||
14 | #include "FileIdentificationStrings.h" | |||
15 | #include "FilePanels.h" | |||
16 | #include "FloaterManager.h" | |||
17 | #include "HSVControl.h" | |||
18 | #include "MessageConstants.h" | |||
19 | #include "MessageFilters.h" | |||
20 | #include "Patterns.h" | |||
21 | #include "PaintApplication.h" | |||
22 | #include "PaletteWindowClient.h" | |||
23 | #include "ResourceServer.h" | |||
24 | #include "RGBControl.h" | |||
25 | #include "SettingsServer.h" | |||
26 | #include "StatusView.h" | |||
27 | #include "UtilityClasses.h" | |||
28 | #include "YIQControl.h" | |||
29 | #include "YUVControl.h" | |||
30 | ||||
31 | ||||
32 | #include <Alert.h> | |||
33 | #include <Bitmap.h> | |||
34 | #include <Catalog.h> | |||
35 | #include <FilePanel.h> | |||
36 | #include <MenuBar.h> | |||
37 | #include <MenuItem.h> | |||
38 | #include <NodeInfo.h> | |||
39 | #include <Path.h> | |||
40 | #include <PictureButton.h> | |||
41 | #include <Resources.h> | |||
42 | #include <Roster.h> | |||
43 | #include <TextControl.h> | |||
44 | ||||
45 | ||||
46 | #include <stdlib.h> | |||
47 | #include <string.h> | |||
48 | ||||
49 | ||||
50 | #undef B_TRANSLATION_CONTEXT"ColorPalette" | |||
51 | #define B_TRANSLATION_CONTEXT"ColorPalette" "ColorPalette" | |||
52 | ||||
53 | ||||
54 | // Initialize the static variable to NULL. | |||
55 | ColorPaletteWindow* ColorPaletteWindow::palette_window = NULL__null; | |||
56 | BList* ColorPaletteWindow::master_window_list = new BList(); | |||
57 | BList* ColorPaletteWindow::palette_window_clients = new BList(); | |||
58 | ||||
59 | ||||
60 | ColorPaletteWindow::ColorPaletteWindow(BRect frame, int32 mode) | |||
61 | : BWindow(frame, B_TRANSLATE("Colors")BLocaleRoster::Default()->GetCatalog()->GetString(("Colors" ), "ColorPalette"), | |||
62 | B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_RESIZABLE | | |||
63 | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK | B_AVOID_FRONT) | |||
64 | , open_panel(NULL__null) | |||
65 | , save_panel(NULL__null) | |||
66 | { | |||
67 | // here we just record the mode that user has requested | |||
68 | // for displaying the controls (eg. RGBA, HSV, something else) | |||
69 | selector_mode = mode; | |||
70 | ||||
71 | color_control = NULL__null; | |||
72 | color_slider = NULL__null; | |||
73 | ||||
74 | window_feel feel = B_NORMAL_WINDOW_FEEL; | |||
75 | if (SettingsServer* server = SettingsServer::Instance()) { | |||
76 | server->SetValue(SettingsServer::Application, skPaletteWindowVisible, | |||
77 | true); | |||
78 | ||||
79 | BMessage settings; | |||
80 | if (server->GetApplicationSettings(&settings) == B_OK((int)0)) | |||
81 | settings.FindInt32(skPaletteWindowFeel, (int32*)&feel); | |||
82 | } | |||
83 | SetFeel(feel); | |||
84 | ||||
85 | window_look look = B_FLOATING_WINDOW_LOOK; | |||
86 | if (feel == B_NORMAL_WINDOW_FEEL) | |||
87 | look = B_TITLED_WINDOW_LOOK; | |||
88 | SetLook(look); | |||
89 | ||||
90 | openMenuBar(); | |||
91 | // call some function that initializes the views depending on the mode | |||
92 | if (!openControlViews(mode)) { | |||
93 | // if for some reason view opening did not succeed we delete all of them | |||
94 | // that were created | |||
95 | deleteControlViews(mode); | |||
96 | } else { | |||
97 | // we can assume that everything went OK show ourselves on screen | |||
98 | Show(); | |||
99 | } | |||
100 | ||||
101 | if (Lock()) { | |||
102 | AddCommonFilter(new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, | |||
103 | B_MOUSE_DOWN, window_activation_filter)); | |||
104 | AddCommonFilter(new BMessageFilter(B_KEY_DOWN,AppKeyFilterFunction)); | |||
105 | Unlock(); | |||
106 | } | |||
107 | ||||
108 | palette_window = this; | |||
109 | FloaterManager::AddFloater(this); | |||
110 | } | |||
111 | ||||
112 | ||||
113 | ColorPaletteWindow::~ColorPaletteWindow() | |||
114 | { | |||
115 | delete open_panel; | |||
116 | delete save_panel; | |||
117 | ||||
118 | if (SettingsServer* server = SettingsServer::Instance()) { | |||
119 | server->SetValue(SettingsServer::Application, skPaletteWindowFrame, | |||
120 | Frame()); | |||
121 | server->SetValue(SettingsServer::Application, skPaletteWindowVisible, | |||
122 | false); | |||
123 | server->SetValue(SettingsServer::Application, skPaletteColorMode, | |||
124 | selector_mode); | |||
125 | } | |||
126 | ||||
127 | FloaterManager::RemoveFloater(this); | |||
128 | palette_window = NULL__null; | |||
129 | } | |||
130 | ||||
131 | ||||
132 | void ColorPaletteWindow::MessageReceived(BMessage *message) | |||
133 | { | |||
134 | // this path is used when getting the applications path to save | |||
135 | // the palettes. It must be defined here instead of inside the | |||
136 | // switch-clause | |||
137 | BPath path; | |||
138 | BMessage *color_message; | |||
139 | rgb_color color; | |||
140 | int32 buttons; | |||
141 | ||||
142 | switch (message->what) { | |||
143 | ||||
144 | // this comes from the HSColorControl object and indicates that it's value has changed | |||
145 | case HS_COLOR_CONTROL_INVOKED'CCIn': | |||
146 | // send message to each container | |||
147 | // message should contain the index of that color in color-set | |||
148 | // this should only be done if the color_container is in edit-mode | |||
149 | // and set the current color in the set for that color too | |||
150 | color_message = new BMessage(HS_COLOR_CHANGED'CoCH'); | |||
151 | color_message->AddInt32("index",ColorSet::currentSet()->currentColorIndex()); | |||
152 | // For some reason the alpha channel needs to be forced to 255 | |||
153 | color = color_control->ValueAsColor(); | |||
154 | color.alpha = 255; | |||
155 | ColorSet::currentSet()->setCurrentColor(color); | |||
156 | ColorContainer::sendMessageToAllContainers(color_message); | |||
157 | SelectedColorsView::sendMessageToAll(color_message); | |||
158 | ||||
159 | // also change the color for mousebutton that was used | |||
160 | message->FindInt32("buttons",&buttons); | |||
161 | if (buttons & B_PRIMARY_MOUSE_BUTTON) | |||
162 | ((PaintApplication*)be_app)->SetColor(color, TRUE1); | |||
163 | else | |||
164 | ((PaintApplication*)be_app)->SetColor(color, FALSE0); | |||
165 | ||||
166 | InformClients(ColorSet::currentSet()->currentColor()); | |||
167 | break; | |||
168 | ||||
169 | // This comes from the RGBControl-object and indicates that it's value has changed. | |||
170 | // This might also come from CMYControl, YIQControl ... | |||
171 | case HS_RGB_CONTROL_INVOKED'RGIn': | |||
172 | // send message to each container | |||
173 | // message should contain the index of that color in color-set | |||
174 | // this should only be done if the color_container is in edit-mode | |||
175 | // and set the current color in the set for that color too | |||
176 | color_message = new BMessage(HS_COLOR_CHANGED'CoCH'); | |||
177 | color_message->AddInt32("index",ColorSet::currentSet()->currentColorIndex()); | |||
178 | ColorSet::currentSet()->setCurrentColor(color_slider->ValueAsColor()); | |||
179 | ColorContainer::sendMessageToAllContainers(color_message); | |||
180 | SelectedColorsView::sendMessageToAll(color_message); | |||
181 | ||||
182 | // also change the color for mousebutton that was used | |||
183 | message->FindInt32("buttons",&buttons); | |||
184 | if (buttons & B_PRIMARY_MOUSE_BUTTON) | |||
185 | ((PaintApplication*)be_app)->SetColor(color_slider->ValueAsColor(),TRUE1); | |||
186 | else | |||
187 | ((PaintApplication*)be_app)->SetColor(color_slider->ValueAsColor(),FALSE0); | |||
188 | ||||
189 | InformClients(ColorSet::currentSet()->currentColor()); | |||
190 | break; | |||
191 | ||||
192 | // this comes from the menubar->"Set"->"New Palette"->"N" and indicates that a new | |||
193 | // palette-set should be created, the "colors"-parameter tells us how many colors the | |||
194 | // new set has | |||
195 | case HS_NEW_PALETTE_CREATED'NPaC': | |||
196 | new ColorSet(message->FindInt32("colors")); | |||
197 | // inform the color-containers about change | |||
198 | ColorContainer::sendMessageToAllContainers(new BMessage(HS_PALETTE_CHANGED'PaCh')); | |||
199 | // here change the name view to display sets name | |||
200 | if (ColorSet::numberOfSets() > 1) { | |||
201 | menu_bar->FindItem(HS_DELETE_PALETTE'DePa')->SetEnabled(TRUE1); | |||
202 | } | |||
203 | break; | |||
204 | ||||
205 | // this comes from the menubar->"Set"->"Delete Current Set" and indicates that the current | |||
206 | // set should be deleted | |||
207 | case HS_DELETE_PALETTE'DePa': | |||
208 | // check if there are any more sets left | |||
209 | if (ColorSet::numberOfSets() >= 2) { | |||
210 | // first delete ourselves | |||
211 | delete ColorSet::currentSet(); | |||
212 | // inform the color-containers about change | |||
213 | ColorContainer::sendMessageToAllContainers(new BMessage(HS_PALETTE_CHANGED'PaCh')); | |||
214 | // here change the name view to display sets name | |||
215 | if (ColorSet::numberOfSets() <= 1) { | |||
216 | menu_bar->FindItem(HS_DELETE_PALETTE'DePa')->SetEnabled(FALSE0); | |||
217 | } | |||
218 | } | |||
219 | else { | |||
220 | (new BAlert("", B_TRANSLATE("Cannot delete the only color set.")BLocaleRoster::Default()->GetCatalog()->GetString(("Cannot delete the only color set." ), "ColorPalette"), | |||
221 | B_TRANSLATE("OK")BLocaleRoster::Default()->GetCatalog()->GetString(("OK" ), "ColorPalette")))->Go(); | |||
222 | } | |||
223 | break; | |||
224 | ||||
225 | // this comes from a button that is named "next set button", the button is in this window | |||
226 | // the message indicates that we should change the colorcontainers to display next color set | |||
227 | case HS_NEXT_PALETTE'NxPl': | |||
228 | // change the entry in palette list | |||
229 | ColorSet::moveToNextSet(); | |||
230 | // inform all color-containers about palette-change | |||
231 | ColorContainer::sendMessageToAllContainers(new BMessage(HS_PALETTE_CHANGED'PaCh')); | |||
232 | break; | |||
233 | ||||
234 | // this comes from a button that is named "previous set button", the button is in this window | |||
235 | // the message indicates that we should change the colorcontainers to display previous color set | |||
236 | case HS_PREVIOUS_PALETTE'PrPl': | |||
237 | // change the entry in palette list | |||
238 | ColorSet::moveToPrevSet(); | |||
239 | // inform all color-containers about palette-change | |||
240 | ColorContainer::sendMessageToAllContainers(new BMessage(HS_PALETTE_CHANGED'PaCh')); | |||
241 | break; | |||
242 | ||||
243 | // this is sent from ColorContainer::MouseDown and it's purpose is to | |||
244 | // let us change the corresponding color to the color-controller also | |||
245 | case HS_PALETTE_SELECTION_CHANGED'PslC': | |||
246 | // update the color controller to display this new color | |||
247 | // only should do it if container is in edit mode | |||
248 | if (color_control != NULL__null) | |||
249 | color_control->SetValue(ColorSet::currentSet()->currentColor()); | |||
250 | if (color_slider != NULL__null) | |||
251 | color_slider->SetValue(ColorSet::currentSet()->currentColor()); | |||
252 | InformClients(ColorSet::currentSet()->currentColor()); | |||
253 | break; | |||
254 | ||||
255 | // this comes from the menubar->"Set"->"Open Set" and indicates that | |||
256 | // a file panel should be opened for the purpose of loading new set | |||
257 | case HS_SHOW_PALETTE_OPEN_PANEL'SpOp': | |||
258 | // here we must open the file-panel for loading | |||
259 | // here get the path for palette-files, should be made relative to apps directory | |||
260 | // or maybe remember the directory from last use | |||
261 | ||||
262 | if (open_panel == NULL__null) { | |||
263 | // here we get the home directory of the application | |||
264 | PaintApplication::HomeDirectory(path); | |||
265 | ||||
266 | // force normalization of the path to check validity | |||
267 | if (path.Append("Palette sets/",TRUE1) != B_OK((int)0)) { | |||
268 | PaintApplication::HomeDirectory(path); | |||
269 | } | |||
270 | ||||
271 | entry_ref ref; | |||
272 | get_ref_for_path(path.Path(), &ref); | |||
273 | ||||
274 | BMessenger target(this); | |||
275 | BMessage message(HS_PALETTE_OPEN_REFS'PaOr'); | |||
276 | open_panel = new BFilePanel(B_OPEN_PANEL, &target, &ref, | |||
277 | B_FILE_NODE, true, &message); | |||
278 | } | |||
279 | open_panel->Window()->SetTitle(B_TRANSLATE("ArtPaint: Open color set" B_UTF8_ELLIPSIS)BLocaleRoster::Default()->GetCatalog()->GetString(("ArtPaint: Open color set" "\xE2\x80\xA6"), "ColorPalette")); | |||
280 | set_filepanel_strings(open_panel); | |||
281 | open_panel->Show(); | |||
282 | break; | |||
283 | ||||
284 | // this comes from the menubar->"Set"->"Save Set" and indicates that | |||
285 | // a file panel should be opened for the purpose of saving current set | |||
286 | case HS_SHOW_PALETTE_SAVE_PANEL'SpSp': | |||
287 | // here we must open the file-panel for saving | |||
288 | if (save_panel == NULL__null) { | |||
289 | // get the home directory of the app | |||
290 | PaintApplication::HomeDirectory(path); | |||
291 | ||||
292 | // force normalization of the path to check validity | |||
293 | if (path.Append("Palette sets/",TRUE1) != B_OK((int)0)) { | |||
294 | PaintApplication::HomeDirectory(path); | |||
295 | } | |||
296 | // convert it to entry_ref | |||
297 | entry_ref ref; | |||
298 | get_ref_for_path(path.Path(), &ref); | |||
299 | ||||
300 | BMessenger target(this); | |||
301 | BMessage message(HS_PALETTE_SAVE_REFS'PaSr'); | |||
302 | save_panel = new BFilePanel(B_SAVE_PANEL, &target, &ref, 0, false, | |||
303 | &message); | |||
304 | } | |||
305 | save_panel->SetSaveText(ColorSet::currentSet()->getName()); | |||
306 | save_panel->Window()->SetTitle(B_TRANSLATE("ArtPaint: Open color set" B_UTF8_ELLIPSIS)BLocaleRoster::Default()->GetCatalog()->GetString(("ArtPaint: Open color set" "\xE2\x80\xA6"), "ColorPalette")); | |||
307 | set_filepanel_strings(save_panel); | |||
308 | save_panel->Show(); | |||
309 | break; | |||
310 | ||||
311 | // this comes from the open_panel or the applocation-object and includes refs for | |||
312 | // the palette-files that should be loaded | |||
313 | case HS_PALETTE_OPEN_REFS'PaOr': | |||
314 | handlePaletteLoad(message); | |||
315 | ||||
316 | // inform all color containers that palette has changed | |||
317 | ColorContainer::sendMessageToAllContainers(new BMessage(HS_PALETTE_CHANGED'PaCh')); | |||
318 | if (ColorSet::numberOfSets() > 1) { | |||
319 | menu_bar->FindItem(HS_DELETE_PALETTE'DePa')->SetEnabled(TRUE1); | |||
320 | } | |||
321 | break; | |||
322 | ||||
323 | // this comes from the save_panel and indicates that current set should be saved | |||
324 | // to the file that the "refs" indicate | |||
325 | case HS_PALETTE_SAVE_REFS'PaSr': | |||
326 | handlePaletteSave(message); | |||
327 | break; | |||
328 | ||||
329 | // this comes from the menubar->"Mode"->"RGB-Mode" and indicates that | |||
330 | // the color selector should be changed to a RGBControl, this is used | |||
331 | // also for other purposes than just a message-constant | |||
332 | case HS_RGB_COLOR_MODE: | |||
333 | if (selector_mode != HS_RGB_COLOR_MODE) { | |||
334 | deleteControlViews(selector_mode); | |||
335 | selector_mode = HS_RGB_COLOR_MODE; | |||
336 | openControlViews(HS_RGB_COLOR_MODE); | |||
337 | } | |||
338 | break; | |||
339 | ||||
340 | // this comes from the menubar->"Mode"->"CMY-Mode" and indicates that | |||
341 | // the color selector should be changed to a RGBControl, this is used | |||
342 | // also for other purposes than just a message-constant | |||
343 | case HS_CMY_COLOR_MODE: | |||
344 | if (selector_mode != HS_CMY_COLOR_MODE) { | |||
345 | deleteControlViews(selector_mode); | |||
346 | selector_mode = HS_CMY_COLOR_MODE; | |||
347 | openControlViews(HS_CMY_COLOR_MODE); | |||
348 | } | |||
349 | break; | |||
350 | ||||
351 | // this comes from the menubar->"Mode"->"YIQ-Mode" and indicates that | |||
352 | // the color selector should be changed to a RGBControl, this is used | |||
353 | // also for other purposes than just a message-constant | |||
354 | case HS_YIQ_COLOR_MODE: | |||
355 | if (selector_mode != HS_YIQ_COLOR_MODE) { | |||
356 | deleteControlViews(selector_mode); | |||
357 | selector_mode = HS_YIQ_COLOR_MODE; | |||
358 | openControlViews(HS_YIQ_COLOR_MODE); | |||
359 | } | |||
360 | break; | |||
361 | ||||
362 | // this comes from the menubar->"Mode"->"YUV-Mode" and indicates that | |||
363 | // the color selector should be changed to a RGBControl, this is used | |||
364 | // also for other purposes than just a message-constant | |||
365 | case HS_YUV_COLOR_MODE: | |||
366 | if (selector_mode != HS_YUV_COLOR_MODE) { | |||
367 | deleteControlViews(selector_mode); | |||
368 | selector_mode = HS_YUV_COLOR_MODE; | |||
369 | openControlViews(HS_YUV_COLOR_MODE); | |||
370 | } | |||
371 | break; | |||
372 | ||||
373 | case HS_HSV_COLOR_MODE: | |||
374 | if (selector_mode != HS_HSV_COLOR_MODE) { | |||
375 | deleteControlViews(selector_mode); | |||
376 | selector_mode = HS_HSV_COLOR_MODE; | |||
377 | openControlViews(HS_HSV_COLOR_MODE); | |||
378 | } | |||
379 | break; | |||
380 | ||||
381 | ||||
382 | // this comes from the menubar->"Mode"->"Simple-Mode" and indicates that | |||
383 | // the color selector should be changed to a HSColorControl, this is used | |||
384 | // also for other purposes than just a message-constant | |||
385 | case HS_SIMPLE_COLOR_MODE: | |||
386 | if (selector_mode != HS_SIMPLE_COLOR_MODE) { | |||
387 | deleteControlViews(selector_mode); | |||
388 | selector_mode = HS_SIMPLE_COLOR_MODE; | |||
389 | openControlViews(HS_SIMPLE_COLOR_MODE); | |||
390 | } | |||
391 | break; | |||
392 | ||||
393 | default: | |||
394 | BWindow::MessageReceived(message); | |||
395 | break; | |||
396 | } | |||
397 | } | |||
398 | ||||
399 | bool ColorPaletteWindow::QuitRequested() | |||
400 | { | |||
401 | // We might do something useful here. | |||
402 | return TRUE1; | |||
403 | } | |||
404 | ||||
405 | bool ColorPaletteWindow::openControlViews(int32 mode) | |||
406 | { | |||
407 | // first we open the views that are common to all modes of color palette | |||
408 | // at least the menubar and the color-set container and controls that can change | |||
409 | // the color-set or its name | |||
410 | ||||
411 | // these variables are used to position the views correctly | |||
412 | float top , left; | |||
413 | ||||
414 | // update the top to be under menu_bar | |||
415 | top = menu_bar->Frame().Height() + 1; | |||
416 | ||||
417 | box1 = new BBox(BRect(0,top,0,top)); | |||
418 | box1->SetBorder(B_PLAIN_BORDER); | |||
419 | // here open the color_container | |||
420 | color_container = new ColorContainer(BRect(0,3,63,66),ColorSet::currentSet()->sizeOfSet()); | |||
421 | color_container->SetDraggingEnabled(TRUE1); | |||
422 | box1->AddChild(color_container); | |||
423 | ||||
424 | // update the top to be under container in the box1 coordinates that is | |||
425 | top = color_container->Frame().bottom + 4; | |||
426 | ||||
427 | // Here add the buttons that control the color-set. | |||
428 | ResourceServer* server = ResourceServer::Instance(); | |||
429 | if (server) { | |||
430 | BPicture arrow_pushed; | |||
431 | BPicture arrow_not_pushed; | |||
432 | ||||
433 | server->GetPicture(LEFT_ARROW, &arrow_not_pushed); | |||
434 | server->GetPicture(LEFT_ARROW_PUSHED, &arrow_pushed); | |||
435 | ||||
436 | previous_set = new BPictureButton(BRect(3, top, 11, top + 12), | |||
437 | "left_arrow", &arrow_not_pushed, &arrow_pushed, | |||
438 | new BMessage(HS_PREVIOUS_PALETTE'PrPl')); | |||
439 | box1->AddChild(previous_set); | |||
440 | previous_set->SetTarget(this); | |||
441 | previous_set->ResizeToPreferred(); | |||
442 | ||||
443 | server->GetPicture(RIGHT_ARROW, &arrow_not_pushed); | |||
444 | server->GetPicture(RIGHT_ARROW_PUSHED, &arrow_pushed); | |||
445 | ||||
446 | next_set = new BPictureButton(previous_set->Frame(), "right arrow", | |||
447 | &arrow_not_pushed, &arrow_pushed, new BMessage(HS_NEXT_PALETTE'NxPl')); | |||
448 | box1->AddChild(next_set); | |||
449 | next_set->SetTarget(this); | |||
450 | next_set->ResizeToPreferred(); | |||
451 | next_set->MoveBy(next_set->Frame().Width() + 3,0); | |||
452 | } | |||
453 | ||||
454 | // here resize the box1 to appropriate size | |||
455 | box1->ResizeTo(max_c(next_set->Frame().right + 20,color_container->Frame().Width()+6)((next_set->Frame().right + 20)>(color_container->Frame ().Width()+6)?(next_set->Frame().right + 20):(color_container ->Frame().Width()+6)),next_set->Frame().bottom+3); | |||
456 | ||||
457 | // here center the views horizontally | |||
458 | color_container->MoveBy((box1->Frame().Width() - color_container->Frame().Width())/2,0); | |||
459 | ||||
460 | AddChild(box1); | |||
461 | left = box1->Frame().right + 1; | |||
462 | top = menu_bar->Frame().Height() + 1; | |||
463 | ||||
464 | // this will be assigned to RGBControl or similar object | |||
465 | BMessage *invocation_message; | |||
466 | // here we open the views that show color controls e.g. RGB- or HSV-controls | |||
467 | switch (mode) { | |||
468 | ||||
469 | // in this case just open a HSColorControl and color-set container | |||
470 | case HS_SIMPLE_COLOR_MODE: | |||
471 | box2 = new BBox(BRect(box1->Frame().right+1,top,box1->Frame().right+10,box1->Frame().bottom)); | |||
472 | color_control = new HSColorControl(BPoint(5,0),B_CELLS_32x8,8,""); | |||
473 | color_control->SetTarget(this); | |||
474 | box2->ResizeTo(color_control->Frame().Width()+10,box2->Frame().Height()); | |||
475 | ||||
476 | ResizeTo(box2->Frame().right,max_c(box1->Frame().Height() + top-1,color_control->Frame().Height() + top)((box1->Frame().Height() + top-1)>(color_control->Frame ().Height() + top)?(box1->Frame().Height() + top-1):(color_control ->Frame().Height() + top))); | |||
477 | box2->AddChild(color_control); | |||
478 | AddChild(box2); | |||
479 | // here center the color control vertically | |||
480 | color_control->MoveBy(0,(box2->Frame().Height() - color_control->Frame().Height())/2); | |||
481 | break; | |||
482 | ||||
483 | // in this case open an RGBControl | |||
484 | case HS_RGB_COLOR_MODE: case HS_CMY_COLOR_MODE: case HS_YIQ_COLOR_MODE: case HS_YUV_COLOR_MODE: | |||
485 | case HS_HSV_COLOR_MODE: | |||
486 | box2 = new BBox(BRect(box1->Frame().right+1,top,box1->Frame().right+10,box1->Frame().bottom)); | |||
487 | ||||
488 | if (mode == HS_RGB_COLOR_MODE) { | |||
489 | rgb_color c = {0,0,0,255}; | |||
490 | color_slider = new RGBControl(BPoint(5,0),c); | |||
491 | } | |||
492 | else if (mode == HS_CMY_COLOR_MODE) { | |||
493 | rgb_color c = {255,255,255,255}; | |||
494 | color_slider = new CMYControl(BPoint(5,0),c); | |||
495 | } | |||
496 | else if (mode == HS_YIQ_COLOR_MODE) { | |||
497 | rgb_color c = {255,255,255,255}; | |||
498 | color_slider = new YIQControl(BPoint(5,0),c); | |||
499 | } | |||
500 | else if (mode == HS_YUV_COLOR_MODE) { | |||
501 | rgb_color c = {255,255,255,255}; | |||
502 | color_slider = new YUVControl(BPoint(5,0),c); | |||
503 | } | |||
504 | else if (mode == HS_HSV_COLOR_MODE) { | |||
505 | rgb_color c = {255,255,255,255}; | |||
506 | color_slider = new HSVControl(BPoint(5,0),c); | |||
507 | } | |||
508 | box2->AddChild(color_slider); | |||
509 | AddChild(box2); | |||
510 | ||||
511 | color_slider->SetTarget(this); | |||
512 | box2->ResizeTo(color_slider->Frame().Width()+10,box2->Frame().Height()); | |||
513 | ResizeTo(box2->Frame().right,max_c(box1->Frame().Height() +((box1->Frame().Height() + top-1)>(color_slider->Frame ().Height() + top)?(box1->Frame().Height() + top-1):(color_slider ->Frame().Height() + top)) | |||
514 | top-1,color_slider->Frame().Height() + top)((box1->Frame().Height() + top-1)>(color_slider->Frame ().Height() + top)?(box1->Frame().Height() + top-1):(color_slider ->Frame().Height() + top))); | |||
515 | ||||
516 | // here center the color control vertically | |||
517 | color_slider->MoveBy(0,(box2->Frame().Height() - | |||
518 | color_slider->Frame().Height())/2); | |||
519 | invocation_message = new BMessage(HS_RGB_CONTROL_INVOKED'RGIn'); | |||
520 | invocation_message->AddInt32("buttons",0); | |||
521 | color_slider->SetMessage(invocation_message); | |||
522 | break; | |||
523 | ||||
524 | default: | |||
525 | return TRUE1; | |||
526 | } | |||
527 | box2->SetBorder(B_PLAIN_BORDER); | |||
528 | ||||
529 | // Update the color-controllers and slider's values | |||
530 | if (color_control != NULL__null) | |||
531 | color_control->SetValue(ColorSet::currentSet()->currentColor()); | |||
532 | if (color_slider != NULL__null) | |||
533 | color_slider->SetValue(ColorSet::currentSet()->currentColor()); | |||
534 | ||||
535 | return TRUE1; | |||
536 | } | |||
537 | ||||
538 | ||||
539 | ||||
540 | void ColorPaletteWindow::deleteControlViews(int32) | |||
541 | { | |||
542 | // here we delete all views that are not NULL | |||
543 | box1->RemoveSelf(); | |||
544 | delete box1; | |||
545 | ||||
546 | box2->RemoveSelf(); | |||
547 | delete box2; | |||
548 | ||||
549 | // NULL all the controls | |||
550 | color_control = NULL__null; | |||
551 | color_slider = NULL__null; | |||
552 | } | |||
553 | ||||
554 | ||||
555 | void ColorPaletteWindow::openMenuBar() | |||
556 | { | |||
557 | BMenu *menu; | |||
558 | BMenu *sub_menu; | |||
559 | BMenuItem *menu_item; | |||
560 | ||||
561 | menu_bar = new BMenuBar(BRect(0,0,0,0),"menu bar"); | |||
562 | menu = new BMenu(B_TRANSLATE("Color set")BLocaleRoster::Default()->GetCatalog()->GetString(("Color set" ), "ColorPalette")); | |||
563 | menu_bar->AddItem(menu); | |||
564 | ||||
565 | sub_menu = new BMenu(B_TRANSLATE("New color set")BLocaleRoster::Default()->GetCatalog()->GetString(("New color set" ), "ColorPalette")); | |||
566 | ||||
567 | // in this loop we add possible palette sizes to menu | |||
568 | BMessage *msg; | |||
569 | char item_title[20] = ""; | |||
570 | for (int32 i = 3; i <= 6; i++) { | |||
571 | sprintf(item_title, "%ld %s",((int32)pow(2, i)), | |||
572 | B_TRANSLATE("Colors")BLocaleRoster::Default()->GetCatalog()->GetString(("Colors" ), "ColorPalette")); | |||
573 | msg = new BMessage(HS_NEW_PALETTE_CREATED'NPaC'); | |||
574 | msg->AddInt32("colors", ((int32)pow(2, i))); | |||
575 | menu_item = new BMenuItem(item_title, msg); | |||
576 | sub_menu->AddItem(menu_item); | |||
577 | } | |||
578 | // the palette window will handle all things that concern making | |||
579 | // or loading new palette | |||
580 | sub_menu->SetTargetForItems(this); | |||
581 | menu->AddItem(sub_menu); | |||
582 | ||||
583 | menu_item = new BMenuItem(B_TRANSLATE("Delete current set")BLocaleRoster::Default()->GetCatalog()->GetString(("Delete current set" ), "ColorPalette"), | |||
584 | new BMessage(HS_DELETE_PALETTE'DePa')); | |||
585 | menu_item->SetTarget(this); | |||
586 | menu->AddItem(menu_item); | |||
587 | if (ColorSet::numberOfSets() <= 1) { | |||
588 | menu_item->SetEnabled(FALSE0); | |||
589 | } | |||
590 | ||||
591 | menu->AddItem(new BSeparatorItem()); | |||
592 | menu_item = new BMenuItem(B_TRANSLATE("Open color set" B_UTF8_ELLIPSIS)BLocaleRoster::Default()->GetCatalog()->GetString(("Open color set" "\xE2\x80\xA6"), "ColorPalette"), | |||
593 | new BMessage(HS_SHOW_PALETTE_OPEN_PANEL'SpOp')); | |||
594 | menu_item->SetTarget(this); | |||
595 | menu->AddItem(menu_item); | |||
596 | menu_item = new BMenuItem(B_TRANSLATE("Save color set")BLocaleRoster::Default()->GetCatalog()->GetString(("Save color set" ), "ColorPalette"), | |||
597 | new BMessage(HS_SHOW_PALETTE_SAVE_PANEL'SpSp')); | |||
598 | menu_item->SetTarget(this); | |||
599 | menu->AddItem(menu_item); | |||
600 | ||||
601 | menu = new BMenu(B_TRANSLATE("Color model")BLocaleRoster::Default()->GetCatalog()->GetString(("Color model" ), "ColorPalette")); | |||
602 | menu_bar->AddItem(menu); | |||
603 | ||||
604 | char string[256]; | |||
605 | sprintf(string,"RGB"); | |||
606 | menu_item = new BMenuItem(string,new BMessage(HS_RGB_COLOR_MODE)); | |||
607 | menu_item->SetTarget(this); | |||
608 | menu->AddItem(menu_item); | |||
609 | sprintf(string,"CMY"); | |||
610 | menu_item = new BMenuItem(string,new BMessage(HS_CMY_COLOR_MODE)); | |||
611 | menu_item->SetTarget(this); | |||
612 | menu->AddItem(menu_item); | |||
613 | sprintf(string,"HSV"); | |||
614 | menu_item = new BMenuItem(string,new BMessage(HS_HSV_COLOR_MODE)); | |||
615 | menu_item->SetTarget(this); | |||
616 | menu->AddItem(menu_item); | |||
617 | sprintf(string,"YIQ"); | |||
618 | menu_item = new BMenuItem(string,new BMessage(HS_YIQ_COLOR_MODE)); | |||
619 | menu_item->SetTarget(this); | |||
620 | menu->AddItem(menu_item); | |||
621 | sprintf(string,"YUV"); | |||
622 | menu_item = new BMenuItem(string,new BMessage(HS_YUV_COLOR_MODE)); | |||
623 | menu_item->SetTarget(this); | |||
624 | menu->AddItem(menu_item); | |||
625 | sprintf(string,"BeOS"); | |||
626 | menu_item = new BMenuItem(string,new BMessage(HS_SIMPLE_COLOR_MODE)); | |||
627 | menu_item->SetTarget(this); | |||
628 | menu->AddItem(menu_item); | |||
629 | menu->SetRadioMode(TRUE1); | |||
630 | menu->FindItem(selector_mode)->SetMarked(TRUE1); | |||
631 | ||||
632 | AddChild(menu_bar); | |||
633 | } | |||
634 | ||||
635 | void ColorPaletteWindow::handlePaletteLoad(BMessage *message) | |||
636 | { | |||
637 | // here check for file type and possibly load it to memory | |||
638 | uint32 type; | |||
639 | int32 count; | |||
640 | entry_ref ref; | |||
641 | ||||
642 | // this holds the bytes that were read | |||
643 | ssize_t bytes_read; | |||
644 | ||||
645 | // this will hold the identification string, they are not longer than 256 chars | |||
646 | char file_type[256]; | |||
647 | ||||
648 | ||||
649 | // we can probably assume that the ref is actually a file | |||
650 | message->GetInfo("refs", &type, &count); | |||
651 | if ( type != B_REF_TYPE ) | |||
652 | return; | |||
653 | ||||
654 | for ( long i = --count; i >= 0; i-- ) { | |||
655 | if ( message->FindRef("refs", i, &ref) == B_OK((int)0) ) { | |||
656 | BFile file; | |||
657 | if ( file.SetTo(&ref, B_READ_ONLY0x0000) == B_OK((int)0) ) { | |||
658 | // the file was succesfully opened | |||
659 | // here we check that it is actually a palette file | |||
660 | // and read it if it is and also generate a new palette to | |||
661 | // list of palettes | |||
662 | if ((bytes_read = file.Read(file_type,strlen(HS_PALETTE_ID_STRING"ArtPaint color set"))) < 0) { | |||
663 | // here some error reading file has happened | |||
664 | (new BAlert("",B_TRANSLATE("Error reading file")BLocaleRoster::Default()->GetCatalog()->GetString(("Error reading file" ), "ColorPalette"),B_TRANSLATE("OK")BLocaleRoster::Default()->GetCatalog()->GetString(("OK" ), "ColorPalette")))->Go(); | |||
665 | } | |||
666 | else { | |||
667 | // the read was succesfull, terminate the id string and compare | |||
668 | file_type[bytes_read] = '\0'; | |||
669 | if (strcmp(file_type,HS_PALETTE_ID_STRING"ArtPaint color set") != 0) { | |||
670 | // this was not a palette file | |||
671 | (new BAlert("",B_TRANSLATE("Not a color set file")BLocaleRoster::Default()->GetCatalog()->GetString(("Not a color set file" ), "ColorPalette"),B_TRANSLATE("OK")BLocaleRoster::Default()->GetCatalog()->GetString(("OK" ), "ColorPalette")))->Go(); | |||
672 | } | |||
673 | else { | |||
674 | // this was palette file, read the rest of it | |||
675 | int32 palette_size; | |||
676 | if ((bytes_read = file.Read(&palette_size,sizeof(int32))) != sizeof(int32)) { | |||
677 | // here some error reading file has happened | |||
678 | (new BAlert("",B_TRANSLATE("File structure corrupted")BLocaleRoster::Default()->GetCatalog()->GetString(("File structure corrupted" ), "ColorPalette"), | |||
679 | B_TRANSLATE("OK")BLocaleRoster::Default()->GetCatalog()->GetString(("OK" ), "ColorPalette")))->Go(); | |||
680 | } | |||
681 | else { | |||
682 | // create the palette and read the palette colors | |||
683 | ColorSet *loaded_set = new ColorSet(palette_size); | |||
684 | rgb_color loaded_color; | |||
685 | ||||
686 | // here is the loop that reads palette entries from file | |||
687 | for (int32 i = 0; i < palette_size; i++) { | |||
688 | file.Read(&loaded_color,sizeof(rgb_color)); | |||
689 | loaded_set->setColor(i,loaded_color); | |||
690 | } | |||
691 | // this array holds the palette-name | |||
692 | char palette_name[256]; | |||
693 | // read as many bytes as there is left to be the palette name | |||
694 | bytes_read = file.Read(palette_name,255); | |||
695 | palette_name[bytes_read] = '\0'; | |||
696 | loaded_set->setName(palette_name); | |||
697 | } | |||
698 | ||||
699 | } | |||
700 | } | |||
701 | } | |||
702 | } | |||
703 | } | |||
704 | } | |||
705 | ||||
706 | ||||
707 | void ColorPaletteWindow::handlePaletteSave(BMessage *message) | |||
708 | { | |||
709 | uint32 type; | |||
710 | int32 count; | |||
711 | entry_ref ref; | |||
712 | ||||
713 | // we can probably assume that the ref is actually a file | |||
714 | message->GetInfo("directory", &type, &count); | |||
715 | if ( type != B_REF_TYPE ) { | |||
716 | return; | |||
717 | } | |||
718 | // here take a pointer to current color-set, so that if current set is changed | |||
719 | // this will still save the same set | |||
720 | ColorSet *color_set = ColorSet::currentSet(); | |||
721 | ||||
722 | for ( long i = --count; i >= 0; i-- ) { | |||
723 | if ( message->FindRef("directory", i, &ref) == B_OK((int)0) ) { | |||
724 | BFile file; | |||
725 | BDirectory directory = BDirectory(&ref); | |||
726 | if ( file.SetTo(&directory,message->FindString("name",i), | |||
727 | B_READ_WRITE0x0002 | B_CREATE_FILE0x0200 | B_ERASE_FILE0x0400) == B_OK((int)0) ) { | |||
728 | // here we write the current color-set to file | |||
729 | // first set the file's type and other metadata | |||
730 | // get the applications signature | |||
731 | app_info info; | |||
732 | be_app->GetAppInfo(&info); | |||
733 | ||||
734 | BNodeInfo node(&file); | |||
735 | node.SetType(HS_PALETTE_MIME_STRING"application/x-vnd.artpaint-palette-file"); | |||
736 | node.SetPreferredApp(info.signature); | |||
737 | ||||
738 | if (file.Write(HS_PALETTE_ID_STRING"ArtPaint color set",strlen(HS_PALETTE_ID_STRING"ArtPaint color set")) < 0) { | |||
739 | // error happened | |||
740 | (new BAlert("",B_TRANSLATE("Cannot write to file")BLocaleRoster::Default()->GetCatalog()->GetString(("Cannot write to file" ), "ColorPalette"),B_TRANSLATE("OK")BLocaleRoster::Default()->GetCatalog()->GetString(("OK" ), "ColorPalette")))->Go(); | |||
741 | } | |||
742 | else { | |||
743 | // write the rest of the file | |||
744 | int32 size = color_set->sizeOfSet(); | |||
745 | file.Write(&size,sizeof(int32)); | |||
746 | ||||
747 | // this loop writes the color entries | |||
748 | for (int32 i=0;i<size;i++) { | |||
749 | rgb_color c = color_set->colorAt(i); | |||
750 | file.Write(&c,sizeof(rgb_color)); | |||
751 | } | |||
752 | ||||
753 | // finally write the name of set | |||
754 | file.Write(color_set->getName(),strlen(color_set->getName())); | |||
755 | } | |||
756 | } | |||
757 | } | |||
758 | } | |||
759 | } | |||
760 | ||||
761 | ||||
762 | void | |||
763 | ColorPaletteWindow::showPaletteWindow(BMessage *msg) | |||
764 | { | |||
765 | if (palette_window == NULL__null) { | |||
766 | BRect frame(300, 100, 400, 200); | |||
767 | color_window_modes mode = HS_RGB_COLOR_MODE; | |||
768 | ||||
769 | if (SettingsServer* server = SettingsServer::Instance()) { | |||
770 | BMessage settings; | |||
771 | server->GetApplicationSettings(&settings); | |||
772 | settings.FindRect(skPaletteWindowFrame, &frame); | |||
773 | settings.FindInt32(skPaletteColorMode, (int32*)&mode); | |||
774 | } | |||
775 | ||||
776 | ColorPaletteWindow* window = new ColorPaletteWindow(frame, mode); | |||
777 | for (int32 i = 0; i < master_window_list->CountItems(); ++i) | |||
778 | ((BWindow*)master_window_list->ItemAt(i))->AddToSubset(window); | |||
779 | } else { | |||
780 | if (palette_window->Lock()) { | |||
781 | palette_window->SetWorkspaces(B_CURRENT_WORKSPACE0); | |||
782 | if (palette_window->IsHidden()) | |||
783 | palette_window->Show(); | |||
784 | ||||
785 | if (!palette_window->IsActive()) | |||
786 | palette_window->Activate(TRUE1); | |||
787 | ||||
788 | palette_window->Unlock(); | |||
789 | } | |||
790 | } | |||
791 | ||||
792 | if (palette_window->Lock()) { | |||
793 | BRect palette_window_frame = palette_window->Frame(); | |||
794 | palette_window_frame = FitRectToScreen(palette_window_frame); | |||
795 | palette_window->MoveTo(palette_window_frame.LeftTop()); | |||
796 | palette_window->Unlock(); | |||
797 | } | |||
798 | ||||
799 | // If we got a message we should try to use it for loading a palette. | |||
800 | if (msg) | |||
801 | palette_window->handlePaletteLoad(msg); | |||
802 | } | |||
803 | ||||
804 | ||||
805 | void | |||
806 | ColorPaletteWindow::ChangePaletteColor(rgb_color& c) | |||
807 | { | |||
808 | if (palette_window != NULL__null) { | |||
809 | palette_window->Lock(); | |||
810 | ||||
811 | if (palette_window->color_control != NULL__null) | |||
812 | palette_window->color_control->SetValue(c); | |||
813 | if (palette_window->color_slider != NULL__null) | |||
814 | palette_window->color_slider->SetValue(c); | |||
815 | ||||
816 | palette_window->Unlock(); | |||
817 | } | |||
818 | } | |||
819 | ||||
820 | ||||
821 | void | |||
822 | ColorPaletteWindow::setFeel(window_feel feel) | |||
823 | { | |||
824 | if (SettingsServer* server = SettingsServer::Instance()) { | |||
825 | server->SetValue(SettingsServer::Application, skPaletteWindowFeel, | |||
826 | int32(feel)); | |||
827 | } | |||
828 | ||||
829 | if (palette_window) { | |||
830 | window_look look = B_FLOATING_WINDOW_LOOK; | |||
831 | if (feel == B_NORMAL_WINDOW_FEEL) | |||
832 | look = B_TITLED_WINDOW_LOOK; | |||
833 | ||||
834 | palette_window->SetFeel(feel); | |||
835 | palette_window->SetLook(look); | |||
836 | } | |||
837 | } | |||
838 | ||||
839 | ||||
840 | void | |||
841 | ColorPaletteWindow::AddMasterWindow(BWindow *window) | |||
842 | { | |||
843 | master_window_list->AddItem(window); | |||
844 | if (palette_window) | |||
845 | window->AddToSubset(palette_window); | |||
846 | } | |||
847 | ||||
848 | ||||
849 | void | |||
850 | ColorPaletteWindow::RemoveMasterWindow(BWindow *window) | |||
851 | { | |||
852 | master_window_list->RemoveItem(window); | |||
853 | } | |||
854 | ||||
855 | ||||
856 | ||||
857 | void | |||
858 | ColorPaletteWindow::AddPaletteWindowClient(PaletteWindowClient *client) | |||
859 | { | |||
860 | if (!palette_window_clients->HasItem(client)) | |||
861 | palette_window_clients->AddItem(client); | |||
862 | } | |||
863 | ||||
864 | ||||
865 | void | |||
866 | ColorPaletteWindow::RemovePaletteWindowClient(PaletteWindowClient *client) | |||
867 | { | |||
868 | palette_window_clients->RemoveItem(client); | |||
869 | } | |||
870 | ||||
871 | ||||
872 | void | |||
873 | ColorPaletteWindow::InformClients(const rgb_color& c) | |||
874 | { | |||
875 | for (int32 i = 0; i < palette_window_clients->CountItems(); ++i) { | |||
876 | PaletteWindowClient* client = | |||
877 | static_cast<PaletteWindowClient*>(palette_window_clients->ItemAt(i)); | |||
878 | if (client) | |||
879 | client->PaletteColorChanged(c); | |||
880 | } | |||
881 | } | |||
882 | ||||
883 | ||||
884 | // here is the definition of HSColorControl-class | |||
885 | HSColorControl::HSColorControl(BPoint location, color_control_layout matrix, | |||
886 | float cellSide, const char *name) | |||
887 | : BColorControl(location, matrix, cellSide, name) | |||
888 | { | |||
889 | // Set the message here so that using the text boxes before the sliders will work | |||
890 | BMessage *message = new BMessage(HS_COLOR_CONTROL_INVOKED'CCIn'); | |||
891 | message->AddInt32("buttons", B_PRIMARY_MOUSE_BUTTON); | |||
892 | SetMessage(message); | |||
893 | } | |||
894 | ||||
895 | void HSColorControl::MouseDown(BPoint location) | |||
896 | { | |||
897 | // here we take the button that was pressed | |||
898 | int32 buttons = 0; | |||
899 | Window()->CurrentMessage()->FindInt32("buttons", &buttons); | |||
900 | ||||
901 | // set the invokers message to contain the mouse-button that was last pressed | |||
902 | BMessage *message = new BMessage(HS_COLOR_CONTROL_INVOKED'CCIn'); | |||
903 | message->AddInt32("buttons",buttons); | |||
904 | SetMessage(message); | |||
905 | ||||
906 | // call the inherited MouseDown-function | |||
907 | BColorControl::MouseDown(location); | |||
908 | } | |||
909 | ||||
910 | ||||
911 | ||||
912 | ||||
913 | // here starts the definitions for ColorContainer class | |||
914 | ||||
915 | // here define the variable that points to list of color containers | |||
916 | BList* ColorContainer::container_list = new BList(); | |||
917 | ||||
918 | ||||
919 | ColorContainer::ColorContainer(BRect frame, int32 amount_of_colors, uint32 resizingMode, bool highlight,bool add_arrows) | |||
920 | : BView(frame,"color container",resizingMode,B_WILL_DRAW) | |||
921 | { | |||
922 | // here initialize the important variables | |||
923 | ||||
924 | highlight_selected = highlight; | |||
925 | left_arrow = NULL__null; | |||
926 | right_arrow = NULL__null; | |||
927 | contains_arrows = FALSE0; | |||
928 | ||||
929 | setUpContainer(frame,amount_of_colors,add_arrows); | |||
930 | ||||
931 | // add this container to the list | |||
932 | container_list->AddItem(this); | |||
933 | ||||
934 | dragging_enabled = FALSE0; | |||
935 | } | |||
936 | ||||
937 | ||||
938 | ||||
939 | ColorContainer::~ColorContainer() | |||
940 | { | |||
941 | // here remove ourselves from container list | |||
942 | container_list->RemoveItem(this); | |||
943 | } | |||
944 | ||||
945 | ||||
946 | void ColorContainer::AttachedToWindow() | |||
947 | { | |||
948 | BView::AttachedToWindow(); | |||
949 | if (Parent() != NULL__null) | |||
950 | SetViewColor(Parent()->ViewColor()); | |||
951 | ||||
952 | if (left_arrow != NULL__null) | |||
953 | left_arrow->SetTarget(this); | |||
954 | if (right_arrow != NULL__null) | |||
955 | right_arrow->SetTarget(this); | |||
956 | } | |||
957 | ||||
958 | void ColorContainer::Draw(BRect) | |||
959 | { | |||
960 | // here we draw the colors with FillRect | |||
961 | // we get the colors from palette that is held somewhere | |||
962 | // every instance of this class should also draw whenever | |||
963 | // a palette entry changes, how should we achieve that ???? | |||
964 | ||||
965 | BRect rect; | |||
966 | ||||
967 | for (int32 i=0;i<color_count;i++) { | |||
968 | ||||
969 | rect = colorBounds(i); | |||
970 | SetHighAndLowColors(ColorSet::currentSet()->colorAt(i)); | |||
971 | FillRect(rect,HS_2X2_BLOCKS); | |||
972 | } | |||
973 | ||||
974 | if (highlight_selected) { | |||
975 | // also draw the rectangle around selected color if required | |||
976 | SetHighColor(255,255,255,255); | |||
977 | StrokeRect(colorBounds(ColorSet::currentSet()->currentColorIndex())); | |||
978 | } | |||
979 | } | |||
980 | ||||
981 | ||||
982 | ||||
983 | void ColorContainer::MouseDown(BPoint point) | |||
984 | { | |||
985 | // here we highlight the color that is under the cursor | |||
986 | // and when we have selected the color we inform some | |||
987 | // third parties about that | |||
988 | uint32 buttons = 0; | |||
989 | uint32 original_button; | |||
990 | ||||
991 | GetMouse(&point, &buttons, true); | |||
992 | int32 index,prev_index = ColorSet::currentSet()->currentColorIndex(); | |||
993 | ||||
994 | // first draw the rectangle around the newly selected color | |||
995 | index = pointIndex(point); | |||
996 | if (index != -1) { | |||
997 | // only of course if some color was actually selected | |||
998 | SetHighColor(255,255,255); | |||
999 | StrokeRect(colorBounds(index)); | |||
1000 | } | |||
1001 | ||||
1002 | original_button = buttons; | |||
1003 | ||||
1004 | if (dragging_enabled == FALSE0) { | |||
1005 | while ( buttons ) { | |||
1006 | index = pointIndex(point); | |||
1007 | if ((index != -1) && (index != prev_index)) { | |||
1008 | // point is over some new color-entry | |||
1009 | if (prev_index != -1) { | |||
1010 | // re-draw the previous rectangle | |||
1011 | SetHighAndLowColors(ColorSet::currentSet()->colorAt(prev_index)); | |||
1012 | FillRect(colorBounds(prev_index),HS_2X2_BLOCKS); | |||
1013 | } | |||
1014 | // then draw rect around new color | |||
1015 | SetHighColor(255,255,255); | |||
1016 | StrokeRect(colorBounds(index)); | |||
1017 | } | |||
1018 | else if ((index == -1) && (prev_index != -1)) { | |||
1019 | // we fill the previous rectangle | |||
1020 | SetHighColor(ColorSet::currentSet()->colorAt(prev_index)); | |||
1021 | FillRect(colorBounds(prev_index)); | |||
1022 | } | |||
1023 | ||||
1024 | prev_index = index; | |||
1025 | snooze(20 * 1000); | |||
1026 | GetMouse(&point, &buttons, true); | |||
1027 | } | |||
1028 | } | |||
1029 | else if (index >= 0) { | |||
1030 | float distance = 0; | |||
1031 | BPoint original_point = point; | |||
1032 | while ((distance < 6) && (buttons)) { | |||
1033 | GetMouse(&point,&buttons); | |||
1034 | snooze(20 * 1000); | |||
1035 | distance = fabs(original_point.x-point.x) + fabs(original_point.y-point.y); | |||
1036 | } | |||
1037 | ||||
1038 | if ((distance >= 6) && buttons) { | |||
1039 | // Start a drag'n'drop session. | |||
1040 | BBitmap *dragged_map = new BBitmap(BRect(0,0,15,15),B_RGB32,TRUE1); | |||
1041 | BView *dragger_view = new BView(BRect(0,0,15,15),"dragger_view",B_FOLLOW_NONE0,B_WILL_DRAW); | |||
1042 | rgb_color c = ColorSet::currentSet()->colorAt(index); | |||
1043 | dragged_map->AddChild(dragger_view); | |||
1044 | dragged_map->Lock(); | |||
1045 | float alpha = c.alpha; | |||
1046 | c.alpha = 127; | |||
1047 | dragger_view->SetHighColor(c); | |||
1048 | c.alpha = (uint8)alpha; | |||
1049 | dragger_view->FillRect(dragger_view->Bounds()); | |||
1050 | dragger_view->Sync(); | |||
1051 | dragged_map->Unlock(); | |||
1052 | BMessage dragger_message(B_PASTE); | |||
1053 | dragger_message.AddData("RGBColor",B_RGB_COLOR_TYPE,&c,sizeof(rgb_color)); | |||
1054 | DragMessage(&dragger_message,dragged_map,B_OP_ALPHA,BPoint(7,7)); | |||
1055 | // dragged = TRUE; | |||
1056 | index = ColorSet::currentSet()->currentColorIndex(); // The active color did not change. | |||
1057 | } | |||
1058 | } | |||
1059 | ||||
1060 | if (index != -1) { | |||
1061 | // here we should make the current_color_index in active set to be index | |||
1062 | ColorSet::currentSet()->setCurrentColorIndex(index); | |||
1063 | ||||
1064 | // here we should inform the app that a color has been changed | |||
1065 | if (original_button & B_PRIMARY_MOUSE_BUTTON) | |||
1066 | ((PaintApplication*)be_app)->SetColor(ColorSet::currentSet()->currentColor(),TRUE1); | |||
1067 | else | |||
1068 | ((PaintApplication*)be_app)->SetColor(ColorSet::currentSet()->currentColor(),FALSE0); | |||
1069 | ||||
1070 | // we must also inform all other containers that the selection changed | |||
1071 | // so that they can highlight the proper rectangle, this will be done | |||
1072 | // with messages | |||
1073 | sendMessageToAllContainers(new BMessage(HS_PALETTE_SELECTION_CHANGED'PslC')); | |||
1074 | ||||
1075 | // also inform the selected colors' views | |||
1076 | SelectedColorsView::sendMessageToAll(new BMessage(HS_COLOR_CHANGED'CoCH')); | |||
1077 | ||||
1078 | ||||
1079 | ||||
1080 | // give the window the information that selection has changed | |||
1081 | rgb_color c = ColorSet::currentSet()->currentColor(); | |||
1082 | ColorPaletteWindow::ChangePaletteColor(c); | |||
1083 | Window()->PostMessage(HS_PALETTE_SELECTION_CHANGED'PslC',Window()); | |||
1084 | } | |||
1085 | else { | |||
1086 | SetHighColor(255,255,255); | |||
1087 | StrokeRect(colorBounds(ColorSet::currentSet()->currentColorIndex())); | |||
1088 | } | |||
1089 | ||||
1090 | if (!highlight_selected) { | |||
1091 | // clear the highlight from selected color | |||
1092 | SetHighAndLowColors(ColorSet::currentSet()->currentColor()); | |||
1093 | FillRect(colorBounds(ColorSet::currentSet()->currentColorIndex()), | |||
1094 | HS_2X2_BLOCKS); | |||
1095 | } | |||
1096 | ||||
1097 | } | |||
1098 | ||||
1099 | ||||
1100 | void ColorContainer::MouseMoved(BPoint,uint32 transit,const BMessage*) | |||
1101 | { | |||
1102 | // These are posted to the window in case that the window contains | |||
1103 | // a help view. | |||
1104 | if ((transit == B_ENTERED_VIEW) && (Window()->IsActive())) { | |||
1105 | BMessage *help_message = new BMessage(HS_TEMPORARY_HELP_MESSAGE'ThlM'); | |||
1106 | help_message->AddString("message", | |||
1107 | B_TRANSLATE("Click to select a painting color.")BLocaleRoster::Default()->GetCatalog()->GetString(("Click to select a painting color." ), "ColorPalette")); | |||
1108 | Window()->PostMessage(help_message); | |||
1109 | delete help_message; | |||
1110 | } | |||
1111 | if (transit == B_EXITED_VIEW) { | |||
1112 | Window()->PostMessage(HS_TOOL_HELP_MESSAGE'TolM'); | |||
1113 | } | |||
1114 | } | |||
1115 | ||||
1116 | ||||
1117 | void ColorContainer::MessageReceived(BMessage *message) | |||
1118 | { | |||
1119 | switch (message->what) { | |||
1120 | ||||
1121 | // this message comes from ColorContainer::sendMessageToAllContainers and that function | |||
1122 | // is called in ColorWindow's MessageReceived, it's purpose is to inform | |||
1123 | case HS_PALETTE_CHANGED'PaCh': | |||
1124 | // here call the function that fits the view to | |||
1125 | // accommodate the new palette. 0 colors instructs the function | |||
1126 | // to look the amount from ColorSet. | |||
1127 | setUpContainer(Bounds(),0,FALSE0); | |||
1128 | Draw(Bounds()); | |||
1129 | break; | |||
1130 | ||||
1131 | case HS_NEXT_PALETTE'NxPl': { | |||
1132 | ColorSet::moveToNextSet(); | |||
1133 | BMessage paletteChanged(HS_PALETTE_CHANGED'PaCh'); | |||
1134 | ColorContainer::sendMessageToAllContainers(&paletteChanged); | |||
1135 | } break; | |||
1136 | case HS_PREVIOUS_PALETTE'PrPl': { | |||
1137 | ColorSet::moveToPrevSet(); | |||
1138 | BMessage paletteChanged(HS_PALETTE_CHANGED'PaCh'); | |||
1139 | ColorContainer::sendMessageToAllContainers(&paletteChanged); | |||
1140 | } break; | |||
1141 | ||||
1142 | // this message comes from ColorContainer::sendMessageToAllContainers and that function | |||
1143 | // is called in ColorWindow's MessageReceived, it informs us that one of the colors in the | |||
1144 | // set has been changed, this constant is used for the same purpose in a slight different context | |||
1145 | // the changed color is at "index" int32 data member in the message | |||
1146 | case HS_COLOR_CHANGED'CoCH': { | |||
1147 | // the colorset has been updated, we will draw using colorChanged-function | |||
1148 | colorChanged(message->FindInt32("index")); | |||
1149 | } break; | |||
1150 | ||||
1151 | case B_PASTE: { | |||
1152 | if (message->WasDropped()) { | |||
1153 | // Here we see on to which button it was dropped and then | |||
1154 | // try to extract a color from the message | |||
1155 | rgb_color *color; | |||
1156 | ssize_t color_size; | |||
1157 | if (message->FindData("RGBColor",B_RGB_COLOR_TYPE,(const void**)&color,&color_size) == B_OK((int)0)) { | |||
1158 | BPoint drop_point = message->DropPoint(); | |||
1159 | drop_point = ConvertFromScreen(drop_point); | |||
1160 | int32 index = pointIndex(drop_point); | |||
1161 | if (index >= 0) { | |||
1162 | ColorSet::currentSet()->setCurrentColorIndex(index); | |||
1163 | ColorSet::currentSet()->setCurrentColor(*color); | |||
1164 | BMessage a_message(HS_COLOR_CHANGED'CoCH'); | |||
1165 | a_message.AddInt32("index",index); | |||
1166 | ColorContainer::sendMessageToAllContainers(&a_message); | |||
1167 | a_message.what = HS_PALETTE_SELECTION_CHANGED'PslC'; | |||
1168 | ColorContainer::sendMessageToAllContainers(&a_message); | |||
1169 | Window()->PostMessage(HS_PALETTE_SELECTION_CHANGED'PslC',Window()); | |||
1170 | } | |||
1171 | } | |||
1172 | } | |||
1173 | } break; | |||
1174 | // this message comes from ColorContainer::sendMessageToAllContainers and that function | |||
1175 | // is called in ColorContainer::MouseDown, it informs us that the selected color in the | |||
1176 | // set has changed | |||
1177 | case HS_PALETTE_SELECTION_CHANGED'PslC': { | |||
1178 | // the selected color of palette has changed | |||
1179 | // if we highlight it then draw completely | |||
1180 | // because we don't know what was the previous color | |||
1181 | if (highlight_selected) | |||
1182 | Draw(Bounds()); | |||
1183 | } break; | |||
1184 | default: | |||
1185 | BView::MessageReceived(message); | |||
1186 | break; | |||
1187 | } | |||
1188 | } | |||
1189 | ||||
1190 | void ColorContainer::setUpContainer(BRect frame, int32 number_of_colors,bool add_arrows) | |||
1191 | { | |||
1192 | // This gets stuck in an infinite loop if the height of the frame | |||
1193 | // is negative. | |||
1194 | horiz_c_size = 3; | |||
1195 | vert_c_size = 3; | |||
1196 | horiz_gutter = 1; | |||
1197 | vert_gutter = 1; | |||
1198 | color_count = number_of_colors; | |||
1199 | row_count = 1; | |||
1200 | ||||
1201 | if (color_count == 0) { | |||
1202 | // here we take the new color-count from current color-set | |||
1203 | color_count = ColorSet::currentSet()->sizeOfSet(); | |||
1204 | } | |||
1205 | ||||
1206 | // first count how many rows are to be used | |||
1207 | while ((row_count<=color_count/row_count) && (row_count*vert_c_size<=frame.Height())) | |||
1208 | row_count *= 2; | |||
1209 | row_count /= 2; | |||
1210 | ||||
1211 | if (row_count < 1) | |||
1212 | row_count = 1; | |||
1213 | ||||
1214 | // then increase the row height to maximum | |||
1215 | while ((row_count*(vert_c_size + vert_gutter) - vert_gutter)<=frame.Height()) | |||
1216 | vert_c_size++; | |||
1217 | vert_c_size--; | |||
1218 | ||||
1219 | // then increase the width to maximum | |||
1220 | float maximum_width = frame.Width(); | |||
1221 | if (left_arrow != NULL__null) { | |||
1222 | maximum_width -= (left_arrow->Frame().right + 2); | |||
1223 | } | |||
1224 | while ((color_count/row_count*(horiz_c_size+horiz_gutter) - horiz_gutter) <= maximum_width) | |||
1225 | horiz_c_size++; | |||
1226 | horiz_c_size--; | |||
1227 | ||||
1228 | ResourceServer* server = ResourceServer::Instance(); | |||
1229 | if (add_arrows && server) { | |||
1230 | BPicture arrow_pushed; | |||
1231 | BPicture arrow_not_pushed; | |||
1232 | ||||
1233 | server->GetPicture(LEFT_ARROW, &arrow_not_pushed); | |||
1234 | server->GetPicture(LEFT_ARROW_PUSHED, &arrow_pushed); | |||
1235 | ||||
1236 | left_arrow = new BPictureButton(BRect(0, 0, 8, 12), "left_arrow", | |||
1237 | &arrow_not_pushed, &arrow_pushed, new BMessage(HS_PREVIOUS_PALETTE'PrPl')); | |||
1238 | AddChild(left_arrow); | |||
1239 | left_arrow->ResizeToPreferred(); | |||
1240 | left_arrow->MoveTo(BPoint(2, 2)); | |||
1241 | ||||
1242 | server->GetPicture(RIGHT_ARROW, &arrow_not_pushed); | |||
1243 | server->GetPicture(RIGHT_ARROW_PUSHED, &arrow_pushed); | |||
1244 | ||||
1245 | right_arrow = new BPictureButton(BRect(0, 0, 8, 12), "right_arrow", | |||
1246 | &arrow_not_pushed, &arrow_pushed, new BMessage(HS_NEXT_PALETTE'NxPl')); | |||
1247 | AddChild(right_arrow); | |||
1248 | right_arrow->ResizeToPreferred(); | |||
1249 | right_arrow->MoveTo(BPoint(2, left_arrow->Frame().bottom + 3)); | |||
1250 | ||||
1251 | contains_arrows = true; | |||
1252 | } | |||
1253 | ||||
1254 | // here resize the view to just fit the colors | |||
1255 | ResizeTo((color_count/row_count*(horiz_c_size+horiz_gutter) - horiz_gutter),(row_count*(vert_c_size + vert_gutter) - vert_gutter)); | |||
1256 | ||||
1257 | if (contains_arrows) { | |||
1258 | ResizeBy(left_arrow->Frame().right+2,0); | |||
1259 | } | |||
1260 | } | |||
1261 | ||||
1262 | ||||
1263 | void ColorContainer::SetHighAndLowColors(const rgb_color &c) | |||
1264 | { | |||
1265 | rgb_color low = c; | |||
1266 | rgb_color high = c; | |||
1267 | ||||
1268 | float coeff = c.alpha / 255.0; | |||
1269 | low.red = (uint8)(coeff*c.red); | |||
1270 | low.green = (uint8)(coeff*c.green); | |||
1271 | low.blue = (uint8)(coeff*c.blue); | |||
1272 | low.alpha = 255; | |||
1273 | ||||
1274 | high.red = (uint8)(coeff*c.red + (1-coeff)*255); | |||
1275 | high.green = (uint8)(coeff*c.green + (1-coeff)*255); | |||
1276 | high.blue = (uint8)(coeff*c.blue + (1-coeff)*255); | |||
1277 | high.alpha = 255; | |||
1278 | ||||
1279 | SetHighColor(high); | |||
1280 | SetLowColor(low); | |||
1281 | } | |||
1282 | ||||
1283 | BRect ColorContainer::colorBounds(int32 index) | |||
1284 | { | |||
1285 | // this function calculates the rectangle for the | |||
1286 | // palette entry at index that is to be drawn on screen | |||
1287 | BRect rect; | |||
1288 | int32 row=1,column=1; | |||
1289 | for (int32 i=0;i<index;i++) { | |||
1290 | if (column >= color_count/row_count) { | |||
1291 | column = 1; | |||
1292 | row++; | |||
1293 | } | |||
1294 | else | |||
1295 | column++; | |||
1296 | } | |||
1297 | rect = BRect((column-1)*(horiz_c_size + horiz_gutter),(row-1)*(vert_c_size + vert_gutter),column*(horiz_c_size + horiz_gutter) - horiz_gutter,row*(vert_c_size + vert_gutter) - vert_gutter); | |||
1298 | if ((contains_arrows == TRUE1) && (left_arrow != NULL__null)) { | |||
1299 | rect.OffsetBy(left_arrow->Frame().right + 2,0); | |||
1300 | } | |||
1301 | return rect; | |||
1302 | } | |||
1303 | ||||
1304 | ||||
1305 | int32 ColorContainer::pointIndex(BPoint point) | |||
1306 | { | |||
1307 | // this function returns which palette entry is at point in the view | |||
1308 | // or -1 if no entry is to found there | |||
1309 | // at the moment just calculate usin rect Contains-function | |||
1310 | // later should be implemented more elegantly | |||
1311 | ||||
1312 | for (int32 i=0;i<color_count;i++) { | |||
1313 | if (colorBounds(i).Contains(point)) | |||
1314 | return i; | |||
1315 | } | |||
1316 | ||||
1317 | // none of the rectangles contained point | |||
1318 | return -1; | |||
1319 | } | |||
1320 | ||||
1321 | void ColorContainer::colorChanged(int32 color_index) | |||
1322 | { | |||
1323 | // draw the new color | |||
1324 | rgb_color c = ColorSet::currentSet()->colorAt(color_index); | |||
1325 | rgb_color low = c; | |||
1326 | float coeff = c.alpha / 255.0; | |||
1327 | low.red = (uint8)(c.red*coeff); | |||
1328 | low.green = (uint8)(c.green*coeff); | |||
1329 | low.blue = (uint8)(c.blue*coeff); | |||
1330 | low.alpha = 255; | |||
1331 | ||||
1332 | c.red = (uint8)(c.red * coeff + (1-coeff)*255); | |||
1333 | c.green = (uint8)(c.green * coeff + (1-coeff)*255); | |||
1334 | c.blue = (uint8)(c.blue * coeff + (1-coeff)*255); | |||
1335 | c.alpha = 255; | |||
1336 | ||||
1337 | SetHighColor(c); | |||
1338 | SetLowColor(low); | |||
1339 | FillRect(colorBounds(color_index),HS_2X2_BLOCKS); | |||
1340 | ||||
1341 | // also draw the white rect around the color that is currently selected | |||
1342 | // could be some other that was changed | |||
1343 | if (highlight_selected) { | |||
1344 | SetHighColor(255,255,255); | |||
1345 | StrokeRect(colorBounds(ColorSet::currentSet()->currentColorIndex())); | |||
1346 | } | |||
1347 | // and we will Sync() | |||
1348 | Sync(); | |||
1349 | } | |||
1350 | ||||
1351 | ||||
1352 | void ColorContainer::sendMessageToAllContainers(BMessage *message) | |||
1353 | { | |||
1354 | // here go through the list of color containers | |||
1355 | // and post message to each of them | |||
1356 | ||||
1357 | for (int32 i=0;i<container_list->CountItems();i++) { | |||
1358 | ((ColorContainer*)container_list->ItemAt(i))->Window()->PostMessage(message,(ColorContainer*)container_list->ItemAt(i)); | |||
1359 | } | |||
1360 | } | |||
1361 | ||||
1362 | ||||
1363 | // here begins the definition of ColorSet-class | |||
1364 | // first initialize the static variables | |||
1365 | BList* ColorSet::color_set_list = new BList(); | |||
1366 | int32 ColorSet::current_set_index = 0; | |||
1367 | ||||
1368 | ||||
1369 | ColorSet::ColorSet(int32 amount_of_colors, ColorSet *copy_this_palette) | |||
1370 | { | |||
1371 | // first check that the amount of colors is reasonable | |||
1372 | amount_of_colors = min_c(amount_of_colors,256)((amount_of_colors)>(256)?(256):(amount_of_colors)); | |||
1373 | amount_of_colors = max_c(amount_of_colors,1)((amount_of_colors)>(1)?(amount_of_colors):(1)); | |||
1374 | ||||
1375 | // first allocate memory for the new palette | |||
1376 | palette = new rgb_color[amount_of_colors]; | |||
1377 | ||||
1378 | // allocate memory for name, 100 chars should be long enough | |||
1379 | name = new char[100]; | |||
1380 | ||||
1381 | if (copy_this_palette == NULL__null) { | |||
1382 | // if no palette was given to copy from make a default palette | |||
1383 | for (int32 i=0;i<amount_of_colors;i++) { | |||
1384 | palette[i].red = i*256/amount_of_colors; | |||
1385 | palette[i].green = i*256/amount_of_colors; | |||
1386 | palette[i].blue = i*256/amount_of_colors; | |||
1387 | palette[i].alpha = 255; | |||
1388 | } | |||
1389 | } | |||
1390 | else { | |||
1391 | // here we copy that palette | |||
1392 | int32 source_size = copy_this_palette->sizeOfSet(); | |||
1393 | for (int i=0;i<amount_of_colors;i++) { | |||
1394 | palette[i] = copy_this_palette->colorAt(i % source_size); | |||
1395 | } | |||
1396 | } | |||
1397 | // store the color count | |||
1398 | color_count = amount_of_colors; | |||
1399 | ||||
1400 | // create a default name | |||
1401 | strcpy(name,"default palette"); | |||
1402 | ||||
1403 | // put the current color to 0 | |||
1404 | current_color_index = 0; | |||
1405 | ||||
1406 | color_set_list->AddItem(this); | |||
1407 | } | |||
1408 | ||||
1409 | ColorSet::~ColorSet() | |||
1410 | { | |||
1411 | // remove ourselves from the color_set_list | |||
1412 | color_set_list->RemoveItem(this); | |||
1413 | current_set_index = min_c(current_set_index,color_set_list->CountItems()-1)((current_set_index)>(color_set_list->CountItems()-1)?( color_set_list->CountItems()-1):(current_set_index)); | |||
1414 | } | |||
1415 | ||||
1416 | ||||
1417 | rgb_color ColorSet::colorAt(int32 index) | |||
1418 | { | |||
1419 | // check that the index is correct | |||
1420 | if ((index>=0)&&(index<color_count)) { | |||
1421 | return palette[index]; | |||
1422 | } | |||
1423 | else { | |||
1424 | // otherwise return the first color | |||
1425 | return palette[0]; | |||
1426 | } | |||
1427 | } | |||
1428 | ||||
1429 | ||||
1430 | void ColorSet::setColor(int32 index, rgb_color color) | |||
1431 | { | |||
1432 | // check that the index is correct | |||
1433 | if ((index>=0)&&(index<color_count)) { | |||
1434 | palette[index] = color; | |||
1435 | } | |||
1436 | ||||
1437 | } | |||
1438 | ||||
1439 | ||||
1440 | void ColorSet::setName(const char *set_name) | |||
1441 | { | |||
1442 | strcpy(name,set_name); | |||
1443 | } | |||
1444 | ||||
1445 | ||||
1446 | char* ColorSet::getName() | |||
1447 | { | |||
1448 | return name; | |||
1449 | } | |||
1450 | ||||
1451 | ||||
1452 | status_t ColorSet::readSets(BFile &file) | |||
1453 | { | |||
1454 | int32 number_of_sets; | |||
1455 | ||||
1456 | if (file.Read(&number_of_sets,sizeof(int32)) != sizeof(int32)) | |||
| ||||
1457 | return B_ERROR(-1); | |||
1458 | ||||
1459 | for (int32 i=0;i<number_of_sets;i++) { | |||
| ||||
1460 | int32 size_of_set; | |||
1461 | if (file.Read(&size_of_set,sizeof(int32)) != sizeof(int32)) | |||
1462 | return B_ERROR(-1); | |||
1463 | ||||
1464 | ColorSet *new_set = new ColorSet(size_of_set); | |||
1465 | ||||
1466 | int32 name_length; | |||
1467 | char name[255]; | |||
1468 | file.Read(&name_length,sizeof(int32)); | |||
1469 | file.Read(name,name_length); | |||
1470 | name[name_length] = '\0'; | |||
1471 | ||||
1472 | new_set->setName(name); | |||
1473 | ||||
1474 | for (int32 b=0;b<size_of_set;b++) { | |||
1475 | rgb_color c; | |||
1476 | if (file.Read(&c,sizeof(rgb_color)) != sizeof(rgb_color)) | |||
1477 | return B_ERROR(-1); | |||
1478 | ||||
1479 | new_set->palette[b] = c; | |||
1480 | } | |||
1481 | } | |||
1482 | ||||
1483 | return B_OK((int)0); | |||
1484 | } | |||
1485 | ||||
1486 | ||||
1487 | status_t ColorSet::writeSets(BFile &file) | |||
1488 | { | |||
1489 | int32 written_value = color_set_list->CountItems(); | |||
1490 | ||||
1491 | if (file.Write(&written_value,sizeof(int32)) != sizeof(int32)) | |||
1492 | return B_ERROR(-1); | |||
1493 | ||||
1494 | for (int32 i=0;i<color_set_list->CountItems();i++) { | |||
1495 | written_value = ((ColorSet*)color_set_list->ItemAt(i))->sizeOfSet(); | |||
1496 | if (file.Write(&written_value,sizeof(int32)) != sizeof(int32)) | |||
1497 | return B_ERROR(-1); | |||
1498 | ||||
1499 | written_value = strlen(((ColorSet*)color_set_list->ItemAt(i))->getName()); | |||
1500 | if (file.Write(&written_value,sizeof(int32)) != sizeof(int32)) | |||
1501 | return B_ERROR(-1); | |||
1502 | ||||
1503 | written_value = file.Write(((ColorSet*)color_set_list->ItemAt(i))->getName(), | |||
1504 | strlen(((ColorSet*)color_set_list->ItemAt(i))->getName())); | |||
1505 | if (uint32(written_value) != strlen(((ColorSet*)color_set_list->ItemAt(i))->getName())) | |||
1506 | return B_ERROR(-1); | |||
1507 | ||||
1508 | // here write the palette entries | |||
1509 | for (int32 b=0;b<((ColorSet*)color_set_list->ItemAt(i))->sizeOfSet();b++) { | |||
1510 | rgb_color c = ((ColorSet*)color_set_list->ItemAt(i))->palette[b]; | |||
1511 | if (file.Write(&c,sizeof(rgb_color)) != sizeof(rgb_color)) | |||
1512 | return B_ERROR(-1); | |||
1513 | } | |||
1514 | } | |||
1515 | ||||
1516 | ||||
1517 | return B_OK((int)0); | |||
1518 | } |