Jump to content

klepto2

1,172 views

 Share

Hi, 

I finally managed to build a first release candidate for a SyntaxEditor-Widget. The Widget is using the famous Scintilla TextEditor-Component under the hood and wraps the control into a UAK-Widget.  At this point i only provide binaries (includes and libraries) but i am currently preparing to release the source as well. 

The source itself is semi-autogenerated with a manual created body and a tool which generates the main part of the Scintilla-Component based of so called iFace files maintained by the Scintilla author (these files contains the definitions of each enum or function you can use with Scintilla).

 

Downloads:

Demo (Small sample): Demo.zip

Libraries and Headers:SyntaxEditor_libinc.zip

To use the new widget you need to copy the content of the zip into your project and add the "include" directory to  "Additional Include Directories" and add the 
the path to the Library to "Additional Library Directories" (for Release and Debug configurations).  Finally you need to add the needed lib files to "Additional Dependecies": 

Imm32.lib
SyntaxWidget.lib
Lexilla.lib
Scintilla.lib

 

here is screenshot of the small demo app:

Scintilla_demo.thumb.png.f4d4f5247e28cbb61da0e221848c7898.png

and the code:

#include "UltraEngine.h"
#include "SyntaxWidget.h"
#include "ScintillaLexer.hpp"

using namespace UltraEngine;


int main(int argc, const char* argv[])
{
#ifdef _WIN64
    auto plugin = LoadPlugin("Plugins/FITextureLoader.*");
#else
    auto plugin = LoadPlugin("Plugins (x86)/FITextureLoader.*");
#endif
    if (plugin == NULL)
    {
        Print("Failed to load FreeImage plugin.");
        return 1;
    }

    //Get the displays
    auto displays = GetDisplays(); 
    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CENTER);
    //Create User Interface
    auto ui = CreateInterface(window);
    //Create widget
    auto sz = ui->root->GetSize();

    auto toggleVisibility = CreateButton("Visible", 10, 10, 80, 20, ui->root, ButtonStyle::BUTTON_TOGGLE);
    toggleVisibility->SetState(WidgetState::WIDGETSTATE_SELECTED);

    auto container = CreatePanel(5, 40, sz.x - 10, sz.y - 45, ui->root, PanelStyle::PANEL_BORDER);
    sz = container->ClientSize();
    container->SetLayout(1, 1, 1, 1);
    auto syntaxEditor = CreateSyntaxEditor(5, 5, sz.x - 10, sz.y - 10, container);
    syntaxEditor->SetLayout(1, 1, 1, 1);
    syntaxEditor->SetFoldFlags(FoldFlag::LineAfterContracted | FoldFlag::LineBeforeContracted); // 16  	Draw line below if not expanded

    //auto lualexer = CreateLexer("lua");
   // syntaxEditor->SetILexer(lualexer);
    auto lexer = CreateLuaLexer(syntaxEditor);
    syntaxEditor->SetKeyWords(0, "and break do else elseif end for function if in local nil not or repeat return then until while");
    syntaxEditor->SetKeyWords(1, "print require");
    syntaxEditor->SetProperty("fold", "1");
    syntaxEditor->SetProperty("fold.compact", "0");
    syntaxEditor->SetAutomaticFold(AutomaticFold::Change | AutomaticFold::Click | AutomaticFold::Show);
    syntaxEditor->SetMarginSensitiveN(2, 1);
    auto luasource = R"V0G0N(require("INC_Class.lua")
--========================== =

cAnimal = setclass("Animal")

function cAnimal.methods:init(action, cutename)
self.superaction = action
self.supercutename = cutename
end

--==========================

cTiger = setclass("Tiger", cAnimal)

function cTiger.methods:init(cutename)
self : init_super("HUNT (Tiger)", "Zoo Animal (Tiger)")
self.action = "ROAR FOR ME!!"
self.cutename = cutename

function test()


end

end

--==========================

