[Aptitude-svn-commit] r3501 - in branches/aptitude-0.3/aptitude: . src/vscreen
Daniel Burrows
dburrows@costa.debian.org
Tue, 28 Jun 2005 14:00:00 +0000
Author: dburrows
Date: Tue Jun 28 13:59:58 2005
New Revision: 3501
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.cc
branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.h
Log:
Honor wide character widths in the line editor..maybe.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Tue Jun 28 13:59:58 2005
@@ -1,5 +1,10 @@
2005-06-28 Daniel Burrows <dburrows@debian.org>
+ * src/vscreen/vs_editline.cc, src/vscreen/vs_editline.h:
+
+ Fix the line editor widget to support wide characters properly
+ (it now honors wide character widths).
+
* src/vscreen/curses++.h:
#undef the *add_wch functions for future use.
Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.cc (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.cc Tue Jun 28 13:59:58 2005
@@ -69,32 +69,68 @@
do_layout.connect(sigc::mem_fun(*this, &vs_editline::normalize_cursor));
}
+wchar_t vs_editline::get_char(size_t loc)
+{
+ if(loc>prompt.size())
+ return text[loc-prompt.size()];
+ else
+ return prompt[loc];
+}
+
void vs_editline::normalize_cursor()
{
// Dodge the signedness bullet, hopefully
if(get_width()<0)
return;
- wstring::size_type w=(wstring::size_type) get_width();
+ int w=get_width();
+
+ int promptwidth=wcswidth(prompt.c_str(), prompt.size());
+ int textwidth=wcswidth(text.c_str(), text.size());
+
+ int cursorx=0;
+ if(curloc+prompt.size()>startloc)
+ for(size_t i=startloc; i<curloc+prompt.size(); ++i)
+ cursorx+=wcwidth(get_char(i));
+ else
+ for(size_t i=curloc+prompt.size(); i<startloc; ++i)
+ cursorx-=wcwidth(get_char(i));
- if(prompt.size()+text.size()+1<w)
+ if(promptwidth+textwidth+1<w)
startloc=0;
else if(w>2)
{
- // The extra 2 is to avoid "I'm typing and I can't see what comes next"
- // problems.
- if(prompt.size()+curloc-startloc>=w-2)
- startloc=prompt.size()+curloc-w+2;
+ // Need to move the screen start to this far behind the cursor
+ // loc.
+ int decamt=0;
- if(prompt.size()+curloc>=2 && prompt.size()+curloc<startloc+2)
- startloc=prompt.size()+curloc-2;
+ if(cursorx>=w-2)
+ decamt=2;
+ else if(cursorx<2)
+ decamt=w-2;
+
+ // Do it by moving back this many chars
+ size_t chars=0;
+
+ while(decamt>0 && chars<curloc+prompt.size())
+ {
+ ++chars;
+ decamt-=wcwidth(get_char(prompt.size()+curloc-chars));
+ }
+
+ if(decamt<0 && chars>1)
+ --chars;
+
+ startloc=curloc-chars;
}
else
{
- if(prompt.size()+curloc-startloc>=w)
+ // if width=1, use a primitive approach (we're screwed anyway in
+ // this case)
+ if(cursorx>=w)
startloc=prompt.size()+curloc-w+1;
- if(prompt.size()+curloc<startloc)
+ if(cursorx<0)
startloc=prompt.size()+curloc;
}
@@ -109,7 +145,14 @@
point vs_editline::get_cursorloc()
{
if(getmaxx()>0)
- return point(curloc+prompt.size()-startloc, 0);
+ {
+ int x=0;
+
+ for(size_t loc=startloc; loc<curloc+prompt.size(); ++loc)
+ x+=wcwidth(get_char(loc));
+
+ return point(x, 0);
+ }
else
return point(0,0);
}
@@ -302,14 +345,38 @@
{
int width=getmaxx();
- wstring todisp(prompt+text, startloc, width);
+ int used=0;
+ size_t chars=0;
+
+ while(used<width && startloc+chars<prompt.size()+text.size())
+ {
+ wchar_t ch=get_char(startloc+chars);
+ used+=wcwidth(ch);
+ ++chars;
+ }
+
+ if(used>width && chars>1)
+ --chars;
- mvaddstr(0, 0, todisp);
+ wstring todisp=prompt+text;
+ mvaddstr(0, 0, wstring(todisp, startloc, chars));
}
void vs_editline::dispatch_mouse(short id, int x, int y, int z, mmask_t bstate)
{
- wstring::size_type mouseloc=x+startloc;
+ size_t mouseloc=startloc; // The character at which the mouse press occured
+ while(mouseloc<prompt.size()+text.size() && x>0)
+ {
+ int curwidth=wcwidth(get_char(mouseloc));
+
+ if(curwidth>x)
+ break;
+ else
+ {
+ ++mouseloc;
+ x-=curwidth;
+ }
+ }
if(mouseloc>=prompt.size())
{
@@ -317,7 +384,7 @@
if(mouseloc<=text.size())
curloc=mouseloc;
- else if(mouseloc>text.size())
+ else
curloc=text.size();
}
else
@@ -377,7 +444,7 @@
int vs_editline::width_request()
{
if(desired_size == -1)
- return prompt.size()+text.size()+1;
+ return wcswidth(prompt.c_str(), prompt.size())+wcswidth(text.c_str(), text.size());
else
return desired_size;
}
Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.h (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_editline.h Tue Jun 28 13:59:58 2005
@@ -38,6 +38,11 @@
bool using_history;
void normalize_cursor();
+
+ /** \return the nth char of the visual representation (from either
+ * the prompt or the string being edited)
+ */
+ wchar_t get_char(size_t n);
protected:
bool handle_key(const key &k);
public: