1 /* 2 3 InterfaceUtils.cpp 4 5 Copyright (c) 2002 OpenBeOS. 6 7 Author: 8 Michael Pfeiffer 9 10 Permission is hereby granted, free of charge, to any person obtaining a copy of 11 this software and associated documentation files (the "Software"), to deal in 12 the Software without restriction, including without limitation the rights to 13 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 14 of the Software, and to permit persons to whom the Software is furnished to do 15 so, subject to the following conditions: 16 17 The above copyright notice and this permission notice shall be included in all 18 copies or substantial portions of the Software. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 THE SOFTWARE. 27 28 */ 29 30 #include "BlockingWindow.h" 31 32 33 #include <Alert.h> 34 #include <Debug.h> 35 #include <Message.h> 36 #include <TextView.h> 37 38 39 #include <string.h> 40 41 42 // #pragma mark -- EscapeMessageFilter 43 44 45 EscapeMessageFilter::EscapeMessageFilter(BWindow *window, int32 what) 46 : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, '_KYD') 47 , fWindow(window), 48 fWhat(what) 49 { 50 } 51 52 53 filter_result 54 EscapeMessageFilter::Filter(BMessage *msg, BHandler **target) 55 { 56 int32 key; 57 filter_result result = B_DISPATCH_MESSAGE; 58 if (msg->FindInt32("key", &key) == B_OK && key == 1) { 59 fWindow->PostMessage(fWhat); 60 result = B_SKIP_MESSAGE; 61 } 62 return result; 63 } 64 65 66 // #pragma mark -- HWindow 67 68 69 HWindow::HWindow(BRect frame, const char *title, window_type type, uint32 flags, 70 uint32 workspace, uint32 escape_msg) 71 : BWindow(frame, title, type, flags, workspace) 72 { 73 Init(escape_msg); 74 } 75 76 77 HWindow::HWindow(BRect frame, const char *title, window_look look, window_feel feel, 78 uint32 flags, uint32 workspace, uint32 escape_msg) 79 : BWindow(frame, title, look, feel, flags, workspace) 80 { 81 Init(escape_msg); 82 } 83 84 85 void 86 HWindow::Init(uint32 escape_msg) 87 { 88 AddShortcut('i', 0, new BMessage(B_ABOUT_REQUESTED)); 89 AddCommonFilter(new EscapeMessageFilter(this, escape_msg)); 90 } 91 92 93 void 94 HWindow::MessageReceived(BMessage* msg) 95 { 96 if (msg->what == B_ABOUT_REQUESTED) { 97 AboutRequested(); 98 } else { 99 inherited::MessageReceived(msg); 100 } 101 } 102 103 104 void 105 HWindow::AboutRequested() 106 { 107 const char* aboutText = AboutText(); 108 if (aboutText == NULL) 109 return; 110 111 BAlert *about = new BAlert("About", aboutText, "Cool"); 112 BTextView *v = about->TextView(); 113 if (v) { 114 rgb_color red = {255, 0, 51, 255}; 115 rgb_color blue = {0, 102, 255, 255}; 116 117 v->SetStylable(true); 118 char *text = (char*)v->Text(); 119 char *s = text; 120 // set all Be in blue and red 121 while ((s = strstr(s, "Be")) != NULL) { 122 int32 i = s - text; 123 v->SetFontAndColor(i, i+1, NULL, 0, &blue); 124 v->SetFontAndColor(i+1, i+2, NULL, 0, &red); 125 s += 2; 126 } 127 // first text line 128 s = strchr(text, '\n'); 129 BFont font; 130 v->GetFontAndColor(0, &font); 131 font.SetSize(12); // font.SetFace(B_OUTLINED_FACE); 132 v->SetFontAndColor(0, s-text+1, &font, B_FONT_SIZE); 133 }; 134 about->SetFlags(about->Flags() | B_CLOSE_ON_ESCAPE); 135 about->Go(); 136 } 137 138 139 // #pragma mark -- BlockingWindow 140 141 142 BlockingWindow::BlockingWindow(BRect frame, const char *title, window_type type, 143 uint32 flags, uint32 workspace, uint32 escape_msg) 144 : HWindow(frame, title, type, flags, workspace) 145 { 146 Init(title); 147 } 148 149 150 BlockingWindow::BlockingWindow(BRect frame, const char *title, window_look look, 151 window_feel feel, uint32 flags, uint32 workspace, uint32 escape_msg) 152 : HWindow(frame, title, look, feel, flags, workspace) 153 { 154 Init(title); 155 } 156 157 158 BlockingWindow::~BlockingWindow() 159 { 160 delete_sem(fExitSem); 161 } 162 163 164 void 165 BlockingWindow::Init(const char* title) 166 { 167 fUserQuitResult = B_OK; 168 fResult = NULL; 169 fExitSem = create_sem(0, title); 170 fReadyToQuit = false; 171 } 172 173 174 bool 175 BlockingWindow::QuitRequested() 176 { 177 if (fReadyToQuit) 178 return true; 179 180 // user requested to quit the window 181 *fResult = fUserQuitResult; 182 release_sem(fExitSem); 183 return false; 184 } 185 186 187 void 188 BlockingWindow::Quit() 189 { 190 fReadyToQuit = false; // finally allow window to quit 191 inherited::Quit(); // and quit it 192 } 193 194 195 void 196 BlockingWindow::Quit(status_t result) 197 { 198 if (fResult) 199 *fResult = result; 200 201 release_sem(fExitSem); 202 } 203 204 205 void 206 BlockingWindow::SetUserQuitResult(status_t result) 207 { 208 fUserQuitResult = result; 209 } 210 211 212 status_t 213 BlockingWindow::Go() 214 { 215 status_t result = B_ERROR; 216 fResult = &result; 217 Show(); 218 acquire_sem(fExitSem); 219 // here the window still exists, because QuitRequested returns false if 220 // fReadyToQuit is false, now we can quit the window and am sure that the 221 // window thread dies before this thread 222 if (Lock()) { 223 Quit(); 224 } else { 225 ASSERT(false); // should not reach here!!! 226 } 227 // here the window does not exist, good to have the result in a local variable 228 return result; 229 } 230