Tiger1 = cAnimal:new("HUNT", "Zoo Animal")
Tiger2 = cTiger : new("Mr Grumpy")
Tiger3 = cTiger : new("Mr Hungry")

print("CLASSNAME FOR TIGER1 = ", Tiger1:classname())
print("CLASSNAME FOR TIGER2 = ", Tiger2:classname())
print("CLASSNAME FOR TIGER3 = ", Tiger3:classname())
print("===============")
print("SUPER ACTION", Tiger1.superaction)
print("SUPER CUTENAME", Tiger1.supercutename)
print("ACTION        ", Tiger1.action)
print("CUTENAME", Tiger1.cutename)
print("===============")
print("SUPER ACTION", Tiger2.superaction)
print("SUPER CUTENAME", Tiger2.supercutename)
print("ACTION        ", Tiger2.action)
print("CUTENAME", Tiger2.cutename)
print("===============")
print("SUPER ACTION", Tiger3.superaction)
print("SUPER CUTENAME", Tiger3.supercutename)
print("ACTION        ", Tiger3.action)
print("CUTENAME", Tiger3.cutename))V0G0N";
    String s = luasource;

    syntaxEditor->SetText(s.c_str());
    syntaxEditor->StyleSetBack(STYLE_DEFAULT, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255));
    syntaxEditor->StyleSetFore(STYLE_DEFAULT, RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255));
    syntaxEditor->StyleSetFont(STYLE_DEFAULT, "Consolas");
    syntaxEditor->StyleSetSize(STYLE_DEFAULT, 11);
    syntaxEditor->StyleClearAll();
    syntaxEditor->SetCaretFore(RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255));
    syntaxEditor->SetFoldMarginHiColour(true, RGB(syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].r * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].g * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].b * 255));
    syntaxEditor->SetFoldMarginColour(true, RGB(syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].r * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].g * 255, syntaxEditor->color[WIDGETCOLOR_HIGHLIGHT].b * 255));

    auto textWidth = syntaxEditor->TextWidth(STYLE_LINENUMBER, "_99999");
    syntaxEditor->SetMargins(5);
    syntaxEditor->SetMarginTypeN(0, MarginType::Number);
    syntaxEditor->SetMarginWidthN(0, textWidth);

    syntaxEditor->SetMarginTypeN(2, MarginType::Symbol);
    syntaxEditor->SetMarginMaskN(2, SC_MASK_FOLDERS);
    syntaxEditor->SetMarginWidthN(2, 16);
    syntaxEditor->SetMarginLeft(2);
    syntaxEditor->SetMarginRight(2);

    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDER, MarkerSymbol::BoxPlus);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEROPEN, MarkerSymbol::BoxMinus);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEREND, MarkerSymbol::BoxPlus);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, MarkerSymbol::TCorner);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDEROPENMID, MarkerSymbol::BoxMinusConnected);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERSUB, MarkerSymbol::VLine);
    syntaxEditor->MarkerDefine(SC_MARKNUM_FOLDERTAIL, MarkerSymbol::LCornerCurve);

    for (int i = 25; i <= 31; i++) {
        syntaxEditor->MarkerSetFore(i, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255));
        syntaxEditor->MarkerSetBack(i, RGB(215, 221, 232));
    }

    syntaxEditor->StyleSetFore(LuaLexer::WORD, RGB(150, 190, 177));
    syntaxEditor->StyleSetFore(LuaLexer::WORD2, RGB(220, 220, 170));
    syntaxEditor->StyleSetFore(LuaLexer::COMMENT, RGB(87, 160, 61));
    syntaxEditor->StyleSetFore(LuaLexer::COMMENTLINE, RGB(87, 160, 61));
    syntaxEditor->StyleSetFore(LuaLexer::COMMENTDOC, RGB(87, 160, 61));
    syntaxEditor->StyleSetFore(LuaLexer::CHARACTER, RGB(87, 160, 61));
    syntaxEditor->StyleSetFore(LuaLexer::STRING, RGB(214, 151, 108));

    syntaxEditor->StyleSetBack(STYLE_LINENUMBER, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255));
    syntaxEditor->StyleSetFore(STYLE_LINENUMBER, RGB(43, 145, 175));

    syntaxEditor->SetElementColour(Element::ListBack, RGB(syntaxEditor->color[WIDGETCOLOR_BACKGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_BACKGROUND].b * 255));
    syntaxEditor->SetElementColour(Element::List, RGB(syntaxEditor->color[WIDGETCOLOR_FOREGROUND].r * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].g * 255, syntaxEditor->color[WIDGETCOLOR_FOREGROUND].b * 255));
    syntaxEditor->SetElementColour(Element::ListSelected, RGB(syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].r * 255, syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].g * 255, syntaxEditor->color[WIDGETCOLOR_SELECTEDTEXT].b * 255));
    syntaxEditor->SetElementColour(Element::ListSelectedBack, RGB(syntaxEditor->color[WIDGETCOLOR_SELECTION].r * 255, syntaxEditor->color[WIDGETCOLOR_SELECTION].g * 255, syntaxEditor->color[WIDGETCOLOR_SELECTION].b * 255));

    auto pixmap = LoadPixmap("Resources/class.png")->Resize(16, 16);
    syntaxEditor->RGBAImageSetWidth(pixmap->size.x);
    syntaxEditor->RGBAImageSetHeight(pixmap->size.y);
    syntaxEditor->RegisterRGBAImage(1, pixmap->pixels->Data());

    while (true)
    {
        const Event ev = WaitEvent();

        if (ev.id == SyntaxEditor::EVENT_CHARADDED)
        {
            auto notification = static_cast<TextEditorNotification*>(ev.extra.get());
            if (notification->ch == '.' && !syntaxEditor->AutoCActive())
            {
                syntaxEditor->AutoCShow(0, "Entity?1 Window?1 Hello World");
            }
        }

        switch (ev.id)
        {
            case EVENT_WIDGETACTION:
                if (ev.source == toggleVisibility)
                {
                    if (toggleVisibility->GetState() == WidgetState::WIDGETSTATE_SELECTED)
                    {
                        toggleVisibility->SetText("Visible");
                        syntaxEditor->Show();
                    }
                    else
                    {
                        toggleVisibility->SetText("Hidden");
                        syntaxEditor->Hide();
                    }
                }
                break;
            case EVENT_WIDGETSELECT:
                break;
            case EVENT_QUIT:
            case EVENT_WINDOWCLOSE:
                return 0;
                break;
            default: break;
        }
    }
    return 0;
}

 

