📄 wcon.cpp
字号:
} else
if (get_key_state(VK_LBUTTON) && current_time() - curr_tm > DRAG_WAIT) {
is_dragging = true;
}
}
void mouse_up(Point& pt)
{
if (is_dragging) {
is_dragging = false;
}
}
void right_mouse_down(Point& pt)
{
// shd be a menu!
copy_selection();
}
void keydown(int vkey)
{
switch(vkey) {
case VK_HOME: m_pos.x = m_buff_begin; break;
case VK_END: m_pos.x = m_buff_end; break;
case VK_LEFT: m_pos.x = max(m_pos.x-1,0); break;
case VK_RIGHT: m_pos.x = min(m_pos.x+1,m_end.x); break;
// *fix 1.2.8 page up/down better behaved - using actual m_top
case VK_PRIOR: vscroll(TScrollBar::PAGEUP,m_top); break;
case VK_NEXT: vscroll(TScrollBar::PAGEDOWN,m_top); break;
case VK_UP: history_list(true); break;
case VK_DOWN: history_list(false); break;
case VK_INSERT:
insert_mode(! m_insert_mode);
break;
case VK_DELETE:
m_buff.remove(m_pos);
draw_buff(TClientDC(this),m_pos,Position(m_end.x,m_pos.y));
break;
}
cursor_pos();
}
void check_row()
{
if (m_pos.y > m_top + m_pagesize) { // run out of window
m_top++;
scroll(0,-m_char.y);
}
}
void process_char(int ch, bool from_input)
{
// <enter> is actually '\r', so we massage non-input chars
// probably better to do it via the keydown handler?
if (!from_input && ch=='\n') ch = '\r';
int last_line = m_pos.y;
switch(ch) {
case CTRL_C: // ASCII 3
copy_selection();
break;
case CTRL_V:
paste_into();
break;
case '\b': // backspace
if (m_pos.x > 0) {
m_pos.x--;
m_buff_end--;
m_last_end = m_buff_end;
keydown(VK_DELETE);
} break;
case '\t': // *change 1.2.4 Tabs now 8 chars...
do {process_char(' ',from_input);} while(m_pos.x % 8 != 0);
break;
case '\r':
m_pos.x = 0; // and fall through
m_last_end = m_buff_end;
m_buff_end = 0;
case '\n':
m_pos.y++;
kount++;
m_buff.reserve(m_pos.y); // make sure buffer is big enough!
m_buff.colour(m_pos.y, m_write_colour);
check_row();
scroll_bar()->set_pos(m_pos.y);
m_last_line = max(m_last_line,m_pos.y);
insert_mode(false);
if (from_input && m_nchar==1) { // special case of waiting for a single char...
*m_read_buff='\n';
quit_loop();
}
break;
default:
int xend;
if (m_insert_mode && m_pos.x < m_buff_end) {
m_buff.insert(m_pos);
xend = m_buff_end;
} else xend = m_pos.x+1;
m_buff(m_pos.x, m_pos.y) = ch;
if (m_immediate) draw_buff(TClientDC(this),m_pos,Position(xend,m_pos.y));
m_pos.x ++;
m_last_end = m_buff_end;
m_buff_end ++;
if (m_pos.x > m_end.x) {
m_pos.x = 0;
m_pos.y++;
check_row();
if (m_pos.y > m_end.y) m_pos.y = 0;
}
break;
}
if (from_input) {
// two input scenarios: either we hit the delimiter,
// or we've read m_nchar chars in.
bool hit_delim = ch==m_delim;
bool got_nchar = m_nchar != -1 && m_pos.x - m_buff_begin==m_nchar;
if (m_nchar > 0 && ch == '\r') m_buff_begin = 0; // we don't pick it up?
if (m_read_buff && (hit_delim || got_nchar)) {
int last_pos = m_last_end;
if(hit_delim) {
/*if(m_delim != '\r')*/ last_pos--; // don't copy delim!
}
m_buff.copy_buffer(m_read_buff,last_line,m_buff_begin,last_pos);
m_buff_begin = m_pos.x;
if (hit_delim) {
add_to_history_list(m_read_buff);
m_last_end = 0;
}
quit_loop();
}
}
cursor_pos();
}
void on_char(int ch, int rpt)
{
for(int i = 0; i < rpt; i++) {
process_char(ch,true);
}
}
void clear()
{
m_buff.clear();
reset_pos();
scroll_bar()->set_pos(m_pos.y);
}
void putchars(char *str, bool endline, bool input)
{
try {
if(!input) m_immediate = false;
for(; *str != '\0'; str++) process_char(*str,input);
if (endline) process_char('\r',input);
if (!input) {
m_buff_begin = m_pos.x;
m_immediate = true;
invalidate();
cursor_pos();
}
} catch(...) {
Engine::kill(-1);
message("Buffer overflow\nProgram failed to terminate?");
clear();
}
}
int last_row() { return m_pos.y; }
};
static ConsoleWin *conw[10];
static bool is_eof;
static int curr_id;
static bool mCreateDefered = false;
ConsoleWin *wcon()
{
if (Program::in_main_thread()) return conw[0];
else {
if (mCreateDefered) { conw[curr_id]->show(); mCreateDefered = false; }
return conw[curr_id];
}
}
void wcon_prompt_char(char ch, int col)
// setting ch to 0 will disable prompt stripping
// UCW uses (';',0); DOS wd use (':',1).
{ gPromptChar = ch; gPromptCol = col; }
int wcon_lines()
{ return wcon()->last_row(); }
char *wcon_gets(char *buff)
{
wcon()->set_read_buff(buff);
int iret = wcon()->run();
is_eof = iret !=-1; // i.e. a normal windows exit!
return buff;
}
void wcon_puts(char *buff)
{
wcon()->putchars(buff,true,false);
}
void wcon_puttext(char *buff)
{
wcon()->putchars(buff,false,false);
}
int wcon_getch()
{
char chb[2];
wcon()->set_read_buff(chb,'\0',1);
int iret = wcon()->run();
is_eof = iret !=-1; // i.e. a normal windows exit!
return is_eof ? -1 : chb[0];
}
char wcon_obuff[256];
int wcon_vprintf(char *fmt,va_list args)
{
int ich = vsprintf(wcon_obuff,fmt,args);
wcon_puttext(wcon_obuff);
return ich;
}
int wcon_printf(char *fmt,...)
{
va_list ap;
int ich;
va_start(ap,fmt);
ich = wcon_vprintf(fmt,ap);
va_end(ap);
return ich;
}
int wcon_fprintf(FILE *out, char *fmt,...)
{
va_list ap;
int ich;
va_start(ap,fmt);
if (out==stdout || out==stderr) ich = wcon_vprintf(fmt,ap);
else if (out==_str_out) ich = str_vprintf(fmt,ap); // NOTE(10)
else ich = vfprintf(out,fmt,ap);
va_end(ap);
return ich;
}
static char *ptr = "";
char *wcon_getter(char *p)
{
static char ibuff[150];
if (p != NULL) ptr = p;
else {
ptr = skip_ws(ptr);
if (*ptr == '\0') {
wcon_gets(ibuff);
ptr = ibuff;
}
}
return ptr;
}
int wcon_scanf(char *fmt,...)
{
va_list ap;
int ret;
va_start(ap,fmt);
ret = ex_vfscanf(wcon_getter,fmt,ap);
va_end(ap);
return ret;
}
int wcon_fscanf(FILE *in, char *fmt,...)
{
va_list ap;
int ret;
va_start(ap,fmt);
ret = ex_vfscanf(in == _str_in ? str_getter : wcon_getter,fmt,ap);
va_end(ap);
return ret;
}
char *wcon_fgets(char *buff, int sz, FILE *in)
{
if(in==stdin) wcon_gets(buff);
else fgets(buff,sz,in);
return buff;
}
int wcon_eof()
{ return is_eof; }
ConsoleWin *curr_cw() { return conw[curr_id]; }
void *wcon_window() { return curr_cw(); }
void wcon_copy_to_log(char *file)
{
curr_cw()->copy_out(ofstream(file),0);
}
void *wcon_window_handle()
{
return curr_cw()->handle();
}
void wcon_set_title(char *title, bool do_main)
{
if (do_main) conw[0]->set_text(title);
else curr_cw()->set_text(title);
}
void wcon_set_colour(float r, float g, float b)
{ curr_cw()->set_colour(RGBF(r,g,b)); }
void wcon_set_console(int idx)
{
curr_id = idx;
}
void wcon_clear(int mode)
{
if (mode==0) {// clear input
ptr = "";
// wcon_getter(NULL);
} else
curr_cw()->clear();
}
void wcon_bring_to_front()
{
wcon()->on_top();
}
void* wcon_handle()
{
return wcon()->handle();
}
// *fix 0.9.4 Console window is _not_ made visible automatically; must use wcon_set_size().
// *add 0.9.7 'Defered' create - this is a hack until we can find a more _elegant_ solution...
int wcon_create(int rows, int cols, bool defered)
{
static int last_id = 0;
mCreateDefered = defered;
conw[last_id] = new ConsoleWin(rows,cols);
wcon_set_console(last_id);
return last_id++;
}
void wcon_set_size(int x0, int y0, int w, int h)
{
curr_cw()->resize(x0,y0,w,h);
if (! mCreateDefered) curr_cw()->show();
}
void wcon_destroy(int id)
{
conw[id]->close();
//] delete conw[id];
conw[id] = NULL;
if (curr_id == id) wcon_set_console(0); // main console always available
}
static bool mPaused = false;
bool wcon_paused()
{
return mPaused;
}
void wcon_pause()
{
mPaused = true;
conw[curr_id]->run();
}
void wcon_resume()
{
mPaused = false;
conw[curr_id]->quit_loop();
}
void wcon_set_parent(void *parent)
{
sConsoleParent = new TWin(parent);
}
bool WConIstream::fetch_line(char *buff, int sz)
{
wcon()->set_colour(0); // force input always in black, for now
wcon_gets(buff);
return true;
}
WConOstream::WConOstream(float r, float g, float b)
{
m_colour = RGBF(r,g,b);
m_redirect = NULL;
}
int WConOstream::write(char *buff, int n)
{
if (m_redirect != NULL && Program::in_main_thread() == m_main_console) {
m_redirect->write(buff,n);
} else {
wcon()->set_colour(m_colour);
wcon_puttext(buff);
}
return 1;
}
bool WConOstream::set_redirect(ostream* pos, bool main_console)
{
bool res = m_redirect != pos;
m_redirect = pos; m_main_console = main_console;
return res;
}
ostream* WConOstream::get_redirect() const { return m_redirect; }
bool wcon_redirect_output(WConOstream& out, ostream* pos, bool main_console)
{
return out.set_redirect(pos,main_console);
}
bool wcon_redirect_off(WConOstream& out)
{
delete out.get_redirect();
return out.set_redirect(NULL);
}
bool wcon_is_redirected(const WConOstream& out)
{
return out.get_redirect() != NULL;
}
WConIstream wcon_cin;
WConOstream wcon_cout(0,0,0), //black
wcon_cerr(1,0,0), //red
wcon_cmsg(0,0.5,0); //dark green
extern int main(int,char**);
int SMain(int argc,char **argv) // YAWL main program (see TWL.cpp)
{
int id = wcon_create(ROWS,COLUMNS);
int iret = 0;
#ifndef _USRDLL
iret = main(argc,argv);
wcon_destroy(id);
#endif
return iret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -