1 //------------------------------------------------------------------------------
2 // Copyright (c) 2001-2002, OpenBeOS
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
22 // File Name: CurView.cpp
23 // Author: DarkWyrm <bpmagic@columbus.rr.com>
24 // Description: cursor handler for the app
26 //------------------------------------------------------------------------------
28 #include <Directory.h>
30 #include <storage/Path.h>
34 #include "CursorWhichItem.h"
38 #include "ServerConfig.h"
39 #include <ServerProtocol.h>
40 #include <PortMessage.h>
41 #include <InterfaceDefs.h>
42 #include <TranslationUtils.h>
44 //#define DEBUG_CURSORSET
46 #define SAVE_CURSORSET 'svcu'
47 #define DELETE_CURSORSET 'dlcu'
48 #define LOAD_CURSORSET 'ldcu'
49 #define CURSOR_UPDATED 'csru'
51 CurView::CurView(const BRect
&frame
, const char *name
, int32 resize
, int32 flags
)
52 :BView(frame
,name
,resize
,flags
), settings(B_SIMPLE_DATA
)
54 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
57 cursorset
=new CursorSet("Default");
60 // Code disabled -- cursor set management belongs in another app
61 BMenuBar *mb=new BMenuBar(BRect(0,0,Bounds().Width(),16),"menubar");
63 settings_menu=new BMenu("Settings");
64 settings_menu->AddItem(new BMenuItem("Save Cursor Set",new BMessage(SAVE_CURSORSET),'S'));
65 settings_menu->AddSeparatorItem();
66 settings_menu->AddItem(new BMenuItem("Delete Cursor Set",new BMessage(DELETE_CURSORSET)));
67 mb->AddItem(settings_menu);
69 cursorset_menu=LoadCursorSets();
71 mb->AddItem(cursorset_menu);
74 // We should *never* be here, but just in case....
75 cursorset_menu=new BMenu("Cursor Sets");
76 mb->AddItem(cursorset_menu);
80 BRect
wellrect(0,0,20,20);
81 wellrect
.OffsetTo(10,25);
82 wellrect
.right
=wellrect
.left
+50;
85 // Code disabled -- cursor set management belongs in another app
86 cursorset_label=new BStringView(wellrect,"cursorset_label","Cursor Set: ");
87 AddChild(cursorset_label);
88 cursorset_label->ResizeToPreferred();
89 cursorset_name="<untitled>";
92 // Set up list of cursor attributes
96 cvrect
.Set(0,0,75,75);
98 bmpview
=new BitmapView(BPoint(10,10),new BMessage(CURSOR_UPDATED
),this);
99 bmpview
->MoveTo( (Bounds().Width()-bmpview
->Bounds().Width())/2,30);
103 rect
.left
=(Bounds().Width()-200)/2;
104 rect
.right
=rect
.left
+190;
105 rect
.top
=bmpview
->Frame().bottom
+30;
106 rect
.bottom
=rect
.top
+100;
108 attrlist
=new BListView(rect
,"AttributeList");
110 scrollview
=new BScrollView("ScrollView",attrlist
, B_FOLLOW_LEFT
|
111 B_FOLLOW_TOP
, 0, false, true);
112 AddChild(scrollview
);
113 scrollview
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
115 attrlist
->SetSelectionMessage(new BMessage(ATTRIBUTE_CHOSEN
));
117 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_DEFAULT
));
118 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_TEXT
));
119 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_MOVE
));
120 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_DRAG
));
121 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_RESIZE
));
122 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_RESIZE_NWSE
));
123 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_RESIZE_NESW
));
124 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_RESIZE_NS
));
125 attrlist
->AddItem(new CursorWhichItem(B_CURSOR_RESIZE_EW
));
128 cvrect
.Set(0,0,60,30);
129 cvrect
.OffsetTo( (Bounds().Width()-200)/2,scrollview
->Frame().bottom
+20);
131 defaults
=new BButton(cvrect
,"DefaultsButton","Defaults",
132 new BMessage(DEFAULT_SETTINGS
),B_FOLLOW_LEFT
|B_FOLLOW_TOP
,
133 B_WILL_DRAW
| B_NAVIGABLE
);
136 cvrect
.OffsetBy(70,0);
137 revert
=new BButton(cvrect
,"RevertButton","Revert",
138 new BMessage(REVERT_SETTINGS
),B_FOLLOW_LEFT
|B_FOLLOW_TOP
,
139 B_WILL_DRAW
| B_NAVIGABLE
);
141 revert
->SetEnabled(false);
143 cvrect
.OffsetBy(70,0);
144 apply
=new BButton(cvrect
,"ApplyButton","Apply",
145 new BMessage(APPLY_SETTINGS
),B_FOLLOW_LEFT
|B_FOLLOW_TOP
,
146 B_WILL_DRAW
| B_NAVIGABLE
);
148 apply
->SetEnabled(false);
150 BEntry
entry(COLOR_SET_DIR
);
154 attribute
=B_PANEL_BACKGROUND_COLOR
;
155 attrstring
="Background";
160 CurView::~CurView(void)
165 void CurView::AllAttached(void)
168 attrlist
->SetTarget(this);
169 apply
->SetTarget(this);
170 defaults
->SetTarget(this);
171 revert
->SetTarget(this);
172 bmpview
->SetTarget(this);
173 BMessenger
msgr(this);
176 void CurView::MessageReceived(BMessage
*msg
)
178 if(msg
->WasDropped())
186 CursorWhichItem
*cwi
=(CursorWhichItem
*)attrlist
->ItemAt(attrlist
->CurrentSelection());
188 cwi
->SetBitmap(bmpview
->GetBitmap());
192 case ATTRIBUTE_CHOSEN
:
194 CursorWhichItem
*cwi
=(CursorWhichItem
*)attrlist
->ItemAt(attrlist
->CurrentSelection());
197 bmpview
->SetBitmap(cwi
->GetBitmap());
198 bmpview
->Invalidate();
204 BView::MessageReceived(msg
);
210 // Code disabled -- cursor set management belongs in another app
211 BMenu *CurView::LoadCursorSets(void)
213 #ifdef DEBUG_CURSORSET
214 printf("Loading cursor sets from disk\n");
216 // This function populates the member menu *cursorset_menu with the cursor
217 // set files located in the cursor set directory. To ensure that there are
218 // no entries pointing to invalid cursor sets, they are validated before
219 // a menu item is added.
225 BMenu *menu=new BMenu("Cursor Sets");
227 status_t dirstat=dir.SetTo(COLOR_SET_DIR);
230 // We couldn't set the directory, so more than likely it just
231 // doesn't exist. Create it and return an empty menu.
234 case B_NAME_TOO_LONG:
236 BAlert *a=new BAlert("OpenBeOS","Couldn't open the folder for cursor sets. "
237 "You will be able to change system cursors, but be unable to save them to a cursor set. "
238 "Please contact OpenBeOS about Appearance Preferences::CurView::"
239 "LoadCursorSets::B_NAME_TOO_LONG for a bugfix", "OK",
240 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
241 a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE);
245 case B_ENTRY_NOT_FOUND:
247 create_directory(COLOR_SET_DIR,0777);
252 printf("CurView::LoadCursorSets(): Invalid cursorset folder path.\n");
257 printf("CurView::LoadCursorSets(): No memory left. We're probably going to crash now. \n");
262 printf("CurView::LoadCursorSets(): Busy node " CURSOR_SET_DIR "\n");
267 BAlert *a=new BAlert("OpenBeOS","Couldn't open the folder for cursor sets "
268 "because of a file error. Perhaps there is a file (instead of a folder) at " COLOR_SET_DIR
269 "? You will be able to change system cursors, but be unable to save them to a cursor set. ",
270 "OK", NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
271 a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE);
277 BAlert *a=new BAlert("OpenBeOS","Couldn't open the folder for cursor sets "
278 "because there are too many open files. Please close some files and restart "
279 " this application.", "OK",
280 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
281 a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE);
284 Window()->PostMessage(B_QUIT_REQUESTED);
292 int32 count=dir.CountEntries();
298 for(int32 i=0;i<count;i++)
300 dir.GetNextEntry(&entry);
301 entry.GetPath(&path);
303 if(cs.Load(path.Path())!=B_OK)
306 // Don't include the default set in the menu
308 if(name.Compare("Default")==0)
313 name.Remove(0,name.FindLast('/')+1);
315 msg=new BMessage(LOAD_CURSORSET);
316 msg->AddString("name",name);
317 menu->AddItem(new BMenuItem(name.String(),msg));
323 void CurView::SetCursorSetName(const char *name)
327 BString namestr("Cursor Set: ");
330 cursorset_label->SetText(namestr.String());
331 cursorset_label->ResizeToPreferred();
332 cursorset_label->Invalidate();
336 void CurView::SaveSettings(void)
338 // Save the current GUI cursor settings to the GUI cursors file in the
339 // path specified in defs.h
341 BString
path(SERVER_SETTINGS_DIR
);
342 path
+=CURSOR_SETTINGS_NAME
;
343 #ifdef DEBUG_CURSORSET
344 printf("SaveSettings: %s\n",path
.String());
346 cursorset
->Save(path
.String(),B_CREATE_FILE
|B_ERASE_FILE
);
348 // prev_set_name=cursorset_name;
349 revert
->SetEnabled(false);
352 void CurView::LoadSettings(void)
354 // Load the current GUI cursor settings from disk. This is done instead of
355 // getting them from the server at this point for testing purposes. Comment
356 // out the #define LOAD_SETTINGS_FROM_DISK line to use the server query code
357 #ifdef DEBUG_CURSORSET
358 printf("Loading settings from disk\n");
360 settings
.MakeEmpty();
362 BDirectory dir
,newdir
;
363 if(dir
.SetTo(SERVER_SETTINGS_DIR
)==B_ENTRY_NOT_FOUND
)
365 #ifdef DEBUG_CURSORSET
366 printf("Cursor set folder not found. Creating %s\n",SERVER_SETTINGS_DIR
);
368 create_directory(SERVER_SETTINGS_DIR
,0777);
371 BString
path(SERVER_SETTINGS_DIR
);
372 path
+=CURSOR_SETTINGS_NAME
;
374 status_t stat
=cursorset
->Load(path
.String());
378 #ifdef DEBUG_CURSORSET
379 printf("Couldn't open file %s for read\n",path
.String());
387 void CurView::SetDefaults(void)
389 // The server will perform the necessary work to set defaults, so just ask it to do the
390 // work for us. It is a synchronous procedure, so we will notify the server and load the cursor
392 BString
string(CURSOR_SET_DIR
);
395 cursorset
->Load(string
.String());
397 port_id port
=find_port(SERVER_PORT_NAME
);
398 if(port
==B_NAME_NOT_FOUND
)
401 BPrivate::PortLink
link(port
);
404 link
.StartMessage(AS_SET_SYSCURSOR_DEFAULTS
);
406 link
.GetNextMessage(code
);
410 BitmapView::BitmapView(const BPoint
&pt
,BMessage
*message
, const BHandler
*handler
, const BLooper
*looper
=NULL
)
411 : BBox(BRect(0,0,75,75).OffsetToCopy(pt
),"bitmapview",B_FOLLOW_NONE
,B_WILL_DRAW
, B_PLAIN_BORDER
),
412 BInvoker(message
,handler
,looper
)
414 SetFont(be_plain_font
);
416 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
417 SetDrawingMode(B_OP_ALPHA
);
418 drawrect
=Bounds().InsetByCopy(5,5);
421 BitmapView::~BitmapView(void)
425 void BitmapView::SetBitmap(BBitmap
*bmp
)
430 void BitmapView::Draw(BRect r
)
435 DrawBitmap(bitmap
, drawrect
);
438 void BitmapView::MessageReceived(BMessage
*msg
)
440 if(msg
->WasDropped())
443 if(msg
->FindRef("refs",&ref
)!=B_OK
)
446 BBitmap
*tmp
=BTranslationUtils::GetBitmap(&ref
);
457 drawrect
=bitmap
->Bounds();
458 if(r
.Contains(bitmap
->Bounds()))
460 // calculate a centered rect for direct display
461 offset
=((r
.IntegerWidth()-bitmap
->Bounds().IntegerWidth()) >> 1)+5;
462 drawrect
.OffsetBy(offset
,offset
);
466 // calculate a scaled-down rectangle for display
467 drawrect
.left
=drawrect
.top
=0;
469 if(bitmap
->Bounds().Height() > bitmap
->Bounds().Width())
471 drawrect
.right
=(r
.Height()*bitmap
->Bounds().Width())/bitmap
->Bounds().Height();
472 drawrect
.bottom
=r
.Height();
473 offset
=((r
.IntegerWidth()-drawrect
.IntegerWidth()) >> 1)+5;
474 drawrect
.OffsetBy(offset
,5);
478 drawrect
.bottom
=(r
.Width()*bitmap
->Bounds().Height())/bitmap
->Bounds().Width();
479 drawrect
.right
=r
.Width();
480 offset
=((r
.IntegerHeight()-drawrect
.IntegerHeight()) >> 1)+5;
481 drawrect
.OffsetBy(5,offset
);
490 BBox::MessageReceived(msg
);