ToDo:

  • Publish the source
  • add helper to apply UAK based theming
  • move some Scintilla-Types to UAK-Types (e.g.: Colour to iVec4)

I hope you enjoy the release and i look forward for any suggestions and feedback is very welcome.

  • Like 4
 Share

2 Comments


Recommended Comments

Cannot be built using current versions:

 

1>SyntaxWidget.lib(SyntaxWidget.obj) : error LNK2001: unresolved external symbol "void __cdecl UltraEngine::EmitEvent(int,class std::shared_ptr<class UltraEngine::Object>,int,int,int,int,int,class std::shared_ptr<class UltraEngine::Object>)" (?EmitEvent@UltraEngine@@YAXHV?$shared_ptr@VObject@UltraEngine@@@std@@HHHHH0@Z)
1>SyntaxWidget.lib(SyntaxWidget.obj) : error LNK2001: unresolved external symbol "public: virtual void __cdecl UltraEngine::Widget::SetPointer(enum UltraEngine::MousePointer)" (?SetPointer@Widget@UltraEngine@@UEAAXW4MousePointer@2@@Z)
1>SyntaxWidget.lib(SyntaxWidget.obj) : error LNK2001: unresolved external symbol "public: virtual void __cdecl UltraEngine::Widget::CursorBlink(void)" (?CursorBlink@Widget@UltraEngine@@UEAAXXZ)

 

  • Thanks 1
Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...