1 /* 2 * Copyright 2019-2023, Adrien Destugues, pulkomandy@pulkomandy.tk. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "AlertWithCheckbox.h" 8 9 #include <algorithm> 10 #include <stdio.h> 11 12 #include <Button.h> 13 #include <Catalog.h> 14 #include <CheckBox.h> 15 #include <ControlLook.h> 16 #include <GroupLayout.h> 17 #include <LayoutBuilder.h> 18 #include <Locale.h> 19 #include <IconUtils.h> 20 #include <Resources.h> 21 #include <StripeView.h> 22 #include <TextView.h> 23 24 #undef B_TRANSLATION_CONTEXT 25 #define B_TRANSLATION_CONTEXT "DebugServer" 26 27 28 enum { 29 kButton1Message, 30 kButton2Message, 31 kButton3Message 32 }; 33 34 35 AlertWithCheckbox::AlertWithCheckbox(const char* title, const char* messageText, 36 const char* checkboxLabel, const char* label1, const char* label2, const char* label3) 37 : 38 BWindow(BRect(0, 0, 100, 50), title, 39 B_MODAL_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, 40 B_CLOSE_ON_ESCAPE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS), 41 fBitmap(IconSize(), B_RGBA32), 42 fSemaphore(create_sem(0, "AlertWithCheckbox")), 43 fAction(0) 44 { 45 BIconUtils::GetSystemIcon("dialog-information", &fBitmap); 46 BStripeView *stripeView = new BStripeView(fBitmap); 47 48 BTextView *message = new BTextView("_tv_"); 49 message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 50 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 51 message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); 52 message->MakeEditable(false); 53 message->MakeSelectable(false); 54 message->SetText(messageText); 55 BRect textRect = message->TextRect(); 56 textRect.PrintToStream(); 57 message->SetWordWrap(true); 58 message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET)); 59 float width = message->StringWidth("W") * 40; 60 if (width < textRect.Width()) { 61 message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET)); 62 } 63 64 fDontAskAgain = new BCheckBox("checkbox", checkboxLabel, NULL); 65 66 BGroupView* buttonGroup = new BGroupView(B_HORIZONTAL); 67 BLayoutBuilder::Group<> layoutBuilder(buttonGroup); 68 69 layoutBuilder.AddGlue(); 70 71 if (label1) { 72 BButton* button = new BButton(label1, label1, new BMessage(kButton1Message)); 73 button->MakeDefault(true); 74 layoutBuilder.Add(button); 75 } 76 77 if (label2) { 78 BButton* button = new BButton(label2, label2, new BMessage(kButton2Message)); 79 layoutBuilder.Add(button); 80 } 81 82 if (label3) { 83 BButton* button = new BButton(label3, label3, new BMessage(kButton3Message)); 84 layoutBuilder.Add(button); 85 } 86 87 BLayoutBuilder::Group<>(this) 88 .AddGroup(B_HORIZONTAL) 89 .Add(stripeView) 90 .AddGroup(B_VERTICAL) 91 .SetInsets(B_USE_SMALL_SPACING) 92 .Add(message) 93 .AddGroup(B_HORIZONTAL, 0) 94 .Add(fDontAskAgain) 95 .AddGlue() 96 .End() 97 .Add(buttonGroup) 98 .End() 99 .End(); 100 101 ResizeToPreferred(); 102 CenterOnScreen(); 103 } 104 105 106 AlertWithCheckbox::~AlertWithCheckbox() 107 { 108 delete_sem(fSemaphore); 109 } 110 111 112 void 113 AlertWithCheckbox::MessageReceived(BMessage* message) 114 { 115 switch(message->what) { 116 case B_QUIT_REQUESTED: 117 release_sem(fSemaphore); 118 break; 119 120 case 0: 121 case 1: 122 case 2: 123 fAction = message->what; 124 PostMessage(B_QUIT_REQUESTED); 125 return; 126 } 127 128 BWindow::MessageReceived(message); 129 } 130 131 132 int32 133 AlertWithCheckbox::Go(bool& dontAskAgain) 134 { 135 Show(); 136 137 // Wait for user to close the window 138 acquire_sem(fSemaphore); 139 dontAskAgain = fDontAskAgain->Value(); 140 return fAction; 141 } 142 143 144 BRect 145 AlertWithCheckbox::IconSize() 146 { 147 return BRect(BPoint(0, 0), be_control_look->ComposeIconSize(32)); 148 } 149