• 0

    posted a message on Editor freeze - funcname = varname

    The editor freezes when you declare a function interface and a variable (only tested with a trigger type variable) with the same name.

    The order is important, the function has to be declared first.

    Remember, a function interface does not include the body, declaring the body makes the editor throw an error instead.
    Example:

    void bla();
    trigger bla;
    
    Posted in: Galaxy Editor Bugs and Feedback
  • 0

    posted a message on [Data] How to make the world fit your UI

    Your map has a cool UI?

    It covers a lot of the screen?

    You should think about decreasing the area of the visible world. Not just by covering it with more and more dialogs, but by changing the area your graphics card renders.

    How to do that? Simple:

    1. Go to the UI section of the editor.
    2. Create a new Layout.
    3. Replace the content with this:
      <?xml version="1.0" encoding="utf-8" standalone="yes"?>
      <Desc>
          <Frame type="GameUI" name="GameUI" file="GameUI">
              <Anchor relative="$parent"/>
              <ConsoleWorldTopOffset val="0"/>
              <ConsoleWorldBottomOffset val="0"/>
          </Frame>
          <Frame type="WorldPanel" name="GameUI/WorldPanel" file="GameUI">
              <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
              <Anchor side="Right" relative="$parent" pos="Max" offset="0"/>
          </Frame>
      </Desc>
      

    Now, what does that code do?

    1.  <ConsoleWorldTopOffset val="x"/> 
      
      The area of your screen where the world is rendered starts x interface distance from the top.
    2.  <ConsoleWorldBottomOffset val="x"/> 
      
      The area of your screen where the world is rendered starts x interface distance from the bottom.
    3.  <Anchor side="Left" relative="$parent" pos="start" offset="x"/> 
      
      The left side of the rendered arera on your screen starts at the "start" position which can either be Min (left), Mid (middle) or Max (right) with x as offset to the right.
    4.  <Anchor side="Right" relative="$parent" pos="start" offset="x"/> 
      
      The right side of the rendered area on your screen starts at the "start" position wich can either be Min (left), Mid (middle) or Max (right) with x as offset to the right.

    Pros:

    1. Smaller rendered area equals lower load on your graphics card equals higher quality graphics possible without lag.
    2. The camera focus point is always in the center of the rendered area. Without this method, if a big part of the screen is hidden by dialogs (let's say 1/4 on the left side) and you focus your camera on a unit (with ctrl + shift + f for example) you see 2 times as far on the right side, than on the left (1/4 of the screen on the left, 2/4 on the right).

    QA:
    Q: So, are you really sure this is safe?
    A: Well, actually, I just copied it from blizzard. If you do not disable the normal interface, ConsoleWorldBottomOffset is set to 200.

    Q: Cliff shadows disappear somtimes, what did I do wrong?
    A: Nothing, shadows are only rendered for visible objects. Just make the visible world stretch 50 further under your UI/past the edge of the screen.





    The example does not use any dialogs/dialog items to hide the left side of the screen, it simply isn't rendered. http://www.sc2mapster.com/media/attachments/50/656/example.png

    Posted in: Tutorials
  • 0

    posted a message on Access to player specific options.

    @Mille25: Go

    I do not recommend changing graphics with it. I also posted it in the bugs section because I don't think this is supposed to be this way.

    I will, however, abuse it to change hotkeys back to standard, because my layout will not be standard. Grid layout fucks up most of the non-standard ui maps. In case blizzard patches it, there will be a hidden error message, no big deal.

    Edit:

    If you want a really funny feature, you can reduce graphics settings to the minimum when the hero is low hp/dead :P

    Getting back the graphics setting that were active previously, you just have to create 2 instances of the graphics menu. They are created with the current settings. Activating the unchanged version reverts everything back.

    Posted in: Galaxy Editor Bugs and Feedback
  • 0

    posted a message on Access to player specific options.
    Quote from Ahli634: Go

    Interesting find. :D

    Btw, to allows us to compile the code, we need to change this line

            DialogControlSetPosition(mp, c_allPlayers, c_anchorCenter, 0, 0);
    <</code>>\\
    to\\
    <<code>>
    DialogControlSetPosition(mp, PlayerGroupAll(), c_anchorCenter, 0, 0);
    

    edit: yay, the BBCode tag handling is broken...

    Oh well, I ran this through a texteditor to replace all the c_allPlayers. Somehow that was left alone.

    Fixed it, thanks!

    Posted in: Galaxy Editor Bugs and Feedback
  • 0

    posted a message on Access to player specific options.

    Yeah, you read that right. I don't know if this is already public knowledge or not but I just found out, that the UI-stuff grants you access to prett much every setting a player can access (write only).

    While figuring out how to implement the UI for my map, I stumbled upon a crude and not so well planned UI implementation by blizzard. Playing around with it, I created this code sample, that lets you force a player to change his graphics settings to the maximum (skipped stuff that needs a restart/additional confirmation and antialiazing; if the "fullscreen" constant is checked, the game is also forced to go fullscreen).

    const bool buttonOnly = true;
    const bool fullscreen = false;
    bool clicked (bool a, bool b) {
        TriggerDebugOutput(1, StringToText("Whoops, you clicked it..."), true);
        return true;
    }
    bool UITest(bool a, bool b) {
        int optionsMenu;
        int mp;
        int graphicsPanel;
        int displayMode;
        int textureQuality;
        int shader;
        int lighting;
        int shaderQuality;
        int terrainQuality;
        int reflectionQuality;
        int effectQuality;
        int postProcessingQuality;
        int physicsQuality;
        int portraits;
        int acceptButton;
        int BG;
        DialogCreate(500, 400, c_anchorCenter, 0, 0, true);
        DialogSetFullscreen(DialogLastCreated(), true);
        DialogSetImageVisible(DialogLastCreated(), false);
        DialogSetVisible(DialogLastCreated(), PlayerGroupAll(), true);
        mp = DialogControlCreate(DialogLastCreated(), c_triggerControlTypePanel);
        optionsMenu = DialogControlCreateInPanelFromTemplate(mp, c_triggerControlTypePanel, "GameMenuDialog/GameMenuDialogOptionsPanelTemplate");
        DialogControlSetSize(DialogControlLastCreated(), PlayerGroupAll(), 1600, 1150);
        DialogControlSetPosition(DialogControlLastCreated(), PlayerGroupAll(), c_anchorTopLeft, 0, 0);
        graphicsPanel = DialogControlHookup(optionsMenu, c_triggerControlTypePanel, "GraphicsOptionsPanel");
        displayMode = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "DisplayPanel/DisplayModePulldown");
        textureQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "TextureQualityPanel/TextureQualityPulldown");
        shader = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/ShaderDetailPulldown");
        lighting = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/LightingQualityPulldown");
        shaderQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/ShadowQualityPulldown");
        terrainQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/TerrainQualityPulldown");
        reflectionQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/ReflectionQualityPulldown");
        effectQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/EffectsQualityPulldown");
        postProcessingQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/PostProcessingQualityPulldown");
        physicsQuality = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/PhysicsQualityPulldown");
        portraits = DialogControlHookup(graphicsPanel, c_triggerControlTypePulldown, "GraphicsPanel/PortraitsPulldown");
        acceptButton = DialogControlHookup(optionsMenu, c_triggerControlTypeButton, "AcceptButton");
        TriggerAddEventDialogControl(TriggerCreate("clicked"), -1, acceptButton, c_triggerControlEventTypeClick);
        if (buttonOnly) {
            DialogControlSetSize(mp, PlayerGroupAll(), 300, 120);
            DialogControlSetPosition(mp, PlayerGroupAll(), c_anchorCenter, 0, 0);
            DialogControlSetPositionRelative(acceptButton, PlayerGroupAll(), c_anchorTopLeft, mp, c_anchorTopLeft, -80, 0);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "TopLeftCornerImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "BlackMaskImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "GradientImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "BorderImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "InnerLineImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
            BG = DialogControlHookup(optionsMenu, c_triggerControlTypeImage, "TitleBorderImage");
            DialogControlSetVisible(BG, PlayerGroupAll(), false);
        } else {
            DialogControlSetSize(mp, PlayerGroupAll(), 1600, 1150);
        }
    Wait(0.0625, c_timeGame);
        if (fullscreen) {
            DialogControlAddItem(displayMode, PlayerGroupAll(), StringToText("Derp"));
            DialogControlSelectItem(displayMode, PlayerGroupAll(), 3);
        }
        DialogControlAddItem(textureQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(textureQuality, PlayerGroupAll(), 4);
        DialogControlAddItem(shader, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(shader, PlayerGroupAll(), 4);
        DialogControlAddItem(lighting, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(lighting, PlayerGroupAll(), 4);
        DialogControlAddItem(shaderQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(shaderQuality, PlayerGroupAll(), 3);
        DialogControlAddItem(terrainQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(terrainQuality, PlayerGroupAll(), 4);
        DialogControlAddItem(reflectionQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(reflectionQuality, PlayerGroupAll(), 2);
        DialogControlAddItem(effectQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(effectQuality, PlayerGroupAll(), 4);
        DialogControlAddItem(postProcessingQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(postProcessingQuality, PlayerGroupAll(), 3);
        DialogControlAddItem(physicsQuality, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(physicsQuality, PlayerGroupAll(), 5);
        DialogControlAddItem(portraits, PlayerGroupAll(), StringToText("Derp"));
        DialogControlSelectItem(portraits, PlayerGroupAll(), 2);
        return true;
    }
    void UITest_init () {
        TriggerExecute(TriggerCreate("UITest"), false, false);
    }
    

    This button can look any way you like and be inside the dialog of your choice; the amount of buttons is unlimited.

    I personally will probably use this method to force the standard hotkeys in my map (because I don't use the standard layout). No matter what, I consider this the biggest bug I have yet to encounter in the game.

    Edit:

    1. Fixed @Ahli634: Go
    Posted in: Galaxy Editor Bugs and Feedback
  • 0

    posted a message on SC2 lib images

    First of all, if this is wrong here, please move it or tell me where to go.
    If something similar already exists, please provide a link (I'm interested).

    So I was tired of always searching through what felt like billions of images to find a decent one. Result?:

    Everything is inside the folder Assets\Textures\, so if you want to use them, it should look like "Assets\Textures\name.dds" in the gui or "Assets\\Textures\\name.dds" in the script (you have to escape backslashes).

    Keywords

    I wrote an easy way to filter the sc2 assets. I would publish it too but I'm using a licensed mpq utility library.

    Keyword: frame

    Contains 275 reasonably ok borders. My method was "take everything that doesn't suck too hard".
    The numbers in the center represent the position in the list (testmap only).

    Examples

    http://www.sc2mapster.com/media/attachments/49/324/borders271.pnghttp://www.sc2mapster.com/media/attachments/49/325/borders5.pnghttp://www.sc2mapster.com/media/attachments/49/326/borders19.pnghttp://www.sc2mapster.com/media/attachments/49/327/borders23.pnghttp://www.sc2mapster.com/media/attachments/49/328/borders36.pnghttp://www.sc2mapster.com/media/attachments/49/329/borders80.pnghttp://www.sc2mapster.com/media/attachments/49/330/borders99.pnghttp://www.sc2mapster.com/media/attachments/49/331/borders106.pnghttp://www.sc2mapster.com/media/attachments/49/332/borders122.pnghttp://www.sc2mapster.com/media/attachments/49/333/borders192.pnghttp://www.sc2mapster.com/media/attachments/49/334/borders209.pnghttp://www.sc2mapster.com/media/attachments/49/335/borders266.png

    Filtered

    zip

    Map

    This map contains every image that cointains the keyword.
    Feel free to look through the images yourself. You may use the left/right buttons on your keyboard, the "arrow" buttons on the screen or the edit field to move through the images.
    map

    Additional Information

    I use Wink (external link) to take the pictures (use export as html to get the images).

    Posted in: Art Assets
  • 0

    posted a message on [Pending][Library]ScreenDesigner

    Description

    This is a powerful tool to allow moving your dialog controls around during the game.

    How to use

    targetPlayers is a playergroup with all players that the changes should be applied to.

    Want to do something with a dialog control?
    Add it to the system! (you will need the registration for all other steps):

    string registration = arkless_screenDesigner_addControl( myDialogControl);
    

    So, what can I do now?

    1. Allow other dialog controls to use this one as anchor:
      arkless_screenDesigner_controlIsRelative(registration, targetPlayers);
      
    2. Allow the dialog control to be moved around by the user:
      arkless_screenDesigner_setMovable(registration, targetPlayers);
      
    3. Allow the player to resize to dialog control:
      arkless_screenDesigner_setResizeable(registration, targetPlayers);
      
      However, you have to tell the system the minimum and maximum size of the dialog control:
      arkless_screenDesigner_setBounds(registration, targetPlayers, minWidth, maxWidth, minHeight, maxHeight);
      
      This also works with custom dialog control setups like this (included in the example).

    Important:

    • If one of the controls you add to the system is positioned relative to another one (in some way, even through a chain of relations), you have to let the system know:
      arkless_screenDesigner_setRelationChain(registrationOfTheControlThatIsRelativeToTheOther, targetPlayers, registartionOfTheControlThatIsRelatedTo);
      
    • All controls have to be set to relative (via DialogControlSetPositionRelative) mode to make all properties readable.

    Installation

    Go here to get the the DataTableLists library. Import it into your map.

    Now import this library as well.

    Example map

    Pictures wouldnt show you much, just download it and press the test button (optional: ctrl + F9).
    The button on the bottom right shows/hides the other controls.

    The map.

    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library]DataTableLists

    Description

    This is an easy way to manage your DataTable substructures.

    Pros: - managed through strings - easy to manage - (next to) infinite space

    Cons: - managed through strings - uses data table

    WARNING: In addition to occupying the subtable defined by the prefix and concatenations to the right side, values are sometimes stored with the delimiter (c_arkless_dataTable_list_delimiter) at the very left.

    Demonstration

    Chose any string as prefix for your list.

    You may use every element you get and all possible concatenations to the right side, that do not use the specified delimiter (c_arkless_dataTable_list_delimiter) to store data in the DataTable. Since namespaces do not overlap, you may even use them as prefixes for new lists.

    function interface:

        //get new element
    string arkless_dataTable_list_getListElement(string prefix);
        
        //remove element
    void arkless_dataTable_list_removeListElement(string listElement);
        
        //remove element from list
    void arkless_dataTable_list_removeListElementFromList(string listElement);
        
        //get first/last list element
    string arkless_dataTable_list_getFirst(string prefix);
    string arkless_dataTable_list_getLast(string prefix);
        
        //add element to list
    void arkless_dataTable_list_addElementAsFirst(string toAdd);
    void arkless_dataTable_list_addElementAsLast(string toAdd);
    void arkless_dataTable_list_addElementInFrontOfElement(string toAdd, string inFrontOfThis);
    void arkless_dataTable_list_addElementBehindElement(string toAdd, string behindThis);
        
        //traverse list
    string arkless_dataTable_listElement_getPrevious(string element);
    string arkless_dataTable_listElement_getNext(string element);
    

    Example

    Click Me

    Installation

    Import the library into your map

    Changes

    • 0.004 Changed from wrong library with the right name to the right library
    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars

    I have separated most of the combination functions and made everything more similar to the basic dialog control functions. I am still not good at creating tutorials so I'd be really thankful on your input:

    1. Where did you get stuck.
    2. What was hard to grasp (even if you understood it in the end).
    3. Is something misleadin?
    4. Did I forget to mention any steps?
    5. Do any error messages appear while testing (and are they useful?)?
    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars

    @Elmaex: Go

    That is actually really useful. That might become my method of choice. However, not in this library. Since it changes data stuff, a mod using this library will be needed.

    Another library I'm planning will allow users to move everything on their screen (and maybe resizing stuff as well). I am not sure what comes first or whether it will be created at all.

    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars

    @BasharTeg: Go

    Is it possible to catch mousewheel up and down in sc2?
    If so, it is no problem.

    I do not intend to implement up and down buttons. Reducing the scrollbar size greatly reduces the level of control over the content. However, you can set or modify (in-/decrase) the scrollposition through triggers. This allows you to create buttons with exactly the functionality you want.

    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars
    Quote from BasharTeg: Go

    Unfortunately, it seems much too complicated to actually test within a reasonable amount of time! Well, maybe for a dummy like me. My eyes glaze over when I read step 1 of the step-by-step guide. So I suggest streamlining the library a bit so it's more noob-friendly.

    To be honest, I would love to try and implement something like this in a map, but I'm afraid the time investment required to parse how it works is simply not worth it. Either work on your explanation or make the library more user-friendly.

    You are not the first person to tell me this and I admid that the way it is made is rather unfriendly. At the moment you have to supply all the information up front, even optional stuff. Even though a library is not supposed to be work in progress, splitting up inputs is an update that will definitely come.

    Thank you for the feedback on the step to step guide. Since It will be reworked anyways, I will remove it now and replace it with an easier version later.

    Quote from BasharTeg: Go

    As far as the actual features go, it does pretty much what you need it to do. Adding the ability to click on the empty space in the scroll bar to quickly jump to that point would be a nice addition (seems like you have that already planned, though.)

    Not at the moment but it's a good idea. This is not an easy feat since I work without any knowledge about screen/ui resolution but just thinking about it gives me a few ideas.



    Changes will probably not happen till the end of the week, my schedule is rather busy.

    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on List of Libraries by Category

    So I was just browsing some random libraries. By chance I found "AchDataAward* by Doubotis" in your list. It is still marked with an * even though it clearly is approved (no moderator said it's not after being approved once) and the bug you pointed out seems to have been fixed for over a year.

    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars

    The library is currently in its final version. However, if a bug or desireable functionality is found, it will probably get another update.
    All working copies will stay as attachment for post 1.
    The example will always use the newest version.

    All changes will be listed here:

    Changelog

    • 0.002:
      • fixed a bug where the x position of the content was partly computed using the values for y
        (reason for removal of scrollable_0.001.SC2Lib)
      • added more visibility options to hide specific parts
      • added functions to control the scroll position through triggers
      • deallocating now possible
    • 0.003:
      • a function "void funcname(int newX, newY)" can be registered to be called on scroll end
      • functionality was added to get the current content scroll position for a player
    • 0.004:
      • fixed a bug where deallocation broke the stack/active instances in some cases
        (reason for removal of scrollable_0.002.SC2Lib / scrollable_0.003.SC2Lib)
      • added functionality to force a player into scroll mode for any number of scrolalbles
      • cleaned up varspace - memory usage down by 60%
    • 0.005:
      • added dummy function for importing
    • 0.006:
      • removed a bug that sometimes crashed the update thread when changing the scrollposition of the content through triggers while the content was smaller than the content box
        (reason for removal of scrollable_0.004.SC2Lib / scrollable_0.005.SC2Lib)
    • 0.007:
      • restructured the whole function interface
      • borders now optional
      • background now optional (black if not hidden)
      • positioning system reworked (relative controls now unified)
      • removed a bug that sometimes skipped the player with the highest number in a playergroup
      • slider background now grey by default (can now be distinguished from the content box background)
      • slider image now optional (white by default)
      • removed excessive error messages and checking for correctness that might prevent some adjustments (for example negative border sizes)
    • 0.008:
      • removed additional inputs from the "setSize" functions for sliders
    • 0.009:
      • slider image now resizeable again
    • 0.010:
      • adjusted names to have a _ after scrollable
      • removed ownership variables
    • 0.011:
      • slider images can be changed again
    Posted in: Trigger Libraries & Scripts
  • 0

    posted a message on [Pending][Library] Scrollable - panels with scrollbars

    Scrollable

    Ideas

    The library is fully functioning and I consider it final at the moment (it conaints everything [and more] that was intended when the work began). These ideas may be implemented someday but will not influence anything that is implemented right now.

    • Find good slider image (you may point me to one that is not copyrighted in any ways, preferable your own).
    • Make scrollbar clickable.
    • Make scrollspeed adjustable.
    • Enable mousewheel scrolling. <= cannot be done with just a library, might create a mod that uses this library later, won't be here but will be linked

    Description

    Ever had problems because the screenspace was too small for your map? No more! This library allows the creation of scrollbars to manage your content.

    Pros:

    • unlimited space (100000 x 100000 is no problem for long scrollbars but going too far makes it hard to control, example with scrollheight 80000 included)
    • dynamically adjustable space
    • all 3 parts behave like normal dialog controls, except for the need to call the supplied functiosn (the names are similar to the original)
      native:
      void DialogControlSetPositionRelative (int control, playergroup players, int anchor, int relative, int relativeAnchor, int offsetX, int offsetY);
      
      content box:
      void scrollable_contentBox_setPositionRelative(int id, playergroup targetPlayers, int anchor, int relativeControl, int relativeAnchor, int offsetX, int offsetY);
      

    Cons:

    • A bit sluggish in multiplayer.
    • Might keep the scrollbars in drag mode by leaving the game window at exactly the wrong moment (alt+tab for example). Fixed by clicking and/or moving the mouse over the bugging scrollbar icon.
    • Might not catch a mouse-out if the parent of the sliders is too small.

    Copyable Example Code

    At the moment, I use the following code for my map:

    Data structures

    struct border_properties{
        int sizeTop;
        int sizeRight;
        int sizeBottom;
        int sizeLeft;
        string border;
        int imageType;
        color borderColor;
        string singleBorderImage;
        int singleBorderImageType;
        color singleBorderColor;
        int singleBorderWidth;
        int singleBorderMarginLeft;
        int singleBorderMarginRight;
        int singleBorderHeight;
        int singleBorderMarginTop;
        int singleBorderMarginBottom;
    };
    
    struct icon_properties{
        string image;
        int imageType;
        color imageColor;
        int width;
        int height;
        int marginTop;
        int marginRight;
        int marginBottom;
        int marginLeft;
    };
    
    struct scrollable_vertical_properties{
        int borderType;
        int iconProperties;
        int width;
        int height;
    };
    

    Create instances of those

    border_properties[2] borders;
    icon_properties[1] icons;
    scrollable_vertical_properties[1] scrollable_verticals;
    
    //this dialog is needed for the creation function
    int scrollable_dialog;
    

    Input data

    void init_interface_borders() {
        borders[0].sizeTop = 49;
        borders[0].sizeRight = 5;
        borders[0].sizeBottom = 5;
        borders[0].sizeLeft = 5;
        borders[0].border = "Assets\\Textures\\ui_ingame_resourcesharing_frame_message.dds";
        borders[0].imageType = c_triggerImageTypeHorizontalBorder;
        borders[0].borderColor = Color(100, 100, 100);
        borders[0].singleBorderImage = "Assets\\Textures\\ui_ingame_resourcesharing_frame_message.dds";
        borders[0].singleBorderImageType = c_triggerImageTypeHorizontalBorder;
        borders[0].singleBorderColor = Color(100, 100, 100);
        borders[0].singleBorderWidth = 3;
        borders[0].singleBorderMarginLeft = 0;
        borders[0].singleBorderMarginRight = 0;
        borders[0].singleBorderHeight = 3;
        borders[0].singleBorderMarginTop = 0;
        borders[0].singleBorderMarginBottom = 0;
        
        borders[1].sizeTop = 24;
        borders[1].sizeRight = 36;
        borders[1].sizeBottom = 22;
        borders[1].sizeLeft = 35;
        borders[1].border = "Assets\\Textures\\selectionframe_outer2.dds";
        borders[1].imageType = c_triggerImageTypeNineSlice;
        borders[1].borderColor = Color(100, 100, 100);
        borders[1].singleBorderImage = "Assets\\Textures\\selectionframe_outer2.dds";
        borders[1].singleBorderImageType = c_triggerImageTypeNineSlice;
        borders[1].singleBorderColor = Color(100, 100, 100);
        borders[1].singleBorderWidth = 35;
        borders[1].singleBorderMarginLeft = 12;
        borders[1].singleBorderMarginRight = 12;
        borders[1].singleBorderHeight = 35;
        borders[1].singleBorderMarginTop = 10;
        borders[1].singleBorderMarginBottom = 10;
    }
    
    void init_interface_icons() {
        icons[0].image = "Assets\\Textures\\btn-tips-sellprotossartifacts.dds";
        icons[0].imageType = c_triggerImageTypeNormal;
        icons[0].imageColor = Color(60, 60, 30);
        icons[0].width = 38;
        icons[0].height = 38;
        icons[0].marginTop = 5;
        icons[0].marginRight = 4;
        icons[0].marginBottom = 5;
        icons[0].marginLeft = 4;
    }
    
    void init_interface_scrollable_verticals() {
        scrollable_verticals[0].borderType = 0;
        scrollable_verticals[0].iconProperties = 0;
        scrollable_verticals[0].width = 200;
            //These dimension determine the size of the content area. Everything else will change accordingly.
        scrollable_verticals[0].height = 600;
    }
    
    void init_interface_scrollable_dialog() {
        scrollable_dialog = DialogCreate(1, 1, 1, 1, 1, false);
        DialogSetFullscreen(scrollable_dialog, true);
        DialogSetImageVisible(scrollable_dialog, false);
        DialogSetVisible(scrollable_dialog, c_allPlayers, true);
    }
    

    Creation function

    void init_interface_scrollable_vertical_create(int id, int properties) {
        structref<scrollable_vertical_properties> svp = scrollable_verticals[properties];
        structref<border_properties> bp = borders[svp.borderType];
        structref<icon_properties> ip = icons[svp.iconProperties];
        int box;
        int divider;
        int dividerPanel;
        
        scrollable_contentBox_create(id, scrollable_dialog, false);
        scrollable_contentBox_setSize(id, c_allPlayers, svp.width, svp.height);
        scrollable_contentBox_setBorderSize(id, c_allPlayers, bp.sizeTop, bp.sizeRight + bp.singleBorderWidth - bp.singleBorderMarginLeft - bp.singleBorderMarginRight + ip.width - ip.marginLeft - ip.marginRight, bp.sizeBottom, bp.sizeLeft);
        scrollable_contentBox_setBorderImage(id, c_allPlayers, bp.border, bp.imageType, bp.borderColor);
        scrollable_contentBox_setBackgroundImageVisible(id, c_allPlayers, false);
        scrollable_contentBox_setPosition(id, c_allPlayers, c_anchorTopLeft, 50, 50);
        box = scrollable_getContentPanel(id);
        
        scrollable_verticalSlider_create(id, scrollable_dialog, false);
        scrollable_verticalSlider_setSize(id, c_allPlayers, ip.width, svp.height + ip.marginTop + ip.marginBottom);
        scrollable_verticalSlider_setSliderImage(id, c_allPlayers, ip.image, ip.imageType, ip.imageColor);
        scrollable_verticalSlider_setBackgroundImageVisible(id, c_allPlayers, false);
        scrollable_verticalSlider_setPositionRelative(id, c_allPlayers, c_anchorBottomRight, scrollable_contentBox_relative(id), c_anchorBottomRight, ip.marginBottom - bp.sizeRight, ip.marginBottom - bp.sizeBottom);
        
        
        dividerPanel = DialogControlCreate(scrollable_dialog, c_triggerControlTypePanel);
        DialogControlSetSize(dividerPanel, c_allPlayers, bp.singleBorderWidth, svp.height + bp.singleBorderMarginTop + bp.singleBorderMarginBottom);
        DialogControlSetPositionRelative(dividerPanel, c_allPlayers, c_anchorBottomRight, scrollable_contentBox_relative(id), c_anchorBottomRight, ip.marginLeft - ip.width + ip.marginRight - bp.sizeRight + bp.singleBorderMarginRight, bp.singleBorderMarginBottom - bp.sizeBottom);
        
        divider = DialogControlCreateInPanel(dividerPanel, c_triggerControlTypeImage);
        DialogControlSetPropertyAsString(divider, c_triggerControlPropertyImage, c_allPlayers, bp.singleBorderImage);
        DialogControlSetPropertyAsInt(divider, c_triggerControlPropertyImageType, c_allPlayers, bp.singleBorderImageType);
        DialogControlSetFullDialog(divider, c_allPlayers, true);
    }
    

    Creating a scrollable:

    //THIS FUNCTION HAS TO BE EXECUTED once before scrollables can be created
    void init_scrollableCreation() {
        init_interface_borders();
        init_interface_icons();
        init_interface_scrollable_verticals();
        init_interface_scrollable_dialog();
    }
    
    int myScrollable = scrollable_new("myScrollable");
    //THIS FUNCTION HAS TO BE EXECUTED
    void createMyScrollable() {
        int idOfScrollableVerticals = 0;
        int idOfScrollable = myScrollable;
        init_interface_scrollable_vertical_create(idOfScrollable, idOfScrollableVerticals);
    }
    

    Adding content


    (this is only a dummy, you have to add your own content instead)

    void init_interface_fakeContent(int id) {
        int fakeContent = DialogControlCreateInPanel(scrollable_getContentPanel(id), c_triggerControlTypeLabel);
        int i;
        string content;
        DialogControlSetSize(fakeContent, c_allPlayers, 68, 18165);
        DialogControlSetPropertyAsString(fakeContent, c_triggerControlPropertyStyle, c_allPlayers, "ModRightSize16");
        DialogControlSetPositionRelative(fakeContent, c_allPlayers, c_anchorTopLeft, scrollable_getRelativeControl_top(id), c_anchorTopLeft, 0, 0);
        content = "";
        for (i = 1; i <= 1000; i += 1) {
            content += IntToString(i) + ":\n";
        }
        DialogControlSetPropertyAsText(fakeContent, c_triggerControlPropertyText, c_allPlayers, StringToText(content));
        scrollable_contentBox_setVerticalContentSize(id, c_allPlayers, 18150);
    }
    
    //THIS FUNCTION HAS TO BE EXECUTED
    void addFakeContent() {
        init_interface_fakeContent(myScrollable);
    }
    

    Putting everything together.


    (each step is copy/pasted below the previous one)

    struct border_properties{
        int sizeTop;
        int sizeRight;
        int sizeBottom;
        int sizeLeft;
        string border;
        int imageType;
        color borderColor;
        string singleBorderImage;
        int singleBorderImageType;
        color singleBorderColor;
        int singleBorderWidth;
        int singleBorderMarginLeft;
        int singleBorderMarginRight;
        int singleBorderHeight;
        int singleBorderMarginTop;
        int singleBorderMarginBottom;
    };
    
    struct icon_properties{
        string image;
        int imageType;
        color imageColor;
        int width;
        int height;
        int marginTop;
        int marginRight;
        int marginBottom;
        int marginLeft;
    };
    
    struct scrollable_vertical_properties{
        int borderType;
        int iconProperties;
        int width;
        int height;
    };
    border_properties[2] borders;
    icon_properties[1] icons;
    scrollable_vertical_properties[1] scrollable_verticals;
    
    //this dialog is needed for the creation function
    int scrollable_dialog;
    void init_interface_borders() {
        borders[0].sizeTop = 49;
        borders[0].sizeRight = 5;
        borders[0].sizeBottom = 5;
        borders[0].sizeLeft = 5;
        borders[0].border = "Assets\\Textures\\ui_ingame_resourcesharing_frame_message.dds";
        borders[0].imageType = c_triggerImageTypeHorizontalBorder;
        borders[0].borderColor = Color(100, 100, 100);
        borders[0].singleBorderImage = "Assets\\Textures\\ui_ingame_resourcesharing_frame_message.dds";
        borders[0].singleBorderImageType = c_triggerImageTypeHorizontalBorder;
        borders[0].singleBorderColor = Color(100, 100, 100);
        borders[0].singleBorderWidth = 3;
        borders[0].singleBorderMarginLeft = 0;
        borders[0].singleBorderMarginRight = 0;
        borders[0].singleBorderHeight = 3;
        borders[0].singleBorderMarginTop = 0;
        borders[0].singleBorderMarginBottom = 0;
        
        borders[1].sizeTop = 24;
        borders[1].sizeRight = 36;
        borders[1].sizeBottom = 22;
        borders[1].sizeLeft = 35;
        borders[1].border = "Assets\\Textures\\selectionframe_outer2.dds";
        borders[1].imageType = c_triggerImageTypeNineSlice;
        borders[1].borderColor = Color(100, 100, 100);
        borders[1].singleBorderImage = "Assets\\Textures\\selectionframe_outer2.dds";
        borders[1].singleBorderImageType = c_triggerImageTypeNineSlice;
        borders[1].singleBorderColor = Color(100, 100, 100);
        borders[1].singleBorderWidth = 35;
        borders[1].singleBorderMarginLeft = 12;
        borders[1].singleBorderMarginRight = 12;
        borders[1].singleBorderHeight = 35;
        borders[1].singleBorderMarginTop = 10;
        borders[1].singleBorderMarginBottom = 10;
    }
    
    void init_interface_icons() {
        icons[0].image = "Assets\\Textures\\btn-tips-sellprotossartifacts.dds";
        icons[0].imageType = c_triggerImageTypeNormal;
        icons[0].imageColor = Color(60, 60, 30);
        icons[0].width = 38;
        icons[0].height = 38;
        icons[0].marginTop = 5;
        icons[0].marginRight = 4;
        icons[0].marginBottom = 5;
        icons[0].marginLeft = 4;
    }
    
    void init_interface_scrollable_verticals() {
        scrollable_verticals[0].borderType = 0;
        scrollable_verticals[0].iconProperties = 0;
            //These dimension determine the size of the content area. Everything else will change accordingly.
        scrollable_verticals[0].width = 200;
        scrollable_verticals[0].height = 600;
    }
    
    void init_interface_scrollable_dialog() {
        scrollable_dialog = DialogCreate(1, 1, 1, 1, 1, false);
        DialogSetFullscreen(scrollable_dialog, true);
        DialogSetImageVisible(scrollable_dialog, false);
        DialogSetVisible(scrollable_dialog, c_allPlayers, true);
    }
    
    void init_interface_scrollable_vertical_create(int id, int properties) {
        structref<scrollable_vertical_properties> svp = scrollable_verticals[properties];
        structref<border_properties> bp = borders[svp.borderType];
        structref<icon_properties> ip = icons[svp.iconProperties];
        int box;
        int divider;
        int dividerPanel;
        
        scrollable_contentBox_create(id, scrollable_dialog, false);
        scrollable_contentBox_setSize(id, c_allPlayers, svp.width, svp.height);
        scrollable_contentBox_setBorderSize(id, c_allPlayers, bp.sizeTop, bp.sizeRight + bp.singleBorderWidth - bp.singleBorderMarginLeft - bp.singleBorderMarginRight + ip.width - ip.marginLeft - ip.marginRight, bp.sizeBottom, bp.sizeLeft);
        scrollable_contentBox_setBorderImage(id, c_allPlayers, bp.border, bp.imageType, bp.borderColor);
        scrollable_contentBox_setBackgroundImageVisible(id, c_allPlayers, false);
        scrollable_contentBox_setPosition(id, c_allPlayers, c_anchorTopLeft, 50, 50);
        box = scrollable_getContentPanel(id);
        
        scrollable_verticalSlider_create(id, scrollable_dialog, false);
        scrollable_verticalSlider_setSize(id, c_allPlayers, ip.width, svp.height + ip.marginTop + ip.marginBottom);
        scrollable_verticalSlider_setSliderImage(id, c_allPlayers, ip.image, ip.imageType, ip.imageColor);
        scrollable_verticalSlider_setBackgroundImageVisible(id, c_allPlayers, false);
        scrollable_verticalSlider_setPositionRelative(id, c_allPlayers, c_anchorBottomRight, scrollable_contentBox_relative(id), c_anchorBottomRight, ip.marginBottom - bp.sizeRight, ip.marginBottom - bp.sizeBottom);
        
        
        dividerPanel = DialogControlCreate(scrollable_dialog, c_triggerControlTypePanel);
        DialogControlSetSize(dividerPanel, c_allPlayers, bp.singleBorderWidth, svp.height + bp.singleBorderMarginTop + bp.singleBorderMarginBottom);
        DialogControlSetPositionRelative(dividerPanel, c_allPlayers, c_anchorBottomRight, scrollable_contentBox_relative(id), c_anchorBottomRight, ip.marginLeft - ip.width + ip.marginRight - bp.sizeRight + bp.singleBorderMarginRight, bp.singleBorderMarginBottom - bp.sizeBottom);
        
        divider = DialogControlCreateInPanel(dividerPanel, c_triggerControlTypeImage);
        DialogControlSetPropertyAsString(divider, c_triggerControlPropertyImage, c_allPlayers, bp.singleBorderImage);
        DialogControlSetPropertyAsInt(divider, c_triggerControlPropertyImageType, c_allPlayers, bp.singleBorderImageType);
        DialogControlSetFullDialog(divider, c_allPlayers, true);
    }
    //init_scrollableCreation() has to be called once before scrollables can be created
    void init_scrollableCreation() {
        init_interface_borders();
        init_interface_icons();
        init_interface_scrollable_verticals();
        init_interface_scrollable_dialog();
    }
    
    int myScrollable = scrollable_new("myScrollable");
    void createMyScrollable() {
        int idOfScrollableVerticals = 0;
        int idOfScrollable = myScrollable;
        init_interface_scrollable_vertical_create(idOfScrollable, idOfScrollableVerticals);
    }
    
    void init_interface_fakeContent(int id) {
        int fakeContent = DialogControlCreateInPanel(scrollable_getContentPanel(id), c_triggerControlTypeLabel);
        int i;
        string content;
        DialogControlSetSize(fakeContent, c_allPlayers, 68, 18165);
        DialogControlSetPropertyAsString(fakeContent, c_triggerControlPropertyStyle, c_allPlayers, "ModRightSize16");
        DialogControlSetPositionRelative(fakeContent, c_allPlayers, c_anchorTopLeft, scrollable_getRelativeControl_top(id), c_anchorTopLeft, 0, 0);
        content = "";
        for (i = 1; i <= 1000; i += 1) {
            content += IntToString(i) + ":\n";
        }
        DialogControlSetPropertyAsText(fakeContent, c_triggerControlPropertyText, c_allPlayers, StringToText(content));
        scrollable_contentBox_setVerticalContentSize(id, c_allPlayers, 18150);
    }
    
    void addFakeContent() {
        init_interface_fakeContent(myScrollable);
    }
    
    void executeEverything() {
        init_scrollableCreation();
        createMyScrollable();
        addFakeContent();
    }
    

    The function "ececuteEverything" calls all three functions that are marked as "THIS HAS TO BE EXECUTED". Using it instead of executing them is optional.

    HINT: I just found out that textcontent scales different depending screen resolutions. The dialog items have the same size, but the text that is displayed gets bigger/smaller (in comparison?). The example might look odd but this will NOT happen when you add multiple dialog items as content instead of one.

    Results:
    (might use different width/height than in the default example)

    • borderType = 0:
      http://www.sc2mapster.com/media/attachments/49/434/scrollable.png
    • borderType = 1:
      (I still don't have any good slider images, so I just use the same as in type 1.)
      http://www.sc2mapster.com/media/attachments/49/448/scrollable2.png

    Installation

    1. Download the library.
    2. Import the library.

    Example Map

    The example shows of how powerful of a tool this is but is not as visually pleasing. Download Example Map

    The library does not cause the load time. The example includes more than 10000 dialog controls.

    • Example - Recursion
      • The content box contains the other examples.
    • Example - Colorselection
      • A colorgrid that changes the color of an external image (monocolor) when moving your mouse over it.
      • Shows how usable space can be extended.
      • Contains a checkbox to enable scrolling in both axis.
    • Example - Buttonlist
      • 800 (+1) Buttons that change their vertical-size when clicked (between 20 and 500).
      • Shows how expandable list-content would be handled.

    Searching for border images?
    Click me!

    Posted in: Trigger Libraries & Scripts
  • To post a comment, please or register a new account.