mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-30 23:02:39 -06:00
CtrlLib: Coco MultiButton
git-svn-id: svn://ultimatepp.org/upp/trunk@12281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6deb92c93e
commit
85ef74e429
10 changed files with 143 additions and 17 deletions
|
|
@ -63,7 +63,7 @@ CGGlyph GetCharGlyph(CTFontRef ctfont, int chr)
|
|||
return glyph_index;
|
||||
}
|
||||
|
||||
GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr, bool bold_synth)
|
||||
GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr, bool bold_synth, CGRect *bounds = NULL)
|
||||
{
|
||||
GlyphInfo gi;
|
||||
gi.lspc = gi.rspc = 0;
|
||||
|
|
@ -79,6 +79,10 @@ GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr, bool bold_synth)
|
|||
gi.glyphi = glyph_index;
|
||||
if(bold_synth)
|
||||
gi.width++;
|
||||
if(bounds)
|
||||
CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontOrientationHorizontal,
|
||||
&glyph_index, bounds, 1);
|
||||
|
||||
}
|
||||
}
|
||||
return gi;
|
||||
|
|
@ -101,10 +105,33 @@ CommonFontInfo GetFontInfoSys(Font font)
|
|||
DDUMP(CTFontGetUnderlinePosition(ctfont));
|
||||
DDUMP(MakeRect(CTFontGetBoundingBox(ctfont)));
|
||||
DDUMPHEX(CTFontGetSymbolicTraits(ctfont));
|
||||
DDUMP(font);
|
||||
CGRect cr = CTFontGetBoundingBox(ctfont);
|
||||
DDUMP(cr.origin.y);
|
||||
DDUMP(cr.size.height);
|
||||
DDUMP(cr.origin.y + cr.size.height);
|
||||
#endif
|
||||
fi.descent = ceil(CTFontGetDescent(ctfont));
|
||||
fi.ascent = ceil(CTFontGetAscent(ctfont));
|
||||
fi.external = ceil(CTFontGetLeading(ctfont));
|
||||
|
||||
// Some MacOS fonts have really weird ascent/descents (namely stadard GUI font...)
|
||||
// let us fix it by testing typical charactes bounding boxes
|
||||
|
||||
static WString descent_test = "yjgp";
|
||||
CGRect bb;
|
||||
for(int i = 0; i < descent_test.GetCount(); i++)
|
||||
if(GetGlyphInfoSys(ctfont, descent_test[i], synth && font.IsBold(), &bb).IsNormal())
|
||||
fi.descent = max(fi.descent, (int)ceil(-bb.origin.y));
|
||||
|
||||
int ascent = fi.ascent;
|
||||
static WString ascent_test = "ÀÁÂÃÄË";
|
||||
for(int i = 0; i < ascent_test.GetCount(); i++)
|
||||
if(GetGlyphInfoSys(ctfont, ascent_test[i], synth && font.IsBold(), &bb).IsNormal())
|
||||
ascent = max(ascent, (int)ceil(bb.origin.y + bb.size.height));
|
||||
|
||||
fi.ascent = ascent;
|
||||
|
||||
fi.internal = 0;
|
||||
fi.overhang = 0;
|
||||
fi.maxwidth = GetGlyphInfoSys(ctfont, 'W', synth && font.IsBold()).width; // TODO?
|
||||
|
|
@ -138,7 +165,7 @@ Vector<FaceInfo> GetAllFacesSys()
|
|||
{
|
||||
Index<String> facename;
|
||||
|
||||
facename.Add("Arial"); // TODO: This should be default GUI font
|
||||
facename.Add("Arial"); // This is default GUI font, changed afterward
|
||||
facename.Add("Times New Roman");
|
||||
facename.Add("Arial");
|
||||
facename.Add("Courier New");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
sooner:
|
||||
|
||||
- Assist popup has vertically missaligned text
|
||||
- initial focus in uword
|
||||
- clang install
|
||||
- Information etc.. Images
|
||||
- Ctrl gets stuck
|
||||
- fix package organiser link options (joining link options missing space)
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void CocoButton(Button::Style& s, int type, int value)
|
|||
s.look[i] = h[i];
|
||||
Image gg = CreateImage(h[i].GetSize(), SColorFace());
|
||||
Over(gg, h[i]);
|
||||
s.textcolor[i] = i == CTRL_DISABLED ? SColorDisabled()
|
||||
s.monocolor[i] = s.textcolor[i] = i == CTRL_DISABLED ? SColorDisabled()
|
||||
: Grayscale(AvgColor(gg, h[i].GetSize().cy / 3)) > 160 ? SColorText()
|
||||
: White();
|
||||
}
|
||||
|
|
@ -103,6 +103,25 @@ Color CocoColor(int k, Color bg = SColorFace())
|
|||
return AvgColor(Coco_ThemeImage(bg, 16, 16, 0, COCO_NSCOLOR, k));
|
||||
}
|
||||
|
||||
Color GetInkColor(const Image& m)
|
||||
{
|
||||
int x = m.GetSize().cx / 2;
|
||||
bool dark = !IsDark(SColorText());
|
||||
int best = 1000;
|
||||
Color bestc = SColorText();
|
||||
for(int y = 0; y < m.GetHeight(); y++) {
|
||||
Color c = m[y][x];
|
||||
int g = Grayscale(c);
|
||||
if(dark)
|
||||
g = 255 - g;
|
||||
if(g < best) {
|
||||
best = g;
|
||||
bestc = c;
|
||||
}
|
||||
}
|
||||
return bestc;
|
||||
}
|
||||
|
||||
void ChHostSkin()
|
||||
{
|
||||
CtrlImg::Reset();
|
||||
|
|
@ -115,6 +134,8 @@ void ChHostSkin()
|
|||
DUMP(Coco_Metric(0)); // kThemeMetricScrollBarWidth
|
||||
DUMP(Coco_Metric(7)); // kThemeMetricFocusRectOutset
|
||||
DUMP(Coco_Metric(19)); // kThemeMetricPushButtonHeight
|
||||
|
||||
int button_height = Coco_Metric(19); // kThemeMetricPushButtonHeight
|
||||
|
||||
|
||||
SwapOKCancel_Write(true);
|
||||
|
|
@ -185,6 +206,7 @@ void ChHostSkin()
|
|||
Image thumb = Coco_ThemeImage(s.barsize, 50, 0, COCO_SCROLLTHUMB, 0, status);
|
||||
Rect bounds = FindBounds(thumb);
|
||||
thumb = Crop(thumb, Rect(0, bounds.top, thumb.GetWidth(), bounds.bottom));
|
||||
thumb = AddMargins(thumb, 0, 1, 0, 1, RGBAZero());
|
||||
s.vthumb[status] = Hot3(thumb);
|
||||
|
||||
s.hupper[status] = s.hlower[status] =
|
||||
|
|
@ -192,9 +214,45 @@ void ChHostSkin()
|
|||
thumb = Coco_ThemeImage(50, s.barsize, 0, COCO_SCROLLTHUMB, 1, status);
|
||||
bounds = FindBounds(thumb);
|
||||
thumb = Crop(thumb, Rect(bounds.left, 0, bounds.right, thumb.GetHeight()));
|
||||
thumb = AddMargins(thumb, 1, 0, 1, 0 , RGBAZero());
|
||||
s.hthumb[status] = Hot3(thumb);
|
||||
}
|
||||
}
|
||||
|
||||
ColoredOverride(CtrlsImg::Iml(), CtrlsImg::Iml());
|
||||
|
||||
{
|
||||
|
||||
Color e = GetInkColor(Coco_ThemeImage(SColorFace(), 100, 50, 10, COCO_COMBOBOX));
|
||||
CtrlsImg::Set(CtrlsImg::I_EFE,
|
||||
WithHotSpots(AddMargins(CreateImage(Size(1, 1), SColorPaper()), 1, 1, 1, 1, e),
|
||||
1, 1, 0, 0));
|
||||
|
||||
CtrlsImg::Set(CtrlsImg::I_VE,
|
||||
WithHotSpots(AddMargins(CreateImage(Size(3, 3), SColorPaper()), 1, 1, 1, 1, e),
|
||||
2, 2, 0, 0));
|
||||
|
||||
MultiButton::Style& s = MultiButton::StyleDefault().Write();
|
||||
// s.trivialsep = true;
|
||||
// s.edge[0] = Null;
|
||||
s.clipedge = true;
|
||||
s.border = s.trivialborder = 0;
|
||||
|
||||
for(int i = CTRL_NORMAL; i <= CTRL_DISABLED; i++) {
|
||||
Image m = Coco_ThemeImage(150, button_height + 1, 0, COCO_BUTTON, 1, i); // TODO: ChWithOffset...
|
||||
Size isz = m.GetSize();
|
||||
int x3 = isz.cx / 3;
|
||||
s.left[i] = Hot3(Crop(m, 0, 0, x3, isz.cy));
|
||||
s.trivial[i] = s.look[i] = s.right[i] = Hot3(Crop(m, 2 * x3, 0, isz.cx - 2 * x3, isz.cy));
|
||||
m = Crop(m, x3, 0, x3, isz.cy);
|
||||
s.lmiddle[i] = Hot3(AddMargins(m, 1, 0, 0, 0, SColorPaper()));
|
||||
s.rmiddle[i] = Hot3(AddMargins(m, 0, 0, 1, 0, SColorPaper()));
|
||||
|
||||
s.monocolor[i] = s.fmonocolor[i] = Button::StyleOk().monocolor[i];
|
||||
// Win32Look(s.look[i], XP_COMBOBOX, 4, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DDUMP(Coco_ThemeColor(1));
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ enum ChCocoControlTypes {
|
|||
COCO_RADIOBUTTON,
|
||||
COCO_BEVELBUTTON,
|
||||
COCO_ROUNDEDBUTTON,
|
||||
COCO_COMBOBOX,
|
||||
COCO_SCROLLTHUMB,
|
||||
COCO_SCROLLTRACK,
|
||||
COCO_BRUSH,
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ void Coco_ThemePaint(void *cgcontext, const Upp::Rect& r, int type, int value, i
|
|||
COCO_RADIOBUTTON, (int)kThemeRadioButton,
|
||||
COCO_BEVELBUTTON, (int)kThemeBevelButtonMedium,
|
||||
COCO_ROUNDEDBUTTON, (int)kThemeRoundedBevelButton,
|
||||
COCO_COMBOBOX, (int)kThemeComboBox,
|
||||
(int)kThemePushButtonNormal);
|
||||
#ifdef _DEBUG
|
||||
if(type < 0)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ bool MultiButton::GetPos(SubButton& b, int& lx, int& rx, int& x, int& cx, int px
|
|||
if(b.visible) {
|
||||
cx = Nvl(b.cx, style->stdwidth + tsz.cx);
|
||||
if(IsNull(b.cx) && tsz.cx > 0 && !IsNull(b.img))
|
||||
cx += LB_IMAGE + LB_MARGIN;
|
||||
cx += DPI(LB_IMAGE + LB_MARGIN);
|
||||
}
|
||||
else
|
||||
cx = 0;
|
||||
|
|
@ -263,6 +263,18 @@ void MultiButton::GetPos(int ii, int& x, int& cx)
|
|||
}
|
||||
}
|
||||
|
||||
void MultiButton::GetLR(int& lx, int& rx)
|
||||
{
|
||||
int border;
|
||||
Metrics(border, lx, rx);
|
||||
int x = 0;
|
||||
int cx = 0;
|
||||
for(int i = 0; i < button.GetCount(); i++) {
|
||||
SubButton& b = button[i];
|
||||
GetPos(b, lx, rx, x, cx);
|
||||
}
|
||||
}
|
||||
|
||||
int MultiButton::ChState(int i)
|
||||
{
|
||||
bool frm = Frame();
|
||||
|
|
@ -343,8 +355,16 @@ Rect MultiButton::Paint0(Draw& w, bool getcr)
|
|||
int border, lx, rx;
|
||||
bool frm = Metrics(border, lx, rx);
|
||||
int mst = ChState(MAIN);
|
||||
if(frm && !nobg && !getcr)
|
||||
if(frm && !nobg && !getcr) {
|
||||
if(style->clipedge) {
|
||||
int l, r;
|
||||
GetLR(l, r);
|
||||
w.Clip(l, 0, r - l, sz.cy);
|
||||
}
|
||||
ChPaint(w, sz, style->edge[style->activeedge ? mst : 0]);
|
||||
if(style->clipedge)
|
||||
w.End();
|
||||
}
|
||||
bool left = false;
|
||||
bool right = false;
|
||||
for(int i = 0; i < button.GetCount(); i++) {
|
||||
|
|
@ -394,22 +414,24 @@ Rect MultiButton::Paint0(Draw& w, bool getcr)
|
|||
Image m = tsz.cx > 0 ? b.img : (Image)Nvl(b.img, CtrlsImg::DA());
|
||||
Size isz = m.GetSize();
|
||||
Point p = (st == CTRL_PRESSED) * style->pressoffset;
|
||||
p.x += x + (cx - isz.cx - tsz.cx - (tsz.cx > 0 && isz.cx > 0 ? LB_IMAGE : 0)) / 2;
|
||||
p.x += x + (cx - isz.cx - tsz.cx - (tsz.cx > 0 && isz.cx > 0 ? DPI(LB_IMAGE) : 0)) / 2;
|
||||
p.y += (sz.cy - isz.cy) / 2;
|
||||
if(b.left) {
|
||||
if(!left) p.x += style->loff;
|
||||
}
|
||||
else
|
||||
if(!right) p.x += style->roff;
|
||||
|
||||
Color ink = frm ? style->fmonocolor[st] : style->monocolor[st];
|
||||
if(b.monoimg || IsNull(b.img))
|
||||
w.DrawImage(p.x, p.y, m, frm ? style->fmonocolor[st] : style->monocolor[st]);
|
||||
w.DrawImage(p.x, p.y, m, ink);
|
||||
else
|
||||
w.DrawImage(p.x, p.y, m);
|
||||
|
||||
if(tsz.cx > 0) {
|
||||
if(isz.cx > 0)
|
||||
p.x += isz.cx + LB_IMAGE;
|
||||
w.DrawText(p.x, (sz.cy - tsz.cy) / 2, b.label);
|
||||
p.x += isz.cx + DPI(LB_IMAGE);
|
||||
w.DrawText(p.x, (sz.cy - tsz.cy) / 2, b.label, StdFont(), ink);
|
||||
}
|
||||
}
|
||||
(b.left ? left : right) = true;
|
||||
|
|
|
|||
|
|
@ -21,26 +21,27 @@ public:
|
|||
Value edge[4];
|
||||
bool activeedge;
|
||||
Value look[4];
|
||||
Value left[4];
|
||||
Value lmiddle[4];
|
||||
Value right[4];
|
||||
Value rmiddle[4];
|
||||
Value left[4]; // leftmost button on the left side
|
||||
Value lmiddle[4]; // other buttons on the left size
|
||||
Value right[4]; // rightmost button on the right side
|
||||
Value rmiddle[4]; // other buttons on the right size
|
||||
Value simple[4];
|
||||
int border;
|
||||
Value trivial[4];
|
||||
int trivialborder;
|
||||
Color monocolor[4];
|
||||
Color fmonocolor[4];
|
||||
Point pressoffset;
|
||||
Color monocolor[4]; // color of mono images and text in nonframe situation
|
||||
Color fmonocolor[4]; // color of mono images and text in frame situation
|
||||
Point pressoffset; // offset of images and text if button is pressed
|
||||
Value sep1, sep2;
|
||||
int sepm;
|
||||
int stdwidth;
|
||||
int stdwidth; // standard width of button
|
||||
bool trivialsep;
|
||||
bool usetrivial;
|
||||
Rect margin;
|
||||
int overpaint;
|
||||
int loff, roff;
|
||||
Color error;
|
||||
bool clipedge; // Clip border edge so that it does not paint area where are buttons
|
||||
};
|
||||
|
||||
class SubButton {
|
||||
|
|
@ -109,6 +110,7 @@ private:
|
|||
int FindButton(int px);
|
||||
void Margins(int& l, int& r);
|
||||
Rect ContentRect();
|
||||
void GetLR(int& lx, int& rx);
|
||||
bool GetPos(SubButton& b, int& lx, int& rx, int& x, int& cx, int px = -1);
|
||||
void GetPos(int ii, int& x, int& cx);
|
||||
int ChState(int i);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ struct CommonFontInfo {
|
|||
bool fixedpitch;
|
||||
bool scaleable;
|
||||
bool ttf;
|
||||
int aux;
|
||||
|
||||
char path[256]; // optional
|
||||
};
|
||||
|
|
|
|||
|
|
@ -166,6 +166,15 @@ Image Crop(const Image& img, const Rect& rc)
|
|||
return WithResolution(tgt, img);
|
||||
}
|
||||
|
||||
Image AddMargins(const Image& img, int left, int top, int right, int bottom, RGBA color)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
ImageBuffer ib(sz.cx + left + right, sz.cy + top + bottom);
|
||||
Fill(ib, color, ib.GetLength());
|
||||
Copy(ib, Point(left, top), img, img.GetSize());
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image Crop(const Image& img, int x, int y, int cx, int cy)
|
||||
{
|
||||
return Crop(img, RectC(x, y, cx, cy));
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ void Crop(RasterEncoder& tgt, Raster& img, const Rect& rc);
|
|||
Image Crop(const Image& img, const Rect& rc);
|
||||
Image Crop(const Image& img, int x, int y, int cx, int cy);
|
||||
|
||||
Image AddMargins(const Image& img, int left, int top, int right, int bottom, RGBA color);
|
||||
|
||||
Rect FindBounds(const Image& m, RGBA bg = RGBAZero());
|
||||
Image AutoCrop(const Image& m, RGBA bg = RGBAZero());
|
||||
void AutoCrop(Image *m, int count, RGBA bg = RGBAZero());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue