diff --git a/libraries/ZWidget/CMakeLists.txt b/libraries/ZWidget/CMakeLists.txt index d65e5ccea..f67f52f4c 100644 --- a/libraries/ZWidget/CMakeLists.txt +++ b/libraries/ZWidget/CMakeLists.txt @@ -46,6 +46,7 @@ set(ZWIDGET_SOURCES src/widgets/textlabel/textlabel.cpp src/widgets/pushbutton/pushbutton.cpp src/widgets/checkboxlabel/checkboxlabel.cpp + src/widgets/dropdown/dropdown.cpp src/widgets/listview/listview.cpp src/widgets/tabwidget/tabwidget.cpp src/window/window.cpp @@ -164,6 +165,7 @@ source_group("src\\widgets\\imagebox" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE source_group("src\\widgets\\textlabel" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/textlabel/.+") source_group("src\\widgets\\pushbutton" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/pushbutton/.+") source_group("src\\widgets\\checkboxlabel" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/checkboxlabel/.+") +source_group("src\\widgets\\dropdown" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/dropdown/.+") source_group("src\\widgets\\listview" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/listview/.+") source_group("src\\widgets\\tabwidget" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/tabwidget/.+") source_group("src\\window" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/window/.+") diff --git a/libraries/ZWidget/example/example.cpp b/libraries/ZWidget/example/example.cpp index ec4eed91b..c14505548 100644 --- a/libraries/ZWidget/example/example.cpp +++ b/libraries/ZWidget/example/example.cpp @@ -1,8 +1,10 @@ +#include #include #include #include #include #include +#include #include #include #include @@ -34,6 +36,7 @@ public: PlayButton = new PushButton(this); ExitButton = new PushButton(this); GamesList = new ListView(this); + Choices = new Dropdown(this); SetWindowBackground(Colorf::fromRgba8(51, 51, 51)); SetWindowBorderColor(Colorf::fromRgba8(51, 51, 51)); @@ -60,6 +63,10 @@ public: BrightmapsCheckbox->SetText("Brightmaps"); WidescreenCheckbox->SetText("Widescreen"); + Choices->AddItem("First"); + Choices->AddItem("Second"); + Choices->AddItem("Third"); + try { auto filedata = ReadAllBytes("banner.png"); @@ -93,9 +100,11 @@ public: y += 10.0; - SelectLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, SelectLabel->GetPreferredHeight()); + SelectLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0 - Choices->GetPreferredWidth(), SelectLabel->GetPreferredHeight()); y += SelectLabel->GetPreferredHeight(); + Choices->SetFrameGeometry(GetWidth() - 20.0 - Choices->GetPreferredWidth(), y-Choices->GetPreferredHeight(), Choices->GetPreferredWidth(), Choices->GetPreferredHeight()); + double listViewTop = y + 10.0; y = GetHeight() - 15.0 - PlayButton->GetPreferredHeight(); @@ -140,6 +149,7 @@ public: PushButton* PlayButton = nullptr; PushButton* ExitButton = nullptr; ListView* GamesList = nullptr; + Dropdown* Choices = nullptr; }; static std::vector ReadAllBytes(const std::string& filename); @@ -156,13 +166,23 @@ std::vector LoadWidgetData(const std::string& name) return ReadAllBytes(name); } -int example() +enum class Backend { + Default, Win32, SDL2, X11, Wayland +}; + +int example(Backend backend = Backend::Default) { WidgetTheme::SetTheme(std::make_unique()); - // DisplayBackend::Set(DisplayBackend::TryCreateWin32()); - // DisplayBackend::Set(DisplayBackend::TryCreateSDL2()); - DisplayBackend::Set(DisplayBackend::TryCreateBackend()); + // just for testing backends + switch (backend) + { + case Backend::Default: DisplayBackend::Set(DisplayBackend::TryCreateBackend()); break; + case Backend::Win32: DisplayBackend::Set(DisplayBackend::TryCreateWin32()); break; + case Backend::SDL2: DisplayBackend::Set(DisplayBackend::TryCreateSDL2()); break; + case Backend::X11: DisplayBackend::Set(DisplayBackend::TryCreateX11()); break; + case Backend::Wayland: DisplayBackend::Set(DisplayBackend::TryCreateWayland()); break; + } #if 1 auto launcher = new LauncherWindow(); @@ -275,9 +295,20 @@ static std::vector ReadAllBytes(const std::string& filename) return buffer; } -int main() +int main(int argc, const char** argv) { - example(); + std::string backendStr = argc > 1? argv[1]: ""; + std::transform(backendStr.begin(), backendStr.end(), backendStr.begin(), + [](unsigned char c){ return std::tolower(c); }); + + Backend backend = Backend::Default; + + if (backendStr == "sdl2") backend = Backend::SDL2; + if (backendStr == "x11") backend = Backend::X11; + if (backendStr == "wayland") backend = Backend::Wayland; + if (backendStr == "win32") backend = Backend::Win32; // lol + + example(backend); } #endif diff --git a/libraries/ZWidget/include/zwidget/core/widget.h b/libraries/ZWidget/include/zwidget/core/widget.h index 6d87f72a0..be41697cd 100644 --- a/libraries/ZWidget/include/zwidget/core/widget.h +++ b/libraries/ZWidget/include/zwidget/core/widget.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "canvas.h" #include "rect.h" #include "colorf.h" @@ -11,6 +12,7 @@ class Canvas; class Timer; +class Dropdown; enum class WidgetType { @@ -19,6 +21,13 @@ enum class WidgetType Popup }; +enum class WidgetEvent +{ + VisibilityChange, + + // TODO: add more events +}; + class Widget : DisplayWindowHost { public: @@ -93,6 +102,9 @@ public: void ShowNormal(); void Hide(); + void Subscribe(Widget* subscriber); + void Unsubscribe(Widget* subscriber); + void ActivateWindow(); void Close(); @@ -178,6 +190,8 @@ protected: virtual void OnLostFocus() { } virtual void OnEnableChanged() { } + virtual void Notify(Widget* source, const WidgetEvent type) { }; + private: void DetachFromParent(); @@ -201,6 +215,8 @@ private: void OnWindowDeactivated() override; void OnWindowDpiScaleChanged() override; + void NotifySubscribers(const WidgetEvent type); + WidgetType Type = {}; Widget* ParentObj = nullptr; @@ -234,8 +250,12 @@ private: Widget(const Widget&) = delete; Widget& operator=(const Widget&) = delete; + std::unordered_set Subscribers; + std::unordered_set Subscriptions; + friend class Timer; friend class OpenFileDialog; friend class OpenFolderDialog; friend class SaveFileDialog; + friend class Dropdown; }; diff --git a/libraries/ZWidget/include/zwidget/widgets/dropdown/dropdown.h b/libraries/ZWidget/include/zwidget/widgets/dropdown/dropdown.h new file mode 100644 index 000000000..9091e16d4 --- /dev/null +++ b/libraries/ZWidget/include/zwidget/widgets/dropdown/dropdown.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include + +#include "../../core/widget.h" +#include "../../widgets/listview/listview.h" + +class Dropdown : public Widget +{ +public: + Dropdown(Widget* parent); + + void AddItem(const std::string& text); + void RemoveItem(int index); + void ClearItems(); + + void SetMaxDisplayItems(int items); + void SetDropdownDirection(bool below); + + int GetSelectedItem() const { return selectedItem; } + void SetSelectedItem(int index); + + std::string GetSelectedText() const; + std::string GetText() const { return text; } + + double GetPreferredHeight() const; + double GetPreferredWidth() const; + + std::function OnChanged; + +protected: + void OnPaint(Canvas* canvas) override; + bool OnMouseDown(const Point& pos, InputKey key) override; + void OnKeyDown(InputKey key) override; + void OnGeometryChanged() override; + void OnLostFocus() override; + void Notify(Widget* source, const WidgetEvent type) override; + +private: + void OpenDropdown(); + void CloseDropdown(); + void OnDropdownActivated(); + + size_t GetDisplayItems(); + + std::vector items; + int selectedItem = -1; + std::string text; + + bool dropdownOpen = false; + Widget* dropdown = nullptr; + ListView* listView = nullptr; + + int maxDisplayItems = 0; + bool dropdownDirection = true; +}; diff --git a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h index e1b08192a..4253eae1f 100644 --- a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h +++ b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h @@ -22,6 +22,10 @@ public: void SetSelectedItem(int index); void ScrollToItem(int index); + double GetPreferredWidth(); + double GetPreferredHeight(); + double GetMinimumHeight() const; + void Activate(); std::function OnChanged; diff --git a/libraries/ZWidget/src/core/theme.cpp b/libraries/ZWidget/src/core/theme.cpp index cd553315c..88e482706 100644 --- a/libraries/ZWidget/src/core/theme.cpp +++ b/libraries/ZWidget/src/core/theme.cpp @@ -151,6 +151,7 @@ DarkWidgetTheme::DarkWidgetTheme() auto lineedit = RegisterStyle(std::make_unique(widget), "lineedit"); auto textedit = RegisterStyle(std::make_unique(widget), "textedit"); auto listview = RegisterStyle(std::make_unique(widget), "listview"); + auto dropdown = RegisterStyle(std::make_unique(widget), "dropdown"); auto scrollbar = RegisterStyle(std::make_unique(widget), "scrollbar"); auto tabbar = RegisterStyle(std::make_unique(widget), "tabbar"); auto tabbar_tab = RegisterStyle(std::make_unique(widget), "tabbar-tab"); @@ -217,6 +218,18 @@ DarkWidgetTheme::DarkWidgetTheme() listview->SetColor("border-bottom-color", Colorf::fromRgba8(100, 100, 100)); listview->SetColor("selection-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetDouble("noncontent-left", 5.0); + dropdown->SetDouble("noncontent-top", 5.0); + dropdown->SetDouble("noncontent-right", 5.0); + dropdown->SetDouble("noncontent-bottom", 5.0); + dropdown->SetColor("background-color", Colorf::fromRgba8(38, 38, 38)); + dropdown->SetColor("border-left-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetColor("border-top-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetColor("border-right-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetColor("border-bottom-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetColor("selection-color", Colorf::fromRgba8(100, 100, 100)); + dropdown->SetColor("arrow-color", Colorf::fromRgba8(100, 100, 100)); + scrollbar->SetColor("track-color", Colorf::fromRgba8(33, 33, 33)); scrollbar->SetColor("thumb-color", Colorf::fromRgba8(58, 58, 58)); @@ -290,6 +303,7 @@ LightWidgetTheme::LightWidgetTheme() auto lineedit = RegisterStyle(std::make_unique(widget), "lineedit"); auto textedit = RegisterStyle(std::make_unique(widget), "textedit"); auto listview = RegisterStyle(std::make_unique(widget), "listview"); + auto dropdown = RegisterStyle(std::make_unique(widget), "dropdown"); auto scrollbar = RegisterStyle(std::make_unique(widget), "scrollbar"); auto tabbar = RegisterStyle(std::make_unique(widget), "tabbar"); auto tabbar_tab = RegisterStyle(std::make_unique(widget), "tabbar-tab"); @@ -353,6 +367,18 @@ LightWidgetTheme::LightWidgetTheme() listview->SetColor("border-bottom-color", Colorf::fromRgba8(155, 155, 155)); listview->SetColor("selection-color", Colorf::fromRgba8(200, 200, 200)); + dropdown->SetDouble("noncontent-left", 5.0); + dropdown->SetDouble("noncontent-top", 5.0); + dropdown->SetDouble("noncontent-right", 5.0); + dropdown->SetDouble("noncontent-bottom", 5.0); + dropdown->SetColor("background-color", Colorf::fromRgba8(230, 230, 230)); + dropdown->SetColor("border-left-color", Colorf::fromRgba8(155, 155, 155)); + dropdown->SetColor("border-top-color", Colorf::fromRgba8(155, 155, 155)); + dropdown->SetColor("border-right-color", Colorf::fromRgba8(155, 155, 155)); + dropdown->SetColor("border-bottom-color", Colorf::fromRgba8(155, 155, 155)); + dropdown->SetColor("selection-color", Colorf::fromRgba8(200, 200, 200)); + dropdown->SetColor("arrow-color", Colorf::fromRgba8(200, 200, 200)); + scrollbar->SetColor("track-color", Colorf::fromRgba8(210, 210, 220)); scrollbar->SetColor("thumb-color", Colorf::fromRgba8(180, 180, 180)); diff --git a/libraries/ZWidget/src/core/widget.cpp b/libraries/ZWidget/src/core/widget.cpp index f431a6917..27f6f7b1c 100644 --- a/libraries/ZWidget/src/core/widget.cpp +++ b/libraries/ZWidget/src/core/widget.cpp @@ -1,4 +1,3 @@ - #include "core/widget.h" #include "core/timer.h" #include "core/colorf.h" @@ -34,6 +33,12 @@ Widget::Widget(Widget* parent, WidgetType type, RenderAPI renderAPI) : Type(type Widget::~Widget() { + for (auto subscription: Subscriptions) + subscription->Subscribers.erase(this); + + for (auto subscriber: Subscribers) + subscriber->Subscriptions.erase(this); + if (DispCanvas) DispCanvas->detach(); @@ -46,6 +51,24 @@ Widget::~Widget() DetachFromParent(); } +void Widget::Subscribe(Widget* subscriber) +{ + Subscribers.insert(subscriber); + subscriber->Subscriptions.insert(this); +} + +void Widget::Unsubscribe(Widget* subscriber) +{ + Subscribers.erase(subscriber); + subscriber->Subscriptions.erase(this); +} + +void Widget::NotifySubscribers(const WidgetEvent type) +{ + for (auto subscriber: Subscribers) + subscriber->Notify(this, type); +} + void Widget::SetCanvas(std::unique_ptr canvas) { if (DispWindow) @@ -206,10 +229,12 @@ void Widget::Show() if (Type != WidgetType::Child) { DispWindow->Show(); + NotifySubscribers(WidgetEvent::VisibilityChange); } else if (HiddenFlag) { HiddenFlag = false; + NotifySubscribers(WidgetEvent::VisibilityChange); Update(); } } @@ -260,11 +285,15 @@ void Widget::Hide() if (Type != WidgetType::Child) { if (DispWindow) + { DispWindow->Hide(); + NotifySubscribers(WidgetEvent::VisibilityChange); + } } else if (!HiddenFlag) { HiddenFlag = true; + NotifySubscribers(WidgetEvent::VisibilityChange); Update(); } } diff --git a/libraries/ZWidget/src/widgets/dropdown/dropdown.cpp b/libraries/ZWidget/src/widgets/dropdown/dropdown.cpp new file mode 100644 index 000000000..074be859b --- /dev/null +++ b/libraries/ZWidget/src/widgets/dropdown/dropdown.cpp @@ -0,0 +1,283 @@ +#include + +#include "widgets/dropdown/dropdown.h" +#include "core/widget.h" + +Dropdown::Dropdown(Widget* parent) : Widget(parent) +{ + SetStyleClass("dropdown"); + SetFocus(); + + // Subscribe to all parent widgets to receive notifications. + for (Widget* p = Parent(); p; p = p->Parent()) + p->Subscribe(this); +} + +void Dropdown::Notify(Widget* source, const WidgetEvent type) +{ + if (type != WidgetEvent::VisibilityChange) return; + if (!dropdownOpen) return; + + for (Widget* p = this; p != nullptr; p = p->Parent()) + { + if (p->IsHidden()) + { + CloseDropdown(); + return; + } + } +} + +void Dropdown::AddItem(const std::string& text) +{ + items.push_back(text); + if (selectedItem == -1 && !items.empty()) + { + SetSelectedItem(0); + } + Update(); +} + +void Dropdown::RemoveItem(int index) +{ + if (index < 0 || (size_t)index >= items.size()) + return; + + items.erase(items.begin() + index); + + if ((int)items.size() == 0) + { + SetSelectedItem(-1); + } + else if (selectedItem == index) + { + SetSelectedItem(0); + } + else if (selectedItem > index) + { + SetSelectedItem(selectedItem - 1); + } + Update(); +} + +void Dropdown::ClearItems() +{ + items.clear(); + SetSelectedItem(-1); + Update(); +} + +void Dropdown::SetSelectedItem(int index) +{ + if (index >= (int)items.size()) + index = (int)items.size() - 1; + + if (selectedItem != index) + { + selectedItem = index; + text = (selectedItem != -1) ? items[selectedItem] : ""; + + if (OnChanged) + OnChanged(selectedItem); + + Update(); + } +} + +std::string Dropdown::GetSelectedText() const +{ + if (selectedItem >= 0 && (size_t)selectedItem < items.size()) + return items[selectedItem]; + return {}; +} + +double Dropdown::GetPreferredHeight() const +{ + return 20.0 + 2*5.0; // Text plus top/bottom padding +} + +double Dropdown::GetPreferredWidth() const +{ + Canvas* canvas = GetCanvas(); + + double maxWidth = 0.0; + for (const auto& item : items) + { + auto width = canvas->measureText(item).width; + if (width > maxWidth) + { + maxWidth = width; + } + } + + return maxWidth + 2*10.0 + 16.0; // content, pad l/r, scrollbar from dropdown +} + +void Dropdown::OnPaint(Canvas* canvas) +{ + Colorf textColor = GetStyleColor("color"); + Colorf arrowColor = GetStyleColor("arrow-color"); + + double w = GetWidth(); + double h = GetHeight(); + + auto vtp = canvas->verticalTextAlign(); + double textY = (h-(vtp.bottom-vtp.top))/2.0 + vtp.baseline; + canvas->drawText(Point(7.0, textY), textColor, text); + + double arrowS = 8.0; + double arrowX = w - 3.0; // rightmost point, aligned with scrollbar + double arrowY = (h-arrowS)/2; + + Point p1(arrowX, arrowY); + Point p2(arrowX - arrowS, arrowY); + Point p3(arrowX - arrowS/2, arrowY + arrowS); + + canvas->line(p1, p2, arrowColor); + canvas->line(p2, p3, arrowColor); + canvas->line(p3, p1, arrowColor); +} + +bool Dropdown::OnMouseDown(const Point& pos, InputKey key) +{ + if (key == InputKey::LeftMouse) + { + if (dropdownOpen) + { + // this set focus call will close the popup + SetFocus(); + return true; + } + else + { + SetFocus(); + OpenDropdown(); + return true; + } + } + return false; +} + +void Dropdown::OnKeyDown(InputKey key) +{ + if (key == InputKey::Down) + { + if (selectedItem + 1 < (int)items.size()) + SetSelectedItem(selectedItem + 1); + } + else if (key == InputKey::Up) + { + if (selectedItem > 0) + SetSelectedItem(selectedItem - 1); + } + else if (key == InputKey::Enter || key == InputKey::Space) + { + if (dropdownOpen) + CloseDropdown(); + else + OpenDropdown(); + } +} + +void Dropdown::SetMaxDisplayItems(int items) +{ + maxDisplayItems = items; +} + +size_t Dropdown::GetDisplayItems() +{ + return (maxDisplayItems < 1) + ? std::max(items.size(), 1ul) + : std::min(items.size(), (size_t)maxDisplayItems); +} + +void Dropdown::SetDropdownDirection(bool below) +{ + dropdownDirection = below; +} + +void Dropdown::OnGeometryChanged() +{ + if (dropdownOpen) + { + Point pos = MapToGlobal(Point(0.0, 0.0)); + + double width = GetWidth() + GetNoncontentLeft() + GetNoncontentRight(); + double innerH = GetDisplayItems() * 25.0 + 10.0; + double outerH = GetHeight(); + + pos.x -= GetNoncontentLeft(); + + // adjust to be above/below box + if (dropdownDirection) + pos.y += outerH + GetNoncontentBottom() - 1.0; + else + pos.y -= innerH + GetNoncontentTop() - 1.0; + + dropdown->SetFrameGeometry(pos.x, pos.y, width, innerH); + } +} + +void Dropdown::OnLostFocus() +{ + if (!dropdownOpen) return; + + // Check if the mouse is over the dropdown itself or one of its children + auto hover = Window()->HoverWidget; + if (hover && (hover == dropdown || dropdown->IsParent(hover))) return; + + CloseDropdown(); +} + +void Dropdown::OpenDropdown() +{ + if (dropdownOpen || items.empty()) return; + + dropdownOpen = true; + + dropdown = new Widget(Window()); + listView = new ListView(dropdown); + for (const auto& item : items) + { + listView->AddItem(item); + } + + listView->SetSelectedItem(selectedItem); + + listView->OnActivated = [=]() { OnDropdownActivated(); }; + listView->OnChanged = [=](int index) { OnDropdownActivated(); }; + + listView->SetFrameGeometry( + 0, + 0, + GetWidth() + GetNoncontentLeft() + GetNoncontentRight(), + GetDisplayItems() * 25.0 + 10.0 + ); + OnGeometryChanged(); + + dropdown->Show(); + + listView->ScrollToItem(selectedItem); +} + +void Dropdown::CloseDropdown() +{ + if (!dropdownOpen || !dropdown) return; + + dropdown->Close(); + dropdown = nullptr; + listView = nullptr; + dropdownOpen = false; + + Update(); +} + +void Dropdown::OnDropdownActivated() +{ + if (listView) + { + SetSelectedItem(listView->GetSelectedItem()); + } + CloseDropdown(); + SetFocus(); +} diff --git a/libraries/ZWidget/src/widgets/listview/listview.cpp b/libraries/ZWidget/src/widgets/listview/listview.cpp index 1dd9fc9c1..1f771b3b7 100644 --- a/libraries/ZWidget/src/widgets/listview/listview.cpp +++ b/libraries/ZWidget/src/widgets/listview/listview.cpp @@ -1,4 +1,3 @@ - #include "widgets/listview/listview.h" #include "widgets/scrollbar/scrollbar.h" @@ -284,3 +283,40 @@ void ListView::OnKeyDown(InputKey key) } } } + +double ListView::GetPreferredWidth() +{ + double total = 0.0; + + for (double width : columnwidths) + { + if (width > 0.0) total += width; + } + + if (total == 0.0) + { + auto canvas = GetCanvas(); + + for (const auto& row : items) + { + double wRow = 0.0; + for (const auto& cell : row) + { + wRow += canvas->measureText(cell).width; + } + if (wRow > total) total = wRow; + } + } + + return total + 10.0*2 + scrollbar->GetPreferredWidth(); +} + +double ListView::GetPreferredHeight() +{ + return items.size()*20.0 + 10.0*2; // Items plus top/bottom padding +} + +double ListView::GetMinimumHeight() const +{ + return 20.0 + 10.0*2; // One item plus top/bottom padding +} diff --git a/update-subtrees.cmd b/tools/update-subtrees.cmd similarity index 100% rename from update-subtrees.cmd rename to tools/update-subtrees.cmd diff --git a/tools/update-subtrees.sh b/tools/update-subtrees.sh new file mode 100755 index 000000000..3c32492b9 --- /dev/null +++ b/tools/update-subtrees.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +pushd "$(git rev-parse --show-toplevel)" >/dev/null + +pull() { + if [[ "${1}" == "${2}" || "${1}" == "all" ]] + then + echo "fetching ${2}" + git subtree pull --prefix="${3}" "https://github.com/${4}" "${5}" --squash || exit + else + echo "${2} not specified, skipping" + fi +} + +pull "$1" 'zwidget' 'libraries/ZWidget' 'dpjudas/ZWidget' 'master' +pull "$1" 'zmusic' 'libraries/ZMusic' 'ZDoom/ZMusic' 'master' diff --git a/update-subtrees.sh b/update-subtrees.sh deleted file mode 100755 index e579e013f..000000000 --- a/update-subtrees.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -git subtree pull --prefix=libraries/ZWidget https://github.com/dpjudas/ZWidget master --squash -git subtree pull --prefix=libraries/ZMusic https://github.com/ZDoom/ZMusic master --squash