Step 196: high contrast and colorblind modes
This commit is contained in:
@@ -174,13 +174,27 @@
|
||||
float x = xStart;
|
||||
float amp = 2.0f;
|
||||
bool up = true;
|
||||
int segment = 0;
|
||||
bool dotted = (d.severity != 1 && d.severity != 2);
|
||||
while (x < xEnd) {
|
||||
if (dotted) {
|
||||
drawList->AddCircleFilled(ImVec2(x, baseY), 1.3f, color);
|
||||
x += 4.0f;
|
||||
continue;
|
||||
}
|
||||
float x2 = std::min(x + 4.0f, xEnd);
|
||||
float y1 = baseY + (up ? -amp : amp);
|
||||
float y2 = baseY + (up ? amp : -amp);
|
||||
drawList->AddLine(ImVec2(x, y1), ImVec2(x2, y2), color, 1.0f);
|
||||
bool drawSegment = true;
|
||||
if (d.severity == 2) {
|
||||
drawSegment = (segment % 2 == 0);
|
||||
}
|
||||
if (drawSegment) {
|
||||
drawList->AddLine(ImVec2(x, y1), ImVec2(x2, y2), color, 1.0f);
|
||||
}
|
||||
up = !up;
|
||||
x = x2;
|
||||
segment++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,57 @@
|
||||
#pragma once
|
||||
// Included inside CodeEditorWidget (rendering + folds).
|
||||
public:
|
||||
static int annotationShapeIndex(const std::string& label) {
|
||||
size_t h = 0;
|
||||
for (unsigned char c : label) h = h * 131 + c;
|
||||
return (int)(h % 5);
|
||||
}
|
||||
|
||||
static void drawAnnotationShape(ImDrawList* drawList,
|
||||
const ImVec2& center,
|
||||
float size,
|
||||
ImU32 color,
|
||||
int shape) {
|
||||
switch (shape) {
|
||||
case 0: { // circle
|
||||
drawList->AddCircleFilled(center, size, color);
|
||||
break;
|
||||
}
|
||||
case 1: { // triangle
|
||||
ImVec2 top(center.x, center.y - size);
|
||||
ImVec2 left(center.x - size, center.y + size);
|
||||
ImVec2 right(center.x + size, center.y + size);
|
||||
drawList->AddTriangleFilled(top, left, right, color);
|
||||
break;
|
||||
}
|
||||
case 2: { // square
|
||||
ImVec2 a(center.x - size, center.y - size);
|
||||
ImVec2 b(center.x + size, center.y + size);
|
||||
drawList->AddRectFilled(a, b, color, 0.0f);
|
||||
break;
|
||||
}
|
||||
case 3: { // diamond
|
||||
ImVec2 top(center.x, center.y - size);
|
||||
ImVec2 right(center.x + size, center.y);
|
||||
ImVec2 bottom(center.x, center.y + size);
|
||||
ImVec2 left(center.x - size, center.y);
|
||||
drawList->AddQuadFilled(top, right, bottom, left, color);
|
||||
break;
|
||||
}
|
||||
default: { // star (outline)
|
||||
ImVec2 pts[10];
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
float angle = (float)(IM_PI * 0.5 + i * (IM_PI / 5.0));
|
||||
float radius = (i % 2 == 0) ? size : size * 0.5f;
|
||||
pts[i] = ImVec2(center.x + std::cos(angle) * radius,
|
||||
center.y - std::sin(angle) * radius);
|
||||
}
|
||||
drawList->AddPolyline(pts, 10, color, true, 1.5f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CodeEditorResult render(const char* id,
|
||||
std::string& text,
|
||||
const std::vector<HighlightSpan>& spans,
|
||||
@@ -370,7 +421,12 @@ public:
|
||||
AnnotationMarker marker;
|
||||
if (annotationAtLine(*options.annotations, ln, marker)) {
|
||||
ImVec2 center(origin.x + 12.0f, y + lineHeight * 0.5f);
|
||||
drawList->AddCircleFilled(center, 3.0f, marker.color);
|
||||
if (options.useAnnotationShapes) {
|
||||
int shape = annotationShapeIndex(marker.message);
|
||||
drawAnnotationShape(drawList, center, 3.5f, marker.color, shape);
|
||||
} else {
|
||||
drawList->AddCircleFilled(center, 3.0f, marker.color);
|
||||
}
|
||||
ImVec2 a(center.x - 4.0f, center.y - 4.0f);
|
||||
ImVec2 b(center.x + 4.0f, center.y + 4.0f);
|
||||
bool hoverAnno = ImGui::IsMouseHoveringRect(a, b);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
struct MultiCursor {
|
||||
@@ -34,6 +35,7 @@ struct CodeEditorOptions {
|
||||
bool showAnnotations = false;
|
||||
bool showLineNumbers = true;
|
||||
bool showCurrentLine = true;
|
||||
bool useAnnotationShapes = true;
|
||||
float lineHeightScale = 1.0f;
|
||||
float letterSpacing = 0.0f;
|
||||
float cursorBlinkRate = 2.0f;
|
||||
|
||||
@@ -58,6 +58,8 @@ public:
|
||||
void setShowLineNumbers(bool value) { showLineNumbers_ = value; }
|
||||
bool getReduceMotion() const { return reduceMotion_; }
|
||||
void setReduceMotion(bool value) { reduceMotion_ = value; }
|
||||
bool getUseAnnotationShapes() const { return useAnnotationShapes_; }
|
||||
void setUseAnnotationShapes(bool value) { useAnnotationShapes_ = value; }
|
||||
bool getBlockVulnerableImports() const { return blockVulnerableImports_; }
|
||||
void setBlockVulnerableImports(bool value) { blockVulnerableImports_ = value; }
|
||||
const std::string& getLayoutPreset() const { return layoutPreset_; }
|
||||
@@ -85,6 +87,7 @@ public:
|
||||
showMinimap_ = j.value("showMinimap", showMinimap_);
|
||||
showLineNumbers_ = j.value("showLineNumbers", showLineNumbers_);
|
||||
reduceMotion_ = j.value("reduceMotion", reduceMotion_);
|
||||
useAnnotationShapes_ = j.value("useAnnotationShapes", useAnnotationShapes_);
|
||||
blockVulnerableImports_ = j.value("blockVulnerableImports", blockVulnerableImports_);
|
||||
layoutPreset_ = j.value("layoutPreset", layoutPreset_);
|
||||
keybindingProfile_ = j.value("keybindingProfile", keybindingProfile_);
|
||||
@@ -124,6 +127,7 @@ public:
|
||||
j["showMinimap"] = showMinimap_;
|
||||
j["showLineNumbers"] = showLineNumbers_;
|
||||
j["reduceMotion"] = reduceMotion_;
|
||||
j["useAnnotationShapes"] = useAnnotationShapes_;
|
||||
j["blockVulnerableImports"] = blockVulnerableImports_;
|
||||
j["layoutPreset"] = layoutPreset_;
|
||||
j["keybindingProfile"] = keybindingProfile_;
|
||||
@@ -200,6 +204,7 @@ private:
|
||||
bool showMinimap_ = false;
|
||||
bool showLineNumbers_ = true;
|
||||
bool reduceMotion_ = false;
|
||||
bool useAnnotationShapes_ = true;
|
||||
bool blockVulnerableImports_ = false;
|
||||
std::string layoutPreset_ = "VSCode";
|
||||
std::string keybindingProfile_ = "VSCode";
|
||||
|
||||
@@ -47,6 +47,8 @@ struct ThemeDefinition {
|
||||
std::string sourcePath;
|
||||
ImVec2 panelPadding = ImVec2(8.0f, 6.0f);
|
||||
ImVec2 panelSpacing = ImVec2(8.0f, 6.0f);
|
||||
float windowBorderSize = 1.0f;
|
||||
float frameBorderSize = 0.0f;
|
||||
};
|
||||
|
||||
class ThemeEngine {
|
||||
@@ -326,6 +328,12 @@ private:
|
||||
out.panelSpacing.x = layout["panelSpacing"][0].get<float>();
|
||||
out.panelSpacing.y = layout["panelSpacing"][1].get<float>();
|
||||
}
|
||||
if (layout.contains("windowBorderSize")) {
|
||||
out.windowBorderSize = layout["windowBorderSize"].get<float>();
|
||||
}
|
||||
if (layout.contains("frameBorderSize")) {
|
||||
out.frameBorderSize = layout["frameBorderSize"].get<float>();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -339,6 +347,8 @@ private:
|
||||
}
|
||||
style.WindowPadding = theme.panelPadding;
|
||||
style.ItemSpacing = theme.panelSpacing;
|
||||
style.WindowBorderSize = theme.windowBorderSize;
|
||||
style.FrameBorderSize = theme.frameBorderSize;
|
||||
}
|
||||
|
||||
static bool isSyntaxColor(ThemeColor color) {
|
||||
|
||||
@@ -624,6 +624,7 @@ static void renderBottomPanel(EditorState& state) {
|
||||
leftOpts.showWhitespace = state.ui.showWhitespace;
|
||||
leftOpts.showLineNumbers = state.ui.showLineNumbers;
|
||||
leftOpts.showCurrentLine = false;
|
||||
leftOpts.useAnnotationShapes = state.settings.getUseAnnotationShapes();
|
||||
leftOpts.lineHeightScale = state.settings.getLineHeightScale();
|
||||
leftOpts.letterSpacing = state.settings.getLetterSpacing();
|
||||
leftOpts.highlightLines = &state.diff.beforeLines;
|
||||
@@ -641,6 +642,7 @@ static void renderBottomPanel(EditorState& state) {
|
||||
rightOpts.showWhitespace = state.ui.showWhitespace;
|
||||
rightOpts.showLineNumbers = state.ui.showLineNumbers;
|
||||
rightOpts.showCurrentLine = false;
|
||||
rightOpts.useAnnotationShapes = state.settings.getUseAnnotationShapes();
|
||||
rightOpts.lineHeightScale = state.settings.getLineHeightScale();
|
||||
rightOpts.letterSpacing = state.settings.getLetterSpacing();
|
||||
rightOpts.highlightLines = &state.diff.afterLines;
|
||||
|
||||
@@ -216,6 +216,7 @@ static void renderEditorPanel(EditorState& state) {
|
||||
opts.showMinimap = state.ui.showMinimap;
|
||||
opts.showAnnotations = state.ui.showAnnotations;
|
||||
opts.showLineNumbers = state.ui.showLineNumbers;
|
||||
opts.useAnnotationShapes = state.settings.getUseAnnotationShapes();
|
||||
opts.lineHeightScale = state.settings.getLineHeightScale();
|
||||
opts.letterSpacing = state.settings.getLetterSpacing();
|
||||
opts.cursorBlinkRate = state.settings.getCursorBlinkRate();
|
||||
|
||||
@@ -349,6 +349,11 @@ static void renderSettingsPanel(EditorState& state) {
|
||||
state.settings.setReduceMotion(reduceMotionSetting);
|
||||
settingsChanged = true;
|
||||
}
|
||||
bool useAnnotationShapes = state.settings.getUseAnnotationShapes();
|
||||
if (ImGui::Checkbox("Use Shapes for Annotations", &useAnnotationShapes)) {
|
||||
state.settings.setUseAnnotationShapes(useAnnotationShapes);
|
||||
settingsChanged = true;
|
||||
}
|
||||
bool blockVulnImports = state.settings.getBlockVulnerableImports();
|
||||
if (ImGui::Checkbox("Block Vulnerable Imports", &blockVulnImports)) {
|
||||
state.settings.setBlockVulnerableImports(blockVulnImports);
|
||||
|
||||
Reference in New Issue
Block a user