1 /* 2 * Copyright 2013, Rene Gollent, rene@gollent.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "ConsoleOutputView.h" 8 9 #include <new> 10 11 #include <Button.h> 12 #include <CheckBox.h> 13 #include <LayoutBuilder.h> 14 #include <ScrollView.h> 15 #include <String.h> 16 #include <TextView.h> 17 18 19 enum { 20 MSG_CLEAR_OUTPUT = 'clou' 21 }; 22 23 24 // #pragma mark - ConsoleOutputView 25 26 27 ConsoleOutputView::ConsoleOutputView() 28 : 29 BGroupView(B_VERTICAL, 0.0f), 30 fStdoutEnabled(NULL), 31 fStderrEnabled(NULL), 32 fConsoleOutput(NULL), 33 fClearButton(NULL) 34 { 35 SetName("ConsoleOutput"); 36 } 37 38 39 ConsoleOutputView::~ConsoleOutputView() 40 { 41 } 42 43 44 /*static*/ ConsoleOutputView* 45 ConsoleOutputView::Create() 46 { 47 ConsoleOutputView* self = new ConsoleOutputView(); 48 49 try { 50 self->_Init(); 51 } catch (...) { 52 delete self; 53 throw; 54 } 55 56 return self; 57 } 58 59 60 void 61 ConsoleOutputView::ConsoleOutputReceived(int32 fd, const BString& output) 62 { 63 if (fd == 1 && fStdoutEnabled->Value() != B_CONTROL_ON) 64 return; 65 else if (fd == 2 && fStderrEnabled->Value() != B_CONTROL_ON) 66 return; 67 68 text_run_array run; 69 run.count = 1; 70 run.runs[0].font = be_fixed_font; 71 run.runs[0].offset = 0; 72 run.runs[0].color.red = fd == 1 ? 0 : 192; 73 run.runs[0].color.green = 0; 74 run.runs[0].color.blue = 0; 75 run.runs[0].color.alpha = 255; 76 77 bool autoScroll = false; 78 BScrollBar* scroller = fConsoleOutput->ScrollBar(B_VERTICAL); 79 float min, max; 80 scroller->GetRange(&min, &max); 81 if (min == max || scroller->Value() == max) 82 autoScroll = true; 83 84 fConsoleOutput->Insert(fConsoleOutput->TextLength(), output.String(), 85 output.Length(), &run); 86 if (autoScroll) { 87 scroller->GetRange(&min, &max); 88 fConsoleOutput->ScrollTo(0.0, max); 89 } 90 } 91 92 93 void 94 ConsoleOutputView::MessageReceived(BMessage* message) 95 { 96 switch (message->what) { 97 case MSG_CLEAR_OUTPUT: 98 { 99 fConsoleOutput->SetText(""); 100 break; 101 } 102 default: 103 BGroupView::MessageReceived(message); 104 break; 105 } 106 } 107 108 109 void 110 ConsoleOutputView::AttachedToWindow() 111 { 112 BGroupView::AttachedToWindow(); 113 114 fStdoutEnabled->SetValue(B_CONTROL_ON); 115 fStderrEnabled->SetValue(B_CONTROL_ON); 116 fClearButton->SetTarget(this); 117 } 118 119 120 void 121 ConsoleOutputView::LoadSettings(const BMessage& settings) 122 { 123 fStdoutEnabled->SetValue(settings.GetBool("showStdout", true) 124 ? B_CONTROL_ON : B_CONTROL_OFF); 125 fStderrEnabled->SetValue(settings.GetBool("showStderr", true) 126 ? B_CONTROL_ON : B_CONTROL_OFF); 127 } 128 129 130 status_t 131 ConsoleOutputView::SaveSettings(BMessage& settings) 132 { 133 bool value = fStdoutEnabled->Value() == B_CONTROL_ON; 134 if (settings.AddBool("showStdout", value) != B_OK) 135 return B_NO_MEMORY; 136 137 value = fStderrEnabled->Value() == B_CONTROL_ON; 138 if (settings.AddBool("showStderr", value) != B_OK) 139 return B_NO_MEMORY; 140 141 return B_OK; 142 } 143 144 145 void 146 ConsoleOutputView::_Init() 147 { 148 BScrollView* consoleScrollView; 149 150 BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0.0f) 151 .Add(consoleScrollView = new BScrollView("console scroll", NULL, 0, 152 true, true), 3.0f) 153 .AddGroup(B_VERTICAL, 0.0f) 154 .SetInsets(B_USE_SMALL_SPACING) 155 .Add(fStdoutEnabled = new BCheckBox("Stdout")) 156 .Add(fStderrEnabled = new BCheckBox("Stderr")) 157 .Add(fClearButton = new BButton("Clear")) 158 .AddGlue() 159 .End() 160 .End(); 161 162 consoleScrollView->SetTarget(fConsoleOutput = new BTextView("Console")); 163 164 fClearButton->SetMessage(new BMessage(MSG_CLEAR_OUTPUT)); 165 fConsoleOutput->MakeEditable(false); 166 fConsoleOutput->SetStylable(true); 167 fConsoleOutput->SetDoesUndo(false); 168 } 169