int SelectWnd::selectExec() { WORD oldSelect; int i; BOOL bSetCursor = FALSE; oldSelect = selectNum; selectNum = -1; for(i=0; i<slctCnt; i++) { if(PtInRect(&selectRect[i],sysInf.msPoint)) { selectNum = i; break; } } if(keyState.push_action) { if(selectNum >= 0) { PlayEffectNum(evtHandle[1],SelectSnd); selectEnd(); return selectNum; } } else if(bCancel && keyState.push_cancel) { PlayEffectNum(evtHandle[1],CancelSnd); selectEnd(); return -2; } else if(keyState.push_up || keyState.push_down) { if(keyState.push_up) { if(selectNum == (-1))selectNum = 0; else if(selectNum == 0)selectNum = slctCnt -1; else selectNum --; } else { if(selectNum == (-1))selectNum = 0; else { selectNum ++; if(selectNum >= slctCnt)selectNum = 0; } } bSetCursor = TRUE; } else if(keyState.push_left || keyState.push_right) { if(keyState.push_left) { selectNum = 0; } else { selectNum = slctCnt -1; } bSetCursor = TRUE; } if(bSetCursor) { point.x = selectRect[selectNum].left + 30; point.y = selectRect[selectNum].top + 20; SetWindowCursorPos(sysInf.hWnd, point.x, point.y); } if(oldSelect!=selectNum && selectNum>=0) { PlayEffectNum(evtHandle[1],CurMoveSnd); } return -1; } // SelectWnd::selectExec
/* update returns false if enter has been pressed, true otherwise */ bool TCOD_text_update (TCOD_text_t txt, TCOD_key_t key) { int cx,cy,oldpos; text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return false; oldpos = data->cursor_pos; /* for real-time keyboard : only on key release */ if ( key.pressed ) { /* process keyboard input */ switch (key.vk) { case TCODK_BACKSPACE: /* get rid of the last character */ if ( data->sel_start != MAX_INT ) { deleteSelection(data); } else { deleteChar(data); } break; case TCODK_DELETE: if ( key.shift ) { /* SHIFT-DELETE : cut to clipboard */ cut(data); } else { if ( data->sel_start != MAX_INT ) { deleteSelection(data); } else if ( data->text[data->cursor_pos] ) { data->cursor_pos++; deleteChar(data); } } break; /* shift + arrow / home / end = selection */ /* ctrl + arrow = word skipping. ctrl + shift + arrow = word selection */ case TCODK_LEFT: if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } if ( data->cursor_pos > 0 ) { if ( key.lctrl || key.rctrl ) { previous_word(data); } else data->cursor_pos--; selectStart(data,oldpos,key); } break; case TCODK_RIGHT: if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } if ( data->text[data->cursor_pos] ) { if ( key.lctrl || key.rctrl ) { next_word(data); } else data->cursor_pos++; selectEnd(data,oldpos,key); } break; case TCODK_UP : get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } set_cursor_pos(data,cx,cy-1,false); selectStart(data,oldpos,key); break; case TCODK_DOWN : get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } set_cursor_pos(data,cx,cy+1,false); selectEnd(data,oldpos,key); break; case TCODK_HOME: get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } if ( key.lctrl || key.rctrl ) { set_cursor_pos(data,0,0,true); } else { set_cursor_pos(data,0,cy,true); } selectStart(data,oldpos,key); break; case TCODK_END: get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } if ( key.lctrl || key.rctrl ) { set_cursor_pos(data,data->w,data->h,true); } else { set_cursor_pos(data,data->w-1,cy,true); } selectEnd(data,oldpos,key); break; case TCODK_ENTER: /* validate input */ case TCODK_KPENTER: if ( data->sel_start != MAX_INT ) { deleteSelection(data); } if ( data->multiline ) { get_cursor_coords(data,&cx,&cy); if ( cy < data->h-1 ) insertChar(data,'\n'); } else { data->input_continue = false; } break; case TCODK_TAB : if (data->tab_size ) { int count=data->tab_size; if ( data->sel_start != MAX_INT ) { deleteSelection(data); } while ( count > 0 ) { insertChar(data,' '); count--; } } break; default: { /* append a new character */ if ( (key.c == 'c' || key.c=='C' || key.vk == TCODK_INSERT) && (key.lctrl || key.rctrl) ) { /* CTRL-C or CTRL-INSERT : copy to clipboard */ copy(data); } else if ( (key.c == 'x' || key.c=='X') && (key.lctrl || key.rctrl) ) { /* CTRL-X : cut to clipboard */ cut(data); } else if ( ((key.c == 'v' || key.c=='V') && (key.lctrl || key.rctrl)) || ( key.vk == TCODK_INSERT && key.shift ) ) { /* CTRL-V or SHIFT-INSERT : paste from clipboard */ paste(data); } else if (key.c > 31) { if ( data->sel_start != MAX_INT ) { deleteSelection(data); } insertChar(data,(char)(key.c)); } break; } } } return data->input_continue; }
void NanoInk::redrawText() { InkStyle& skin = this->skin(); nvgResetDisplayList(mTextCache); nvgBindDisplayList(mCtx, mTextCache); float left = mFrame.cleft(); float top = mFrame.ctop(); float width = mFrame.cwidth(); float height = mFrame.cheight(); float pleft = mFrame.pleft(); float ptop = mFrame.ptop(); float pwidth = mFrame.pwidth(); float pheight = mFrame.pheight(); float contentWidth = contentSize(DIM_X) - skin.padding()[DIM_X] - skin.padding()[DIM_X + 2]; float contentHeight = contentSize(DIM_Y) - skin.padding()[DIM_Y] - skin.padding()[DIM_Y + 2]; float cleft = pleft; NVGalign halign = NVG_ALIGN_LEFT; if(skin.align()[DIM_X] == CENTER) { halign = NVG_ALIGN_CENTER; cleft = pleft + pwidth / 2.f - contentWidth / 2.f; } else if(skin.align()[DIM_X] == RIGHT) { halign = NVG_ALIGN_RIGHT; cleft = pleft + pwidth - contentWidth; } float ctop = ptop; if(skin.align()[DIM_Y] == CENTER) ctop = ptop + pheight / 2.f - contentHeight / 2.f; else if(skin.align()[DIM_Y] == RIGHT) ctop = ptop + pheight - contentHeight; // Caption if(!mFrame.widget().label().empty() && !(pwidth <= 0.f || pheight <= 0.f)) { //if(mFrame.dclip(DIM_X) || mFrame.dclip(DIM_Y)) // ^ @note this doesn't work because a frame is set to clipped only by its parent, and not when the label is larger than the frame itself nvgScissor(mCtx, left, top, width, height); this->setupText(); float lineh = 0.f; nvgTextMetrics(mCtx, NULL, NULL, &lineh); const char* start = mFrame.widget().label().c_str(); float x = pleft; float y = ptop; for(NVGtextRow& row : mTextRows) { if(halign & NVG_ALIGN_LEFT) x = pleft; else if(halign & NVG_ALIGN_CENTER) x = pleft + pwidth*0.5f - row.width*0.5f; else if(halign & NVG_ALIGN_RIGHT) x = pleft + pwidth - row.width; if(mSelectFirst != mSelectSecond) { size_t indexStart = row.start - start; size_t indexEnd = row.end - start; if(indexEnd > selectStart() && indexStart < selectEnd()) { size_t selectStart = std::max(indexStart, this->selectStart()); size_t selectEnd = std::min(indexEnd, this->selectEnd()); NVGglyphPosition startPosition; nvgTextGlyphPosition(mCtx, 0.f, 0.f, row.start, row.end, selectStart - (row.start - start), &startPosition); NVGglyphPosition endPosition; nvgTextGlyphPosition(mCtx, 0.f, 0.f, row.start, row.end, selectEnd - (row.start - start), &endPosition); nvgBeginPath(mCtx); nvgFillColor(mCtx, nvgRGBA(0, 55, 255, 124)); nvgRect(mCtx, x + startPosition.x, y, endPosition.x - startPosition.x, lineh); nvgFill(mCtx); } } nvgFillColor(mCtx, nvgColour(skin.mTextColour)); nvgText(mCtx, x, y, row.start, row.end); y += lineh; } /* nvgText(mCtx, cleft, ctop, mFrame.widget().label().c_str(), nullptr); */ nvgResetScissor(mCtx); } if(mFrame.dclip(DIM_X) || mFrame.dclip(DIM_Y)) nvgResetScissor(mCtx); nvgBindDisplayList(mCtx, nullptr); }