1/* 2 3InterfaceUtils.cpp 4 5Copyright (c) 2002 Haiku. 6 7Author: 8 Michael Pfeiffer 9 10Permission is hereby granted, free of charge, to any person obtaining a copy of 11this software and associated documentation files (the "Software"), to deal in 12the Software without restriction, including without limitation the rights to 13use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 14of the Software, and to permit persons to whom the Software is furnished to do 15so, subject to the following conditions: 16 17The above copyright notice and this permission notice shall be included in all 18copies or substantial portions of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26THE 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 45EscapeMessageFilter::EscapeMessageFilter(BWindow *window, int32 what) 46 : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, '_KYD') 47 , fWindow(window), 48 fWhat(what) 49{ 50} 51 52 53filter_result 54EscapeMessageFilter::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 69HWindow::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 77HWindow::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 85void 86HWindow::Init(uint32 escape_msg) 87{ 88 AddShortcut('i', 0, new BMessage(B_ABOUT_REQUESTED)); 89 AddCommonFilter(new EscapeMessageFilter(this, escape_msg)); 90} 91 92 93void 94HWindow::MessageReceived(BMessage* msg) 95{ 96 if (msg->what == B_ABOUT_REQUESTED) { 97 AboutRequested(); 98 } else { 99 inherited::MessageReceived(msg); 100 } 101} 102 103 104void 105HWindow::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 142BlockingWindow::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 150BlockingWindow::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 158BlockingWindow::~BlockingWindow() 159{ 160 delete_sem(fExitSem); 161} 162 163 164void 165BlockingWindow::Init(const char* title) 166{ 167 fUserQuitResult = B_OK; 168 fResult = NULL; 169 fExitSem = create_sem(0, title); 170 fReadyToQuit = false; 171} 172 173 174bool 175BlockingWindow::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 187void 188BlockingWindow::Quit() 189{ 190 fReadyToQuit = false; // finally allow window to quit 191 inherited::Quit(); // and quit it 192} 193 194 195void 196BlockingWindow::Quit(status_t result) 197{ 198 if (fResult) 199 *fResult = result; 200 201 release_sem(fExitSem); 202} 203 204 205void 206BlockingWindow::SetUserQuitResult(status_t result) 207{ 208 fUserQuitResult = result; 209} 210 211 212status_t 213BlockingWindow::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